C++ Logo


Advanced search

Re: [std-proposals] Disable assignment to an rvalue

From: Peter Sommerlad (C++) <"Peter>
Date: Mon, 17 Oct 2022 13:38:32 +0200
FWIW, MISRA-C++ and me propose to define (copy/move) assignment
operators to be lvalue-ref-qualified, at least when you must define
those, because you are implementing a manager type. This is in line with
"when in doubt, do as the ints do" (Scott Meyers), because with the
fundamental types you cannot assign to an rvalue.

my classical example of leaking lvalue references is:

struct X{};

auto & dangle = (X{} = X{});

That we have unqualified member functions like front/back on containers
that could be called on rvalues and deliver lvalue references is a pity,
but that is something where changing the library to delete the
rvalue-qualified overload or make it return by value might be too much work.

But for my own types I'll follow the practice of ref-qualifying member
functions with side effects and returning references to guts accordingly.

I don't know yet, how that will change with deducing this in C++23.

Note, that I don't propose all overloads of any assignment operator to
be lvalue-ref-qualified, because a type might be defining a DSL where
such things might not have side effects or potentially return an lvalue
reference to an rvalue.


blacktea hamburger via Std-Proposals wrote on 07.10.22 14:20:
> N2819 <https://wg21.link/N2819> was rejected on the grounds that (N2920
> <https://wg21.link/N2920>):
> N2819, "N2819 Ref-Qualifiers for assignment operators of the
> Standard Library" was initially considered by the LWG. This proposal
> sought to change 350 copy-assignment operators in the C++ standard
> library to prevent assignment operations in which the left operand
> is an rvalue. Due to the large number of changes required, the
> proposal was sent to EWG, with the request that the default behavior
> for implicit copy-assignment operators be reconsidered, so that
> assignment to an rvalue is not permitted. The EWG resolved to
> maintain the status quo, because of concerns about backwards
> compatibility.
> I think one reason EWG rejected it is that even if the assigned value is
> later lost, the assignment might have other side effects that are
> preserved. However, there are rare cases where rvalues are assigned for
> side effects. Apart from those included in the proposal, I can only
> think of std::ostream_iterator and std::ostreambuf_iterator. If someone
> really wants to do rvalue assignment, the as_lvalue function template
> can be added to the standard to make it work
> (from https://stackoverflow.com/a/29041656/):
> template<class T>
> std::remove_reference_t<T>& as_lvalue(T&&t){return t;}
> Another reason is that the work is too onerous. It can be addressed by
> having the assignment operator include a ref-qualifier by default, but a
> syntax is required to cancel it.
> ||
> I think the same applies to the compound assignment operators, too. Does
> that create new issues?

Peter Sommerlad
Better Software: Consulting, Training, Reviews
Modern, Safe & Agile C++
+41 79 432 23 32

Received on 2022-10-17 11:38:37