[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