Rob_Fir
Rob_Fir

Reputation: 165

Operator overloading(confusion why exactly this operator is called) C++

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

Answers (4)

Paul Floyd
Paul Floyd

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

Some programmer dude
Some programmer dude

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

llllllllll
llllllllll

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

463035818_is_not_an_ai
463035818_is_not_an_ai

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

Related Questions