It may help to rewrite the assignments as function calls instead of operators (as others have stated explicitly, without any (), assignment proceeds right to left):
Line 2: a.operator=(b.operator=(c));
Line 3: (a.operator=(b)).operator=(c);
This makes it a little more clear that on line 3, you are trying to take the result of a=b
and assign c
to that. But in case 3, the output of operator=
is a const object, so this is not allowed (since operator=
is a nonconst function).
It would probably be even more clear to break each assignment into two separate statements:
// with const MyClass MyClass::operator=( const MyClass& X );
// line 1
MyClass a, b, c;
//line 2; originally a=b=c
const MyClass d = (b = c);
a = d; // no problem; a is nonconst, and it's ok for d (the parameter to operator=) to be const
//line 3; originally (a=b)=c
const MyClass e = (a = b); // note: the leftmost = here is initialization rather than assignment
e = c; // no good! e is const, and you can't call a nonconst function like operator= on a const object
Or take it one step further and get rid of any operator-related confusion by just using a function named assign
in place of operator=
:
// with const MyClass MyClass::assign( const MyClass& X );
// line 1
MyClass a, b, c;
//line 2; originally a=b=c
const MyClass d = b.assign(c);
a.assign(d); // ok. assign() is nonconst, but so is a.
//line 3; originally (a=b)=c
const MyClass e = a.assign(b);
e.assign(c); // no good! e is const and assign() is not.