binary operator + , = overloading with const

I am learning C++ concepts and would highly appreciate any help with explanation. Why statement 4 is not compiling but statement 1 is.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  class X {
	public:
			X& operator= (const X& rhs);
			const X& operator+ (const X& rhs) const;
			const X& operator+ (int m);
	private:
			int n;
};

int main() {
		X a, b, c;
		a = a + 5 + c; //statement 1 - No compiler errors
		a = b + 5; //statement 2
		a = a = b + c; //statement 3
		a = b + c + 5; //statement 4 
/*compiler Error thrown - passing 'const X' as 'this' argument of 'const X& X::operator+(int)' 
discards qualifiers [-fpermissive]*/
		(c = a + a) = b + c; ////statement 5
}


As per my understanding (based on: both + & = are right-associative) above 5 statements are called as-

//statement 1
a.operator=(a.operator+(5.operator+(c))); -->I believe this should have thrown error as no defined constructor supports this

//statement 2
a.operator=(b.operator+(5));

//statement 3
a.operator=(a.operator=(b.operator+(c)));

//statement 4
a.operator=(b.operator+(c.operator+(5)));

//statement 5
(c.operator=(a.operator+(a)))=(b.operator+(c)); then
lhs_result.operator=(rhs_result);

Also Did I correctly decipher statement 5th above?
Addition (+) and subtraction (-) are grouped left-to-right.
http://en.cppreference.com/w/cpp/language/operator_precedence

Statement 4 is a.operator=(a.operator+(c).operator+(5));
The problem is that operator+(int) has not been marked as const so it can't be used on the const X& that was returned by a.operator+(c).
You assume right-associativity, but remember this is not the same operator, you have 2 versions of it, and the compiler has to decide which one takes precedence.
Operator overloading is just a convenient syntax for writing certain functions. So you may be using "+" everywhere, but the compiler still has to decide which of your functions to call at any given instance.

Enter overloaded resolution!

There is no int::operator+(X) for doing 5 + c, statement 1 is resolved as "a = (a + 5) + c"
a.operator=((a.operator+(5)).operator+(c) const);

In statement 4, const X& operator+ (const X& rhs) const; is called first, in favour of const X& operator+ (int m); - think of it as being a different operator with higher precedence. So you get a = (b + c) + 5, since operator+(int) is not a const function, it can't be called for a const object (the result of a+b), hence your build error.
a.operator=((b.operator+(c)).operator+(5) -> this won't compile

If const X& operator+ (int m) const; your code would compile.
Topic archived. No new replies allowed.