Problem with Template Function and overloaded equality operator

• 06-06-2004
silk.odyssey
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::operator==(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:

``` 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.
• 06-06-2004
jlou
Make your operator == function const:

bool HugeInt::operator==( const HugeInt &op2 ) const
• 06-06-2004
Prelude
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; }```
• 06-07-2004
silk.odyssey
I'm not sure I understand. Which object is constant and which is not?
• 06-07-2004
Prelude
>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. ;)
• 06-07-2004
silk.odyssey
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?
• 06-07-2004
jlou
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. }```
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. :)
• 06-08-2004
silk.odyssey
Thanks for the help. I understand the problem with my code but references still torment me sometimes :D