Reputation: 165
Here is the code:
#include <iostream>
using namespace std;
class X {
public:
int x;
X(int x=6) : x{x} {}
void print() {cout << x;}
X operator+(int rop) const {
return rop + x;
}
int operator+(const X& rop)const {
return x+rop.x;
}
};
X operator+(int lop, const X& x) {
return 2*lop + x.x;
}
int main()
{
X x;
cout << (5+x) + (x+2);
x.print();
return 0;
}
Here we see different overloading operators, that overloads addition.
In my example for ( 5+x)
was called 2*lop + x.x;
and for (x+2) rop + x;
(I suppose)
But I cannot really understand why(especially in the first case) for (5+x) 2*lop + x.x;
was called? And in general can you explain the differences between these overloading operators?
Upvotes: 3
Views: 187
Reputation: 6906
Currently your addition expression
(5+x) + (x+2)
without optimization compiles to
x.X::operator+(2).X::operator+(operator+(5, x))
(at least with GCC 7.3, I suppose that the order of evaluation of 5+x
and x+2
could be reversed depending on the compiler)
operator+(int rop)
isn't strictly necessary. It gets used for the first addition (of the int 2) because it is a better match than converting int
to X via implicit conversion with the constructor. If you omit
operator+(int rop)
then you would get
X::X(x.X::operator+(X::X(2))).X::operator+(operator+(5, x))
In both cases with optimization, this all simplifies to
std::cout << 24;
std::cout << 6;
Upvotes: 0
Reputation: 409136
Generically, a + b
is equal to a.operator+(b)
, if a
is an object that have an overloaded operator+
member function. Otherwise the compiler attempts to call operator+(a, b)
.
For x + 2
what is really being called is x.operator+(2)
.
With 5 + x
that is not possible, since it's not possible to have e.g. 5.operator+(x)
. Instead the global function have to be used.
Upvotes: 2
Reputation: 16404
If an operator is defined as a class member, then the left operand is the class, and the right operant is the one in the parameter list. Like:
X operator+(int rop) const;
Here when you call it, int
should be the right operand.
If it is defined outside, then it's just in normal order, left the first, right the second.
Thus for (5 + x)
, the operator defined in class X
can't match, and the one defined outside matchs.
Upvotes: 2
Reputation: 122133
Your operators are all different:
One is for X + int
/ X.operator+(int)
:
X operator+(int rop) const {
return rop + x;
}
The next for X + X
/ X.operator+(X)
:
int operator+(const X& rop)const {
return x+rop.x;
}
and the last one for int + X
(has to be a free function as there is no way to overload int.operator+
):
X operator+(int lop, const X& x) {
return 2*lop + x.x;
}
Upvotes: 3