Thread: no match for overloaded operator

  1. #1
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694

    no match for overloaded operator

    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?
    Last edited by std10093; 10-20-2012 at 03:40 PM.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Look closely at your error message, this part in particular:
    candidates are: const
    This seems like it is probably a const correctness issue.

    Jim

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    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();

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    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
    Last edited by jimblumberg; 10-20-2012 at 04:18 PM.

  5. #5
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    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

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    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.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    What you posted is missing the class declaration. Please post that as well.

    Jim

  8. #8
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    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

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    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.
    Last edited by iMalc; 10-20-2012 at 05:15 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    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.... :/ :/

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    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.
    Last edited by iMalc; 10-20-2012 at 05:40 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    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'

  13. #13
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Ah darn it I put the const in the wrong place - fixed it now.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  14. #14
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    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'

  15. #15
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You missed the fact that, as I showed, the const version returns by value, not by reference.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. no match for operator>> !?
    By Spyser in forum C++ Programming
    Replies: 2
    Last Post: 02-21-2012, 08:00 AM
  2. best Overloaded match for method ...
    By deathkosui in forum C# Programming
    Replies: 8
    Last Post: 11-05-2009, 11:23 PM
  3. no match for 'operator>>'
    By Taka in forum C++ Programming
    Replies: 3
    Last Post: 03-30-2009, 12:17 AM
  4. Replies: 3
    Last Post: 12-09-2008, 11:19 AM
  5. no match for operator << ??
    By neoragexxx in forum C++ Programming
    Replies: 6
    Last Post: 05-01-2006, 05:02 PM