Even mathematics has different processes for the same operators on different types. If you see 'a * b' you should be able to assume that it's multiplying two variables, but if those two are real numbers it's different than if they're two matrices of real numbers, for example.
Implementing a Matrix class that overrides * to imlement matrix multiplication seems perfectly fine for me - It's just the same as implementing a Multiply(a, b) method. Just as someone who writes a Multiply method could in theory make it do anything, it is assumed by reading the word 'Multiply' that that is what it does. Just as someone who makes a Multiply() function that does something other than multiply is an idiot, so is someone who overrides operator * to do something other than multiply.
(Note that my point here is that for sane/good code, you normally can be sure that it does what it looks like -- for C++ just the same way as for C.)