# no match for overloaded operator

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 10-20-2012
std10093
The line code that has the error
Code:

`Matrix4d M = T*R4*R1.inverse();`
The error
Code:

```/Users/usi/Desktop/RayTracerFrameWork/CCanvas.cpp:45: error: no match for 'operator*' in 'T. Matrix4d::operator*(((Matrix4d&)(& R4))) * R1. Matrix4d::inverse()' /Users/usi/Desktop/RayTracerFrameWork/Matrix4.h:204: candidates are: const Matrix4d Matrix4d::operator*(Matrix4d&) const```
The function
Code:

```  /**   * Multiplication of two matrices.   * @param m - the other Matrix   * @return the <b> product </b> of the matrix multiplication   */   const Matrix4d operator * ( Matrix4d& m ) const {         Matrix4d M;         // set matrix diagonals to 0         for (int r=0; r<4; r++) { M(r,r) = 0; M(r,r,-1) = 0;}         // Now multiply the two matrices:         for (int r=0; r<4; r++)             for (int c=0; c<4; c++)                 for (int i=0; i<4; i++) {                     M(r,c)    += _v[r][i]*m(i,c);                     M(r,c,-1) += m(r,i,-1)*_inv[i][c];                 }     return M;   };```
the inverse function
Code:

```  /*     * returns the invers of the current matrix:     */   Matrix4d inverse()     {         Matrix4d M;         for (int r=0; r<4; r++)             for (int c=0; c<4; c++) {                 M(r,c)    = _inv[r][c];                 M(r,c,-1) = _v[r][c];             }         return M;   };```
The fields of the class Matrix4d
Code:

```    double _v[4][4];     double _inv[4][4];```
If i change the prototype of the function to this
Code:

`const Matrix4d operator * ( Matrix4d m ) const`
(without the &) then it will work ok.Can i do it by using the &operator for the parameter ?
Like this
Code:

`const Matrix4d operator * ( Matrix4d m ) const`
edit : Or to be more exact what should i write in line that produces the error?
• 10-20-2012
jimblumberg
Look closely at your error message, this part in particular:
Quote:

candidates are: const
This seems like it is probably a const correctness issue.

Jim
• 10-20-2012
std10093
This was my first feeling too Jim.I removed both const keywords and got the same error.Removed only the first,same again.Removed only the second,same error.
Did that before posting :)
So the problem stills remain..Maybe i have to modify this line of code
Code:

`Matrix4d M = T*R4*R1.inverse();`
• 10-20-2012
jimblumberg
You removed the constant, did you try making inverse() const?

If that isn't it I suggest you post the smallest possible complete program that demonstrates the problem so I can play with it.

Jim
• 10-20-2012
std10093
I tried to but error again.Following your suggestion i post the following :

Matrix4.h
Code:

```/*     * Constructor for a translation matrix:     */     static Matrix4d translation( const double x, const double y, const double z)     {     Matrix4d M;         // set the last column of the matrix         M(0,3) = x;         M(1,3) = y;         M(2,3) = z;         // set the last column of the inverse matrix         M(0,3,-1) = -x;         M(1,3,-1) = -y;         M(2,3,-1) = -z;         return M;     };     /*     * Constructor for a rotation matrix:     */     static Matrix4d rotation( const double angle, const char axis)     {         Matrix4d M;         // set rotation around x axis:         if ((axis == 'x') || (axis == 'X')) {             M(1,1) =  cos(angle);  M(1,1,-1) =  cos(angle);             M(1,2) = -sin(angle);  M(1,2,-1) =  sin(angle);             M(2,1) =  sin(angle);  M(2,1,-1) = -sin(angle);             M(2,2) =  cos(angle);  M(2,2,-1) =  cos(angle);             return M;         }         // set rotation around y axis:         if ((axis == 'y') || (axis == 'Y')) {             M(0,0) =  cos(angle);  M(0,0,-1) =  cos(angle);             M(0,2) =  sin(angle);  M(0,2,-1) = -sin(angle);             M(2,0) = -sin(angle);  M(2,0,-1) =  sin(angle);             M(2,2) =  cos(angle);  M(2,2,-1) =  cos(angle);             return M;         }         // set rotation around z axis:         if ((axis == 'z') || (axis == 'Z')) {             M(0,0) =  cos(angle);  M(0,0,-1) =  cos(angle);             M(0,1) = -sin(angle);  M(0,1,-1) =  sin(angle);             M(1,0) =  sin(angle);  M(1,0,-1) = -sin(angle);             M(1,1) =  cos(angle);  M(1,1,-1) =  cos(angle);             return M;         }         return M;     };       /*     * returns the invers of the current matrix:     */   Matrix4d inverse()     {         Matrix4d M;         for (int r=0; r<4; r++)             for (int c=0; c<4; c++) {                 M(r,c)    = _inv[r][c];                 M(r,c,-1) = _v[r][c];             }         return M;   };       /**   * Multiplication of two matrices.   * @param m - the other Matrix   * @return the <b> product </b> of the matrix multiplication   */   const Matrix4d operator * ( Matrix4d m ) const {         Matrix4d M;         // set matrix diagonals to 0         for (int r=0; r<4; r++) { M(r,r) = 0; M(r,r,-1) = 0;}         // Now multiply the two matrices:         for (int r=0; r<4; r++)             for (int c=0; c<4; c++)                 for (int i=0; i<4; i++) {                     M(r,c)    += _v[r][i]*m(i,c);                     M(r,c,-1) += m(r,i,-1)*_inv[i][c];                 }     return M;   };```
and call it from something like this
Code:

```#include "Matrix4.h" int main() {     Matrix4d T = Matrix4d::translation (-1.0, -1.0, 5.0);     Matrix4d R1 = Matrix4d::rotation (PI/4.0,'x');     Matrix4d R4 = Matrix4d::rotation (1.0,'y');     Matrix4d M = T*R4*R1.inverse();  //here it is!     return 0; }```
I think this could be it.
Thank you for your time :)
• 10-20-2012
iMalc
The solution is not to be removing any const, it is to be adding one more:
Code:

`const Matrix4d operator * (const Matrix4d& m) const`
Your code was producing a temporary from a multiplication operation, and then you wanted to use that temporary to take part in another multipication.

Edit: You posted at the same time as I wrote my post.
Your newly posted code works because you accept the parameter by value. This means the temporary is copied. The better solution is to accept a const-reference.
• 10-20-2012
jimblumberg
What you posted is missing the class declaration. Please post that as well.

Jim
• 10-20-2012
std10093
Sorry Jim.iMalc yes this is true, as i pointed to my first post.I posted this by accident.If i add another const then there is going to be problem in the body of the overloaded operaton in these lines
Code:

```M(r,c)    += _v[r][i]*m(i,c);                     M(r,c,-1) += m(r,i,-1)*_inv[i][c];```
The function for the () is this
Code:

```/*     * write,read the matrix element at i,j:     * element of the matrix when no third parameter is specified     * the element at [i,j] in the inverse matrix otherwise     */     double& operator() (int i, int j, int invFlag = 0)     {         if (invFlag == 0)             return _v[i][j];         else             return _inv[i][j];     };```
but as you can see in the translation function i can not make the () const because it will throw an error for invalid initialization.

I will post here the code with iMalc's suggestion

Code:

```#include "Matrix4.h"   int main() {     Matrix4d T = Matrix4d::translation (-1.0, -1.0, 5.0);     Matrix4d R1 = Matrix4d::rotation (PI/4.0,'x');     Matrix4d R4 = Matrix4d::rotation (1.0,'y');       Matrix4d M = T*R4*R1.inverse();  //here it is!       return 0; }```
Matrix4.h
Code:

```#ifndef MATRIX4_H #define MATRIX4_H /*************************************************************************** MATRIX.h Comment:  This file contains all matrix definitions. ***************************************************************************/ //----------------------------------------------------------------------------- /// Template class for 4x4-Matrices. /** * This is the main class for all 4x4-Matrices. * The type of the 16 components is variable. */ class Matrix4d { //----------------------------------------------------------------------------- public:       ...     /*     * write,read the matrix element at i,j:     * element of the matrix when no third parameter is specified     * the element at [i,j] in the inverse matrix otherwise     */     double& operator() (int i, int j, int invFlag = 0)     {         if (invFlag == 0)             return _v[i][j];         else             return _inv[i][j];     };     /*     * Constructor for a translation matrix:     */     static Matrix4d translation( const double x, const double y, const double z)     {     Matrix4d M;         // set the last column of the matrix         M(0,3) = x;         M(1,3) = y;         M(2,3) = z;         // set the last column of the inverse matrix         M(0,3,-1) = -x;         M(1,3,-1) = -y;         M(2,3,-1) = -z;         return M;     };   /*     * Constructor for a rotation matrix:     */     static Matrix4d rotation( const double angle, const char axis)     {         Matrix4d M;         // set rotation around x axis:         if ((axis == 'x') || (axis == 'X')) {             M(1,1) =  cos(angle);  M(1,1,-1) =  cos(angle);             M(1,2) = -sin(angle);  M(1,2,-1) =  sin(angle);             M(2,1) =  sin(angle);  M(2,1,-1) = -sin(angle);             M(2,2) =  cos(angle);  M(2,2,-1) =  cos(angle);             return M;         }         // set rotation around y axis:         if ((axis == 'y') || (axis == 'Y')) {             M(0,0) =  cos(angle);  M(0,0,-1) =  cos(angle);             M(0,2) =  sin(angle);  M(0,2,-1) = -sin(angle);             M(2,0) = -sin(angle);  M(2,0,-1) =  sin(angle);             M(2,2) =  cos(angle);  M(2,2,-1) =  cos(angle);             return M;         }         // set rotation around z axis:         if ((axis == 'z') || (axis == 'Z')) {             M(0,0) =  cos(angle);  M(0,0,-1) =  cos(angle);             M(0,1) = -sin(angle);  M(0,1,-1) =  sin(angle);             M(1,0) =  sin(angle);  M(1,0,-1) = -sin(angle);             M(1,1) =  cos(angle);  M(1,1,-1) =  cos(angle);             return M;         }         return M;     };     ....     /*     * returns the invers of the current matrix:     */   Matrix4d inverse()     {         Matrix4d M;         for (int r=0; r<4; r++)             for (int c=0; c<4; c++) {                 M(r,c)    = _inv[r][c];                 M(r,c,-1) = _v[r][c];             }         return M;   };  ....     /**   * Multiplication of two matrices.   * @param m - the other Matrix   * @return the <b> product </b> of the matrix multiplication   */   const Matrix4d operator * ( const Matrix4d& m ) const {         Matrix4d M;         // set matrix diagonals to 0         for (int r=0; r<4; r++) { M(r,r) = 0; M(r,r,-1) = 0;}         // Now multiply the two matrices:         for (int r=0; r<4; r++)             for (int c=0; c<4; c++)                 for (int i=0; i<4; i++) {                     M(r,c)    += _v[r][i]*m(i,c);                     M(r,c,-1) += m(r,i,-1)*_inv[i][c];                 }     return M;   };   .. //----------------------------------------------------------------------------- private:   /*     * The components of the Matrix in _v[][]     * The components of the inverse Matrix in _inv[][]     */     double _v[4][4];     double _inv[4][4]; }; #endif```
• 10-20-2012
iMalc
Are you aware of how this line parses?:
Code:

`Matrix4d M = T*R4*R1.inverse();`
It's
Code:

`Matrix4d M = T*R4*(R1.inverse());`
Not:
Code:

`Matrix4d M = (T*R4*R1).inverse();`
Thus a lack of const on the inverse function doesn't have the same issue yet because it does not try to modify a temporary. However it should be marked const so that you can use it that way in future.

Also, your operator() needs to be declared as const as well. That is where it's gone wrong now. Basically, every method that does not modify the current object should be markled const. Unless of course it doesn't touch any member variables, in which case static is more appropriate instead.
• 10-20-2012
std10093
Yes i am.But i do not think that you realized what i said :)
Where i overload the * operator,i use inside the body
Code:

`... m(i,c);`
but i have overloaded the () so it won't let me do this.So maybe i should modify the () overloading function but if i declare it as a const then inside the translation function for example i can not do this
Code:

`M(0,3) = x;`
,where M is an instance of the class.... :/ :/
• 10-20-2012
iMalc
In that case you need two versions of operator (). One const and one non-const.
Code:

```double& operator() (int i, int j, int invFlag = 0); double operator() (int i, int j, int invFlag = 0) const;```
Your invFlag should really be a bool too, not an int.
• 10-20-2012
std10093
Agree about the bool.I tried that before a post again and got a syntax error.
Code:

```/Users/usi/Desktop/RayTracerFrameWork/Matrix4.h:55: error: declaration of 'operator()' as non-function /Users/usi/Desktop/RayTracerFrameWork/Matrix4.h:55: error: expected ';' before 'const'```
• 10-20-2012
iMalc
Ah darn it I put the const in the wrong place - fixed it now.
• 10-20-2012
std10093
I tried to do also this but got
Code:

```double& operator() (int i, int j, int invFlag = 0) const     {         if (invFlag == 0)             return _v[i][j]; //error         else             return _inv[i][j]; //error     };```
the error
Code:

```/Users/usi/Desktop/RayTracerFrameWork/Matrix4.h:58: error: invalid initialization of reference of type 'double&' from expression of type 'const double' /Users/usi/Desktop/RayTracerFrameWork/Matrix4.h:58: error: invalid initialization of reference of type 'double&' from expression of type 'const double'```
• 10-20-2012
iMalc
You missed the fact that, as I showed, the const version returns by value, not by reference.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last