Date: Fri, 15 Jan 2021 11:21:44 -0500
If the issue with >> is that it complicates template parsing, why can't we
just require it to be parenthesized? That is, FWD(x) would be written as
(>> x), and because the >> follows an opening parenthesis, it is easy to
tell that it cannot be two closing angle brackets. This is ugly, especially
considering that it would be rare for the argument to be a compound
expression, but I think it's still better than not having this feature at
all. We already have precedent in the standard: fold-expressions are
required to be parenthesized; this confuses some people at first, but
overall fold-expressions are a huge success.
On Fri, Jan 15, 2021 at 11:01 AM Arthur O'Dwyer via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On Fri, Jan 15, 2021 at 10:44 AM Bengt Gustafsson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>>
>> I think it should be a prefix operator, [...]
>
>
> Yes, >>x has been proposed before, but shot down.
>
> The OP's specific idea of postfix `&` or `&&` doesn't work because
> return x&&-y;
> return x&-y;
> already parse as meaningful expressions in C++.
>
> Anyway, with OP's specific idea for syntax gone, all that remains is OP's
> specific idea for semantics. OP should think about what this hypothetical
> facility would do with a variable `x` whose decltype is a non-reference
> type, e.g.
> auto foo(auto x) { return bar(HYPOTHETICAL_FWD_SYNTAX(x)); } // Moves
> (like std::forward/static_cast<decltype(x)>)? Copies? Ill-formed?
>
> Bengt wrote:
>
>> Preferably the operator should work both as move and as forward, it is a
>> struggle understanding which one to use
>
>
> Move and forward are different operations, though.
>
> auto move_from(auto&& x) { return std::move(x); }
> auto forward_from(auto&& x) { return std::forward<decltype(x)>(x); }
> int main() {
> std::shared_ptr<int> o = std::make_shared<int>(42);
> auto x = forward_from(o); // copies
> auto y = move_from(o); // moves
> assert(o == nullptr && x != nullptr && y != nullptr && x == y);
> }
>
> But my understanding is that you can always use forward<T>(x) and
>> move(x) is just a shortcut which is allowed when you know that x is a
>> parameter passed by rvalue reference.
>>
>
> No! `move` unconditionally moves; `forward<T>` is conditional, either
> moving or not-moving, based on the value of T (which is why it has to take
> a template parameter like that).
> Unfortunately I haven't written a blog post on this topic yet. But now
> it's on my list.
>
> HTH,
> –Arthur
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
just require it to be parenthesized? That is, FWD(x) would be written as
(>> x), and because the >> follows an opening parenthesis, it is easy to
tell that it cannot be two closing angle brackets. This is ugly, especially
considering that it would be rare for the argument to be a compound
expression, but I think it's still better than not having this feature at
all. We already have precedent in the standard: fold-expressions are
required to be parenthesized; this confuses some people at first, but
overall fold-expressions are a huge success.
On Fri, Jan 15, 2021 at 11:01 AM Arthur O'Dwyer via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On Fri, Jan 15, 2021 at 10:44 AM Bengt Gustafsson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>>
>> I think it should be a prefix operator, [...]
>
>
> Yes, >>x has been proposed before, but shot down.
>
> The OP's specific idea of postfix `&` or `&&` doesn't work because
> return x&&-y;
> return x&-y;
> already parse as meaningful expressions in C++.
>
> Anyway, with OP's specific idea for syntax gone, all that remains is OP's
> specific idea for semantics. OP should think about what this hypothetical
> facility would do with a variable `x` whose decltype is a non-reference
> type, e.g.
> auto foo(auto x) { return bar(HYPOTHETICAL_FWD_SYNTAX(x)); } // Moves
> (like std::forward/static_cast<decltype(x)>)? Copies? Ill-formed?
>
> Bengt wrote:
>
>> Preferably the operator should work both as move and as forward, it is a
>> struggle understanding which one to use
>
>
> Move and forward are different operations, though.
>
> auto move_from(auto&& x) { return std::move(x); }
> auto forward_from(auto&& x) { return std::forward<decltype(x)>(x); }
> int main() {
> std::shared_ptr<int> o = std::make_shared<int>(42);
> auto x = forward_from(o); // copies
> auto y = move_from(o); // moves
> assert(o == nullptr && x != nullptr && y != nullptr && x == y);
> }
>
> But my understanding is that you can always use forward<T>(x) and
>> move(x) is just a shortcut which is allowed when you know that x is a
>> parameter passed by rvalue reference.
>>
>
> No! `move` unconditionally moves; `forward<T>` is conditional, either
> moving or not-moving, based on the value of T (which is why it has to take
> a template parameter like that).
> Unfortunately I haven't written a blog post on this topic yet. But now
> it's on my list.
>
> HTH,
> –Arthur
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
-- *Brian Bi*
Received on 2021-01-15 10:21:58