I'm still confused by the rules invented to support moving and forwarding. One thing I'm still not sure about is:
Is a forwarding reference just an rvalue reference (with reference collapsing rules applied)?
If it is an rvalue reference, then why does the function:
template<typename T>
void func(T&&);
accept not only rvalues, but also lvalues?
Before T is substituted, T && is an rvalue reference (obviously).
After T is substituted (and after references are collapsed), T && either remains an rvalue reference (if T is not a reference), or becomes an lvalue reference (if T is an lvalue reference).
I'm not sure if this answer will satisfy you, but I can point out the relevant parts of the standard. In a nutshell, the reference T&& is "grammatically" always an rvalue reference, but sometimes the type it ends up declaring is an lvalue reference type.
When this happens as the result of template argument deduction, the entire construct is called "forwarding reference", as a convenient shorthand. (This circumstance requires reference collapsing, but template argument deduction is not the only time reference collapsing happens.)
Now, on to the standard wording. First we have [dcl.ref] (e.g. p2, p6):
A reference type that is declared using
&is called an lvalue reference, and a reference type that is declared using&&is called an rvalue reference. [...]If a typedef-name (9.1.3, 13.1) or a decltype-specifier (9.1.7.2) denotes a type
TRthat is a reference to a typeT, an attempt to create the type “lvalue reference to cvTR” creates the type “lvalue reference toT”, while an attempt to create the type “rvalue reference to cvTR” creates the typeTR. [Note: This rule is known as reference collapsing. — end note]
Finally, the case of template argument deduction is handled in [temp.deduct.call]p3:
A forwarding reference is an rvalue reference to a cv-unqualified template parameter [...]
In other words, a forwarding reference is an rvalue reference, but it's one that accepts lvalues, too. (Note that the standard's definition of "forwarding reference" doesn't actually require the template argument to be deduced, although that is the primary way in which you would usually want to trigger the reference collapsing behaviour.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With