An answer that mirrors one from http://stackoverflow.com/questions/2447696/overloading-assignment-operator-in-c/2448144#2448144:
Returning a const&
will still allow assignment chaining:
a = b = c;
But will disallow some of the more unusual uses:
(a = b) = c;
Note that this makes the assignment operator have semantics similar to what it has in C, where the value returned by the =
operator is not an lvalue. In C++, the standard changed it so the =
operator returns the type of the left operand, so the result is an lvalue. But as Steve Jessop noted in a comment to another answer, while that makes it so the compiler will accept
(a = b) = c;
even for built-ins, the result is undefined behavior for built-ins since a
is modified twice with no intervening sequence point. That problem is avoided for non-builtins with an operator=()
because the operator=()
function call serves as a sequence point.
I see no problem returning a const&
unless you want to specifically allow the lvalue semantics (and design the class to ensure it acts sensibly with those semantics). If you're users want to do something unusual with the result of operator=()
, I'd prefer that the class disallow it rather than hope it gets it right by chance instead of design.
Also. note that while you said:
You can only define one or the other, but not both.
that's because the function signature in C++ doesn't take into account the return value type. You could however have multiple operator=()
assignement operatiors that take different parameters and return different types appropriate to the parameter types:
my_class& operator=( my_class& rhs);
my_class const& operator=(my_class const& rhs);
I'm not entirely sure what this would buy you though. The object being assigned to (that is presumably the reference being returned) is non-const in both cases, so there's no logical reason to return a const&
just because the righ-hand-side of the =
is const
. But maybe I'm missing something...