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.
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); }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 >>
xstd::forward<T>(x)-2- Returns:is
[2016-03 Jacksonville: Move to Ready]
Proposed resolution:
This wording is relative to N4567.
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); }
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