If T
is a class type with the default signature for assignment operator, then we can write:
T const &ref = ( T{} = something );
which creates a dangling reference. However, with the signature:
T &operator=(T t) &
the above code with dangling reference will fail to compile. This would prevent some situations where we return an lvalue that designates a temporary object -- undesirable situations because they can lead to dangling references.
Is there any reason not to do this; would we be disabling any valid use cases for the assignment operators?
I think the same comments can apply to the compound assignment operators too, +=
etc. A more realistic case might be:
std::string const &s = std::string("Hello, ") += "world!";
where the typo would go unnoticed until runtime UB.
In my experience in the rare case you do want to assign to an rvalue, writing
and doing
as_lvalue( tmp() ) = foo
instead oftmp()=foo
is not a huge barrier. It does mean that the occasional bit of code that did assign to an rvalue is now going to break; I personally would suspect most such cases are actually uncaught bugs.Restricting every type in
std
to be lvalue-restricted onoperator=
was considered during C++11 standardization in Frankfurt (2009/07). The resolution reasoning recorded in the minutes was:I read that as saying "350 changes? How about a language change?". EWG said "no, that language change could break compatibility". And possibly the proposal died on the vine.
In 2009, C++11 (then C++0x) was already behind schedule. As the proposition involved 300 changes to the library that (in theory) could cause regressions. No other reason was cited in the minutes. It being declined for not being worth the pain of regressions (or even checking for the frequency of regressions!) is understandable. So I wouldn't presume prejudice on the idea just because C++ rejected it in
std
.