C++ Logo


Advanced search

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

From: blacktea hamburger <greenteahamburger_at_[hidden]>
Date: Sat, 29 Oct 2022 16:00:20 +0800
I thought again, member functions shouldn't be like that.

*make_container().begin(); should work. However, it is impossible to
prohibit *make_container().begin() = v, because the result of pointer
dereferencing is always an lvalue.

So, for consistency, member functions should not be changed.

On Saturday, October 22, 2022, blacktea hamburger <
greenteahamburger_at_[hidden]> wrote:
> I think rvalue assignment should be prohibited instead of making the
result have the same value class as the object being assigned to, because
1=2 is ill-formed instead of returning int&&. But it is useful for member
functions like front/back.
> Maybe it would be better to explicitly add ref-qualifiers to the
assignment operators of some classes that shouldn't do rvalue assignment,
and have the default assignment operators ref-qualified.
> On Tuesday, October 18, 2022, Edward Catmur via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>> On Mon, 17 Oct 2022 at 17:31, Lénárd Szolnoki via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>>> Hi,
>>> On 17 October 2022 12:38:32 BST, "Peter Sommerlad (C++) via
Std-Proposals" <std-proposals_at_[hidden]> wrote:
>>> >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
>>> >"when in doubt, do as the ints do" (Scott Meyers), because with the
>>> >fundamental types you cannot assign to an rvalue.
>>> I think this is a disciplined take for value types, but for reference
types it might not be adequate.
>>> >
>>> >my classical example of leaking lvalue references is:
>>> >
>>> >struct X{};
>>> >
>>> >auto & dangle = (X{} = X{});
>>> The main issue here seems to be to return a reference from the
assignment at all. And if `rvalue = something` returns a reference, it
should better be an rvalue reference. If the object is expiring, then it is
still expiring after you assign to it.
>> But we write the copy assignment operator as X& X::X(X&), and the move
assignment operator as X&& X::X(X&&); the implicit object parameter is not
ref-qualified, so it can accept any value category, but for historical
reasons it always returns lvalue. And this is what the
automatically-generated assignment operators do as well.
>> Are you proposing to double the number of required/supported assignment
operator overloads? Or should the compiler propagate value category from
the LHS of an assignment to class type to its result (if the selected
member assignment operator is not ref-qualified)? After all, the returned
reference may be a different object to the implicit object argument (the
>>> >
>>> >That we have unqualified member functions like front/back on containers
>>> >that could be called on rvalues and deliver lvalue references is a
>>> >but that is something where changing the library to delete the
>>> >rvalue-qualified overload or make it return by value might be too much
>>> >
>>> >But for my own types I'll follow the practice of ref-qualifying member
>>> >functions with side effects and returning references to guts
>>> >
>>> >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.
>>> >
>>> >Regards
>>> >Peter.
>>> Cheers,
>>> Lénárd
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2022-10-29 08:00:23