[libcxx-commits] [PATCH] D107098: [libc++] Implement the underlying mechanism for range adaptors

Tim Song via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jul 30 10:29:45 PDT 2021


tcanens added a comment.

In D107098#2916919 <https://reviews.llvm.org/D107098#2916919>, @ldionne wrote:

> In D107098#2915589 <https://reviews.llvm.org/D107098#2915589>, @tcanens wrote:
>
>> Just a quick note: when P2281R1 <https://wg21.link/P2281R1> talks about perfect forwarding call wrappers, it really means perfect forwarding call wrappers exactly as specified in the standard <http://eel.is/c++draft/func.require#def:perfect_forwarding_call_wrapper>, that is:
>>
>>> A //perfect forwarding call wrapper// is an argument forwarding call wrapper that forwards its state entities to the underlying call expression. This forwarding step delivers a state entity of type `T` as  `cv T&` when the call is performed on an lvalue of the call wrapper type and as `cv T&&` otherwise, where `cv` represents the cv-qualifiers of the call wrapper and where `cv` shall be neither `volatile` nor `const volatile`.
>>
>> In particular, invoking an rvalue wrapper must deliver the state entity as an xvalue and cannot fall back to const lvalue the way `__perfect_forward` does (without deducing `this`, I believe that this requires additional deleted `operator()` overloads). This is particularly significant for `split` - see the examples in the paper.
>
> Thanks a lot for the heads up. However, I'm not entirely sure I understand where the issue is, because what I'm seeing for `__perfect_forward` is this (leaving aside `noexcept` and `-> decltype`):
>
>   template<class... _Args>
>   constexpr auto operator()(_Args&&... __args) &&
>   {return _Op::__call(std::get<_Idxs>(std::move(__bound_))..., std::forward<_Args>(__args)...);}
>
> Since we call `std::get` on `std::move(tuple)`, I think we end up passing rvalue references to `__call`, don't we? Or did you mean something else?

The `decltype` part is important - when `_Op::__call(std::get<_Idxs>(std::move(__bound_))..., std::forward<_Args>(__args)...)` is ill-formed, this overload SFINAEs away, and if the `const&` overload is viable, that can be used, which ends up delivering lvalues.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107098/new/

https://reviews.llvm.org/D107098



More information about the libcxx-commits mailing list