3

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?

4
  • Because that's what you told the code to do? You overloaded operator+ for the case where int + X - the order of operands is important Commented Jan 31, 2018 at 10:14
  • @UnholySheep I didn't code that. That's why I ams asking:) Commented Jan 31, 2018 at 10:15
  • if it isnt your code you should say where it is coming from Commented Jan 31, 2018 at 10:19
  • 1
    Whoever wrote this code should feel ashamed. + should be commutative. Mixing member and non-member + is somewhat bad, but having return types such that x + x + x + 1 uses 3 different functions? disgusting Commented Jan 31, 2018 at 11:09

4 Answers 4

3

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; } 
Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

2

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.

Comments

0

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; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.