Thread: Problem with Template Function and overloaded equality operator

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    167

    Problem with Template Function and overloaded equality operator

    This is the error:

    "main.cpp": main.cpp passing `const HugeInt' as `this' argument of `bool HugeInt:perator==(const HugeInt&)' discards qualifiers at line 29

    This is where the error occurs.

    Code:
     
    template <class T>
    bool isEqualTo( const T &left, const T &right )
    {
      return ( left == right );
    }
    Code for overloaded function

    Code:
     
    bool HugeInt::operator==( const HugeInt &op2 )
    {
        for( int i = 29; i >= 0; i-- ){
          if ( integer[i] != op2.integer[i])
             return false;
        }
        return true;
    }
    Anyone have a clue what's going on here. I don't really understand the error message so that's not helping me.
    silk.odyssey

  2. #2
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Make your operator == function const:

    bool HugeInt::operator==( const HugeInt &op2 ) const

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    You're calling an overloaded operator for a const object with a non-const object. You can do one of two things to fix the problem. First, you can declare the overloaded operator const:
    Code:
    bool HugeInt::operator==( const HugeInt &op2 ) const
    {
        for( int i = 29; i >= 0; i-- ){
          if ( integer[i] != op2.integer[i])
             return false;
        }
        return true;
    }
    Second, and this is the better method because comparison with operator == should be commutative, declare operator== as a friend function that takes two arguments and then define is as such:
    Code:
    bool operator==( const HugeInt& op1, const HugeInt &op2 )
    {
      for( int i = 29; i >= 0; i-- ){
        if ( op1.integer[i] != op2.integer[i])
          return false;
      }
      return true;
    }
    My best code is written with the delete key.

  4. #4
    Registered User
    Join Date
    Dec 2003
    Posts
    167
    I'm not sure I understand. Which object is constant and which is not?
    silk.odyssey

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Which object is constant and which is not?
    The object that you're using is constant, but the object that you say you're using is not. You can't call a non-const member function with a const object, so operator== needs to be declared const. Or you could make it a friend function that takes two arguments like everyone else.
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    Dec 2003
    Posts
    167
    Ok I think I understand now. What was giving me problems was that i passed constant references to the the IsEqualTo function. But that doesn't make the function constant I guess. Is it possible to have a constant reference to a non constant object or are references always constant since they can't be reassigned?
    silk.odyssey

  7. #7
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    The IsEqualTo function is a global function (it appears) and so it isn't const and shouldn't be const. A function being const only makes sense if it is a member function. That is why your operator== needed to be const. It was implemented as a member function. When you call a member function using a const reference or object, that function must be declared as const (this makes sense, you have a const reference so you promise not to change it, and you can only call const functions that promise not to change it).

    A reference can be const or non-const, and you can initialize a const reference with a non-const object.
    Code:
    class Test {
    public:
        void ModifyMe() { /* Do something to modify me */ }
        void DontModifyMe() const { /* Read-only operations */ }
    };
    
    int main()
    {
        Test tInst;
        const Test constInst;
    
        Test& refToInst = tInst;  // Fine, non-const reference to non-const object.
        const Test& constRefToInst = tInst; // Fine, const reference to non-const object.
    
        //Test& refToConstInst = constInst;  // ERROR!! Non-const reference to const object.
        const Test& constRefToConstInst = constInst; // Fine, const reference to const object.
    
        tInst.ModifyMe(); // Fine, call non-const function from non-const object.
        //constInst.ModifyMe(); // ERROR!! Call non-const function from const object.
        refToInst.ModifyMe(); // Fine, call non-const function from non-const reference.
        //constRefToInst.ModifyMe(); // ERROR!! Call non-const function from const reference.
        //constRefToConstInst.ModifyMe(); // ERROR!! Call non-const function from const reference.
    
        tInst.DontModifyMe(); // Fine, call const function from non-const object.
        constInst.DontModifyMe(); // Fine, call const function from const object.
        refToInst.DontModifyMe(); // Fine, call const function from non-const reference.
        constRefToInst.DontModifyMe(); // Fine, call const function from const reference.
        constRefToConstInst.DontModifyMe(); // Fine, call const function from const reference.
    }
    So in your code:
    Code:
    template <class T>
    bool isEqualTo( const T &left, const T &right )
    {
      return ( left == right );
    }
    Note that the above is equivalent to:
    Code:
    template <class T>
    bool isEqualTo( const T &left, const T &right )
    {
      return ( left.operator==(right) );
    }
    You have a const reference, left, calling a member function, bool operator==( const HugeInt &op2 ), that wasn't const. That is like the line above:
    //constRefToInst.ModifyMe(); // ERROR!! Call non-const function from const reference.

    When you add the const to the operator==, you see that it works like this line:
    constRefToInst.DontModifyMe(); // Fine, call const function from const reference.

    Of course, then once you understood why it wasn't working before, you changed operator== to not be a member function like Prelude suggested, and you stopped having to worry about member function constness for this problem.

  8. #8
    Registered User
    Join Date
    Dec 2003
    Posts
    167
    Thanks for the help. I understand the problem with my code but references still torment me sometimes
    silk.odyssey

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why can = operator not be overloaded with member function?
    By chottachatri in forum C++ Programming
    Replies: 9
    Last Post: 02-22-2008, 04:30 PM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. Problem with overloaded function templates
    By New++ in forum C++ Programming
    Replies: 10
    Last Post: 09-05-2005, 04:00 PM
  4. problem of the overloaded operator
    By Arwen in forum C++ Programming
    Replies: 13
    Last Post: 09-16-2004, 06:48 AM
  5. Returned value with operator overloaded function???
    By silk.odyssey in forum C++ Programming
    Replies: 8
    Last Post: 05-12-2004, 11:46 AM