C++ Logo

sg20

Advanced search

Re: [SG20] A draft paper to fix the range-based for loop to make it teachable

From: Amir Kirsh <kirshamir_at_[hidden]>
Date: Fri, 13 Nov 2020 14:09:26 +0200
Which brings us back to the idea that the caller is responsible for
handling temporaries correctly (I think it was Yehezkel Bernat who raised
it above with the example of std::min getting and returning const
reference).

In those cases where you see that callers *constantly do not handle
temporaries correctly *(the getOrDefault example by Louis Brandy
<https://www.youtube.com/watch?v=lkgszkPnV8g&t=13m0s>) - then go and amend
the function to handle temporaries differently, or just delete it for
temporaries.

Bottom line: handling temporaries correctly is something that is
unavoidable, whether you teach it or just count on the students to get to
it by themselves at some point.

Is there something special - teaching-wise - for temporaries in
range-based-for? maybe.
Can it be solved specifically for temporaries in range-based-for? maybe.
But I'd argue it wouldn't make it easier to teach. Temporaries are still
there with their weird behavior.
Not saying that the proposed fix is bad - it can be useful in eliminating
potential bugs in range-based-for. But similar bugs in other, quite similar
code examples, can still occur.


On Fri, Nov 13, 2020 at 1:25 PM Peter Sommerlad (C++) via SG20 <
sg20_at_[hidden]> wrote:

> 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,
> >
> >
> >
>
>
> --
> Peter Sommerlad
>
> Better Software: Consulting, Training, Reviews
> Modern, Safe & Agile C++
>
> peter.cpp_at_[hidden]
> +41 79 432 23 32
> --
> SG20 mailing list
> SG20_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg20
>

Received on 2020-11-13 06:09:43