Section: 22.2.4 [forward] Status: CD1 Submitter: Jens Maurer Opened: 2008-03-13 Last modified: 2016-02-01
Priority: Not Prioritized
View all other issues in [forward].
View all issues with CD1 status.
Discussion:
p4 (forward) says:
Return type: If
T
is an lvalue-reference type, an lvalue; otherwise, an rvalue.
First of all, lvalue-ness and rvalue-ness are properties of an expression, not of a type (see 7.2.1 [basic.lval]). Thus, the phrasing "Return type" is wrong. Second, the phrase says exactly what the core language wording says for folding references in 13.4.2 [temp.arg.type]/p4 and for function return values in 7.6.1.3 [expr.call]/p10. (If we feel the wording should be retained, it should at most be a note with cross-references to those sections.)
The prose after the example talks about "forwarding as an int&
(an lvalue)" etc.
In my opinion, this is a category error: "int&
" is a type, "lvalue" is a
property of an expression, orthogonal to its type. (Btw, expressions cannot
have reference type, ever.)
Similar with move:
Return type: an rvalue.
is just wrong and also redundant.
Proposed resolution:
Change 22.2.4 [forward] as indicated:
template <class T> T&& forward(typename identity<T>::type&& t);...
Return type: IfT
is an lvalue-reference type, an lvalue; otherwise, an rvalue....
-7- In the first call to
factory
,A1
is deduced asint
, so 2 is forwarded toA
's constructor asanan rvalueint&&
(). In the second call to factory,A1
is deduced asint&
, soi
is forwarded toA
's constructor asanan lvalueint&
(). In both cases,A2
is deduced as double, so 1.414 is forwarded toA
's constructor asan rvaluedouble&&
().template <class T> typename remove_reference<T>::type&& move(T&& t);...
Return type: an rvalue.