As your error message states, your operator cannot be invoked on constant Pair in the left side. You explicitely marked it as changing left operand.
Be const correct: booloperator==(const Pair<T1, T2>& other) const // ← There and in some other places
Or, even better, define your operator as non-member.
class Class
{
public:
int val;
voidoperator=(const Class& other)
{ val = other.val; }
/* Should not be const as a value is modified (?) */
booloperator==(const Class& other) const
{ return (val == other.val); }
/* Should be const as no value is modified (?) */
};
class ClassManager
{
public:
Class c;
booloperator==(const Class& other) const
{ return (c == other); }
/*
Since "operator==" in <Class> was declared const,
this can be called on a const object (?)
*/
};
However, what about the following:
1 2 3
booloperator==(const Class& rhs, const Class& lhs)
{ return (rhs.val == lhs.val); }
/* Is this a correct implementation? Should it be const or non-const? */
Ah, I see. In that case, which should I use? If I understand correctly, having a non-member operator overloaded means that you can use String s = "Hello" + "World", not only String s = String("Hello") + "World", or something to that effect. Is this correct?
If so, is this the only advantage having a non-member versus a member o.o.? Are there any disadvantages?
If I understand correctly, having a non-member operator overloaded means that you can use String s = "Hello" + "World", not only String s = String("Hello") + "World", or something to that effect. Is this correct?
No, in the first example both the left and right side are primitive types and so no code you write can ever affect that operation.
With a member operator:
1 2 3
auto s1 = std::string("hello") + std::string(" world"); //no casts
auto s2 = std::string("hello") + " world"; //implicit cast of second argument
auto s3 = "hello" + std::string(" world"); //would not compile
With a non-member operator, the last would compile by implicitly casting the first argument.
What do you mean when you say that both the left and right side are primitive types? In this case, I am using String as a custom class, not the standard std::string.
"Hello" is a const char*: a primitive type "World" is a const char*: a primitive type
You cannot overload operator+ for them.
However, if you have implicit constructor for your string from const char*, you can do stuff like:
Oh, I see what you mean. However, what do you mean by "implicit constructor"? I thought that meant that the compiler creates one for you. What is the difference between implicit and explicit, then?