In your example
double wage = 5; double salary = wage = 9999.99;
& hellip; there is only one purpose , namely
wage = 9999.99
Other instances = are part of the initialization syntax.
The destination returns a reference to the object to which the value is assigned, in this case wage . So the example is equivalent
double wage = 5; wage = 9999.99; double salary = wage;
If your example is rewritten to use several purposes,
double wage; double salary; wage = 5; salary = wage = 9999.99;
& hellip; it becomes important that assignment operators are right-associative. So the last line is equivalent
salary = (wage = 9999.99);
& hellip; where the expression in parentheses returns a link to wage .
Standard containers require the user assignment operator to return a reference to the assigned object. The main language does not have this requirement, so it may be tempting to use void . That is, guaranteed efficiency that does not support unholy code based on side effects and a more concise implementation, all of which are good:
struct S { void operator=( S );
However, in order for the delete or default assignment operator, the operator declaration must give it a reference return type:
struct T { auto operator=( T const& ) -> T&
On the third and exciting hand, a detailed, not guaranteed-effective and non-competitive-side-effect-code operator= can be expressed in terms of a separate void member function, which can even be an operator:
struct U { void assign( U other ); auto operator=( U const& other ) -> U& { assign( other ); return *this; } };