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

### 808. §[forward] incorrect redundant specification

Section: 20.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 20.2.4 [forward] as indicated:

>     template <class T> T&& forward(typename identity<T>::type&& t);

> > ...

> > Return type: If `T` is an lvalue-reference type, an lvalue; otherwise, an rvalue.

> > ...

> > -7- In the first call to `factory`, `A1` is deduced as `int`, so 2 is forwarded to `A`'s constructor as an `int&&` (an rvalue). In the second call to factory, `A1` is deduced as `int&`, so `i` is forwarded to `A`'s constructor as an `int&` (an lvalue). In both cases, `A2` is deduced as double, so 1.414 is forwarded to `A`'s constructor as `double&&` (an rvalue).

>     template <class T> typename remove_reference<T>::type&& move(T&& t);

> > ...

> > Return type: an rvalue.