Date: Wed, 22 Jul 2020 11:19:52 +0000
> -----Original Message-----
> From: Peter Sommerlad (C++) <peter.cpp_at_sommerlad.ch>
> Sent: Wednesday, July 22, 2020 11:36 AM
> To: Michael Hava <mfh_at_[hidden]>
> Cc: std-proposals_at_lists.isocpp.org
> Subject: Re: [std-proposals] Language Feature for Reducing Duplicated Code
>
> I still think it might be better to return by value from rref-qualified members
> to avoid dangling, e.g. in the following:
>
> auto&& dangle = vector{1,2,3}[0];
Sure, the following would work too...
T operator[](size_t i) &&;
But, has additional requirements on T compared to the version returning T&&...
What's gonna happen for non-moveable types?
Additionally you'd have to think about those pesky throwing moves...
(I'm not too thrilled about the idea of accessing the guts of a temporary may involve copies or throws.)
All that trouble, preventing the user from handing out a "temporary reference" (which would be totally fine as a sink parameter [1]), just to prevent the stupid mistake of storing a dangling reference locally via "auto &&"?
[1] https://godbolt.org/z/fb15q7
In a safety-first above all else language? Yeah, that sounds like a good idea.
But in a language that supports this:
int main() {
using namespace std::string_literals;
std::string_view sv{"This string will be dangled on!"s};
std::cout << sv << "\n"; //access dangling string
}
Not convinced.
Don't get me wrong, dangling is a real problem (though I can't even remember when I last encountered it).
But applying a local fix to a global problem will not lead to a clean, well thought out, design.
>
> And there is no need for overloading on const&&, because that would be
> ridiculous, since you can not move from a const object.
Ridiculous or not, that's what we got for std::get...
And while const&& is not really useful for moving, it is somewhat useful for detecting (severe) programming errors - e.g. std::[c]ref.
Best Regards,
Michael
> I think, blindly following the pattern
>
> T && operator[](size_t i) &&;
>
> is bad and not really helpful. RVO helps with that and a move-optimized T
> will have the appropriate constructor.
>
> Regards
> Peter.
>
> Michael Hava wrote on 22.07.20 11:28:
> > And while we are at it:
> > Operations that return references to internals of an object should also be
> rvalue-ref-qualified, as there is no reason one shouldn't be able to move the
> guts out of a temporary...
> >
> > T & operator[](size_t i) &;
> > const T & operator[](size_t i) const &; T && operator[](size_t i) &&;
> > const T && operator[](size_t i) const &&;
> >
> > Matching what we already do with std::get for array/pair/tuple/variant ...
> >
> >> -----Original Message-----
> >> From: Std-Proposals <std-proposals-bounces_at_lists.isocpp.org> On
> >> Behalf Of Peter Sommerlad (C++) via Std-Proposals
> >> Sent: Wednesday, July 22, 2020 9:10 AM
> >> To: David Ledger via Std-Proposals <std-proposals_at_lists.isocpp.org>
> >> Cc: Peter Sommerlad (C++) <peter.cpp_at_sommerlad.ch>
> >> Subject: Re: [std-proposals] Language Feature for Reducing Duplicated
> >> Code
> >>
> >> David,
> >>
> >> You are missing the ref-qualification.
> >>
> >> I always argue that member functions returning the guts of an object
> >> or a reference to *this should be lvalue-ref qualified to make sure
> >> they are not called on temporaries, because that would lead to
> >> immediate dangling. So your examples (in my book) should be
> >>
> >> iterator begin() &;
> >> iterator begin() const &;
> >> >
> >> T & operator[](size_t i) &;
> >> T const & operator[](size_t i) const &;
> >>
> >> Just my 0.02CHF
> >>
> >> Peter.
> >>
> >> David Ledger via Std-Proposals wrote on 18.07.20 07:29:
> >>> Hello Everyone,
> >>>
> >>> Duplicate function bodies seem to exist everywhere in C++ codebases.
> >>> This attempts to reduce duplicate code by allowing deduction of
> >>> const for a
> >> function. Allowing a const and non-const function to have the same
> >> function body but call the appropriate const or non-const functions.
> >>>
> >>> What I'm talking about it that everyone writes:
> >>>
> >>> iterator begin();
> >>> iterator begin() const;
> >>>
> >>> T & operator[](size_t i);
> >>> T const & operator[](size_t i) const;
> >>>
> >>> Same for operator[] and function at, and begin, end, front, back etc...
> >>>
> >>> For the const and non-const versions of the function, often the body
> >>> of
> >> these functions is identical, all that changes is the return type and
> >> the selected overloads in the function body. I don't really see the
> >> benefit for this and want to improve this.
> >>>
> >>> So I want to propose the following:
> >>>
> >>> const(auto),
> >>> const(boolean expr)
> >>>
> >>> noexcept(auto), we already have noexcept(boolean expr)
> >>>
> >>> This would let me write:
> >>>
> >>> iterator begin() const(auto);
> >>>
> >>> The problem this introduces is how is the return type determined
> >>> here,
> >> well to do that we would need the bool available for the user:
> >>>
> >>> abbreviated syntax:
> >>> auto begin() const(is_const) -> iterator<is_const>;
> >>>
> >>> or,
> >>>
> >>> template syntax:
> >>> template <bool is_const>
> >>> auto begin() const(is_const) -> iterator<is_const>;
> >>>
> >>> or,
> >>>
> >>> template syntax with return using conditional_t
> >>> auto begin() const(is_const) -> conditional_t<is_const, citerator,
> >>> iterator>;
> >>>
> >>> There are additional benefits here:
> >>> - Keep function logic in one place, not many.
> >>> - Use template parameters of a class to fully const or not-const all
> >>> functions
> >> in a class.
> >>> - Reduce the maintenance cost of std library code by halving (in
> >>> some
> >> cases) the number of overloads.
> >>>
> >>> As I see it, what needs to be solved:
> >>> - Member function pointers, how to get an exact one?
> >>>
> >>> I'm happy to write up a proposal for this to submit.
> >>> Anyone have and feedback before I write it up?
> >>>
> >>> Regards,
> >>> David Ledger
> >>>
> >>
> >>
> >> --
> >> Peter Sommerlad
> >>
> >> Better Software: Consulting, Training, Reviews Modern, Safe & Agile
> >> C++
> >>
> >> peter.cpp_at_sommerlad.ch
> >> +41 79 432 23 32
> >> --
> >> Std-Proposals mailing list
> >> Std-Proposals_at_[hidden]socpp.org
> >> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
> --
> Peter Sommerlad
>
> Better Software: Consulting, Training, Reviews Modern, Safe & Agile C++
>
> peter.cpp_at_[hidden]
> +41 79 432 23 32
> From: Peter Sommerlad (C++) <peter.cpp_at_sommerlad.ch>
> Sent: Wednesday, July 22, 2020 11:36 AM
> To: Michael Hava <mfh_at_[hidden]>
> Cc: std-proposals_at_lists.isocpp.org
> Subject: Re: [std-proposals] Language Feature for Reducing Duplicated Code
>
> I still think it might be better to return by value from rref-qualified members
> to avoid dangling, e.g. in the following:
>
> auto&& dangle = vector{1,2,3}[0];
Sure, the following would work too...
T operator[](size_t i) &&;
But, has additional requirements on T compared to the version returning T&&...
What's gonna happen for non-moveable types?
Additionally you'd have to think about those pesky throwing moves...
(I'm not too thrilled about the idea of accessing the guts of a temporary may involve copies or throws.)
All that trouble, preventing the user from handing out a "temporary reference" (which would be totally fine as a sink parameter [1]), just to prevent the stupid mistake of storing a dangling reference locally via "auto &&"?
[1] https://godbolt.org/z/fb15q7
In a safety-first above all else language? Yeah, that sounds like a good idea.
But in a language that supports this:
int main() {
using namespace std::string_literals;
std::string_view sv{"This string will be dangled on!"s};
std::cout << sv << "\n"; //access dangling string
}
Not convinced.
Don't get me wrong, dangling is a real problem (though I can't even remember when I last encountered it).
But applying a local fix to a global problem will not lead to a clean, well thought out, design.
>
> And there is no need for overloading on const&&, because that would be
> ridiculous, since you can not move from a const object.
Ridiculous or not, that's what we got for std::get...
And while const&& is not really useful for moving, it is somewhat useful for detecting (severe) programming errors - e.g. std::[c]ref.
Best Regards,
Michael
> I think, blindly following the pattern
>
> T && operator[](size_t i) &&;
>
> is bad and not really helpful. RVO helps with that and a move-optimized T
> will have the appropriate constructor.
>
> Regards
> Peter.
>
> Michael Hava wrote on 22.07.20 11:28:
> > And while we are at it:
> > Operations that return references to internals of an object should also be
> rvalue-ref-qualified, as there is no reason one shouldn't be able to move the
> guts out of a temporary...
> >
> > T & operator[](size_t i) &;
> > const T & operator[](size_t i) const &; T && operator[](size_t i) &&;
> > const T && operator[](size_t i) const &&;
> >
> > Matching what we already do with std::get for array/pair/tuple/variant ...
> >
> >> -----Original Message-----
> >> From: Std-Proposals <std-proposals-bounces_at_lists.isocpp.org> On
> >> Behalf Of Peter Sommerlad (C++) via Std-Proposals
> >> Sent: Wednesday, July 22, 2020 9:10 AM
> >> To: David Ledger via Std-Proposals <std-proposals_at_lists.isocpp.org>
> >> Cc: Peter Sommerlad (C++) <peter.cpp_at_sommerlad.ch>
> >> Subject: Re: [std-proposals] Language Feature for Reducing Duplicated
> >> Code
> >>
> >> David,
> >>
> >> You are missing the ref-qualification.
> >>
> >> I always argue that member functions returning the guts of an object
> >> or a reference to *this should be lvalue-ref qualified to make sure
> >> they are not called on temporaries, because that would lead to
> >> immediate dangling. So your examples (in my book) should be
> >>
> >> iterator begin() &;
> >> iterator begin() const &;
> >> >
> >> T & operator[](size_t i) &;
> >> T const & operator[](size_t i) const &;
> >>
> >> Just my 0.02CHF
> >>
> >> Peter.
> >>
> >> David Ledger via Std-Proposals wrote on 18.07.20 07:29:
> >>> Hello Everyone,
> >>>
> >>> Duplicate function bodies seem to exist everywhere in C++ codebases.
> >>> This attempts to reduce duplicate code by allowing deduction of
> >>> const for a
> >> function. Allowing a const and non-const function to have the same
> >> function body but call the appropriate const or non-const functions.
> >>>
> >>> What I'm talking about it that everyone writes:
> >>>
> >>> iterator begin();
> >>> iterator begin() const;
> >>>
> >>> T & operator[](size_t i);
> >>> T const & operator[](size_t i) const;
> >>>
> >>> Same for operator[] and function at, and begin, end, front, back etc...
> >>>
> >>> For the const and non-const versions of the function, often the body
> >>> of
> >> these functions is identical, all that changes is the return type and
> >> the selected overloads in the function body. I don't really see the
> >> benefit for this and want to improve this.
> >>>
> >>> So I want to propose the following:
> >>>
> >>> const(auto),
> >>> const(boolean expr)
> >>>
> >>> noexcept(auto), we already have noexcept(boolean expr)
> >>>
> >>> This would let me write:
> >>>
> >>> iterator begin() const(auto);
> >>>
> >>> The problem this introduces is how is the return type determined
> >>> here,
> >> well to do that we would need the bool available for the user:
> >>>
> >>> abbreviated syntax:
> >>> auto begin() const(is_const) -> iterator<is_const>;
> >>>
> >>> or,
> >>>
> >>> template syntax:
> >>> template <bool is_const>
> >>> auto begin() const(is_const) -> iterator<is_const>;
> >>>
> >>> or,
> >>>
> >>> template syntax with return using conditional_t
> >>> auto begin() const(is_const) -> conditional_t<is_const, citerator,
> >>> iterator>;
> >>>
> >>> There are additional benefits here:
> >>> - Keep function logic in one place, not many.
> >>> - Use template parameters of a class to fully const or not-const all
> >>> functions
> >> in a class.
> >>> - Reduce the maintenance cost of std library code by halving (in
> >>> some
> >> cases) the number of overloads.
> >>>
> >>> As I see it, what needs to be solved:
> >>> - Member function pointers, how to get an exact one?
> >>>
> >>> I'm happy to write up a proposal for this to submit.
> >>> Anyone have and feedback before I write it up?
> >>>
> >>> Regards,
> >>> David Ledger
> >>>
> >>
> >>
> >> --
> >> Peter Sommerlad
> >>
> >> Better Software: Consulting, Training, Reviews Modern, Safe & Agile
> >> C++
> >>
> >> peter.cpp_at_sommerlad.ch
> >> +41 79 432 23 32
> >> --
> >> Std-Proposals mailing list
> >> Std-Proposals_at_[hidden]socpp.org
> >> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
> --
> Peter Sommerlad
>
> Better Software: Consulting, Training, Reviews Modern, Safe & Agile C++
>
> peter.cpp_at_[hidden]
> +41 79 432 23 32
Received on 2020-07-22 06:23:12