This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2328. Rvalue stream extraction should use perfect forwarding

Section: 31.7.5.6 [istream.rvalue] Status: C++17 Submitter: Stephan T. Lavavej Opened: 2013-09-21 Last modified: 2017-07-30

Priority: 3

View all other issues in [istream.rvalue].

View all issues with C++17 status.

Discussion:

31.7.5.6 [istream.rvalue] declares `operator>>(basic_istream<charT, traits>&& is, T& x)`. However, [istream::extractors]/7 declares `operator>>(basic_istream<charT,traits>& in, charT* s)`, plus additional overloads for `unsigned char*` and `signed char*`. This means that "`return_rvalue_istream() >> &arr[0]`" won't compile, because `T&` won't bind to the rvalue `&arr[0]`.

[2014-02-12 Issaquah : recategorize as P3]

Jonathan Wakely: Bill was certain the change is right, I think so with less certainty

Jeffrey Yaskin: I think he's right, hate that we need this

Jonathan Wakely: is this the security issue Jeffrey raised on lib reflector?

Move to P3

[2015-05-06 Lenexa: Move to Review]

WEB, MC: Proposed wording changes one signature (in two places) to take a forwarding reference.

TK: Should be consistent with an istream rvalue?

MC: This is the case where you pass the stream by rvalue reference.

RP: I would try it before standardizing.

TK: Does it break anything?

RP, TK: It will take all arguments, will be an exact match for everything.

RS, TK: This adapts streaming into an rvalue stream to make it act like streaming into an lvalue stream.

RS: Should this really return the stream by lvalue reference instead of by rvalue reference? ⇒ new LWG issue.

RP: Security issue?

MC: No. That's `istream >> char*`, C++ version of `gets()`. Remove it, as we did for `gets()`? ⇒ new LWG issue.

RS: Proposed resolution looks correct to me.

MC: Makes me (and Jonathan Wakely) feel uneasy.

Move to Review, consensus.

[2016-01-15, Daniel comments and suggests improved wording]

It has been pointed out by Tim Song, that the initial P/R (deleting the Returns paragraph and making the Effects "equivalent to `return is >> /* stuff */;`") breaks cases where the applicable `operator>>` doesn't return a type that is convertible to a reference to the stream:

>     struct A{};
>     void operator>>(std::istream&, A&){ }

>     void f() {
>       A a;
>       std::istringstream() >> a; // was OK, now error
>     }

This seems like an unintended wording artifact of the "Equivalent to" Phrase Of Power and could be easily fixed by changing the second part of the P/R slightly as follows:

>     template <class charT, class traits, class T>
>       basic_istream<charT, traits>&
>       operator>>(basic_istream<charT, traits>&& is, T&& x);

> > -1- Effects: Equivalent to:`is >>x`

> > >     is >> std::forward<T>(x);
> > >     return is;

> > -2- Returns: `is`

Previous resolution [SUPERSEDED]:

> This wording is relative to N4567.

> 1. Edit [iostream.format.overview], header `<istream>` synopsis, as indicated:

>    >     namespace std {
>    >       […]
>    >       template <class charT, class traits, class T>
>    >         basic_istream<charT, traits>&
>    >         operator>>(basic_istream<charT, traits>&& is, T&& x);
>    >     }

> 2. Edit 31.7.5.6 [istream.rvalue] as indicated:

>    >     template <class charT, class traits, class T>
>    >       basic_istream<charT, traits>&
>    >       operator>>(basic_istream<charT, traits>&& is, T&& x);

>    > > -1- Effects: Equivalent to `return` `is >>x std::forward<T>(x)`

>    > > -2- Returns: `is`

[2016-03 Jacksonville: Move to Ready]

Proposed resolution:

This wording is relative to N4567.

1. Edit [iostream.format.overview], header `<istream>` synopsis, as indicated:

   >     namespace std {
   >       […]
   >       template <class charT, class traits, class T>
   >         basic_istream<charT, traits>&
   >         operator>>(basic_istream<charT, traits>&& is, T&& x);
   >     }

2. Edit 31.7.5.6 [istream.rvalue] as indicated:

   >     template <class charT, class traits, class T>
   >       basic_istream<charT, traits>&
   >       operator>>(basic_istream<charT, traits>&& is, T&& x);

   > > -1- Effects: Equivalent to:`is >>x`

   > > >     is >> std::forward<T>(x);
   > > >     return is;

   > > -2- Returns: `is`