Date: Fri, 13 Nov 2020 12:25:12 +0100
FWIW
I would not delete the &&-qualified overload but return the string by
value to avoid leaking a dangling reference in such a case
std::string getName() && { return std::move(name); }
I think that would make your code work again. However, I am not sure,
this approach is generalizable for the standard library.
In addition we would need to provide rref-qualified overloads of
functions taking parameters by const-lref that return a reference to the
parameter (or its guts) as well.
std::string const & whatsYourName(Person const &p){ return p.getName(); }
std::string whatsYourName(Person &&p) { return p.getName(); } // rely on RVO
Regards
Peter.
Giuseppe D'Angelo via SG20 wrote on 13.11.20 11:20:
> On 13/11/2020 10:04, Amir Kirsh via SG20 wrote:
>>
>> Taking this approach in users' code is possible, though a bit
>> cumbersome today:
>>
>> class Person {
>> std::string name;
>> public:
>> Person(std::string name): name(std::move(name)) {}
>> const std::string& getName() const & { return name; }
>> const std::string& getName() const && = delete;
>
> This makes legitimate code not work:
>
> std::string name = // not a reference
> getPerson().getName();
>
>
>> // or:
>> // std::string getName() const && { return name; }
>
> This works but makes a copy instead of moving the data member into the
> return object. You'd also need something like:
>
> std::string getName() && { return std::move(name); }
>
>
> Usual disclaimer: you justify this because you know that std::string is
> reasonably cheap to move, so you can afford the cost of return by value
> in these circumstances. If you were to return something not necessarily
> cheap to move, then justifying the return by value -- even from rvalue
> overload -- is not so easy. So you'd return by rvalue reference
> (otherwise, a chain like getArrayOfPersons().getFirst().getName()
> creates N possibly expensive temporaries). And we're back to square one
> for the general case.
>
> Other usual disclaimer, this assumes that "moved from" means "partially
> formed", not "valid but unspecified" like the stdlib does (you've likely
> just broken class invariants).
>
> Moreover: going this route for any "getter" makes the implementation
> alone, today, terribly cumbersome (this is probably where "deducing
> this" could help). I still find that the teachability of all of this is
> nothing but dreadful.
>
> My 2 c,
>
>
>
I would not delete the &&-qualified overload but return the string by
value to avoid leaking a dangling reference in such a case
std::string getName() && { return std::move(name); }
I think that would make your code work again. However, I am not sure,
this approach is generalizable for the standard library.
In addition we would need to provide rref-qualified overloads of
functions taking parameters by const-lref that return a reference to the
parameter (or its guts) as well.
std::string const & whatsYourName(Person const &p){ return p.getName(); }
std::string whatsYourName(Person &&p) { return p.getName(); } // rely on RVO
Regards
Peter.
Giuseppe D'Angelo via SG20 wrote on 13.11.20 11:20:
> On 13/11/2020 10:04, Amir Kirsh via SG20 wrote:
>>
>> Taking this approach in users' code is possible, though a bit
>> cumbersome today:
>>
>> class Person {
>> std::string name;
>> public:
>> Person(std::string name): name(std::move(name)) {}
>> const std::string& getName() const & { return name; }
>> const std::string& getName() const && = delete;
>
> This makes legitimate code not work:
>
> std::string name = // not a reference
> getPerson().getName();
>
>
>> // or:
>> // std::string getName() const && { return name; }
>
> This works but makes a copy instead of moving the data member into the
> return object. You'd also need something like:
>
> std::string getName() && { return std::move(name); }
>
>
> Usual disclaimer: you justify this because you know that std::string is
> reasonably cheap to move, so you can afford the cost of return by value
> in these circumstances. If you were to return something not necessarily
> cheap to move, then justifying the return by value -- even from rvalue
> overload -- is not so easy. So you'd return by rvalue reference
> (otherwise, a chain like getArrayOfPersons().getFirst().getName()
> creates N possibly expensive temporaries). And we're back to square one
> for the general case.
>
> Other usual disclaimer, this assumes that "moved from" means "partially
> formed", not "valid but unspecified" like the stdlib does (you've likely
> just broken class invariants).
>
> Moreover: going this route for any "getter" makes the implementation
> alone, today, terribly cumbersome (this is probably where "deducing
> this" could help). I still find that the teachability of all of this is
> nothing but dreadful.
>
> My 2 c,
>
>
>
-- Peter Sommerlad Better Software: Consulting, Training, Reviews Modern, Safe & Agile C++ peter.cpp_at_[hidden] +41 79 432 23 32
Received on 2020-11-13 05:25:21