Template argument output - T is output and used by T &&

In the example

template <typename T> void function(T&& arg) 

Can someone explain in detail how this ends, that the signature of the function becomes T & for lvalues ​​and T && for missing values? I know that one way or another (a standard string is required) T β†’ T & in the case of lvalues ​​and T β†’ T in the case of revaluation, and then by combining and && it returns the value lvalue / rvalue.

+1
c ++ c ++ 11 templates
source share
2 answers

The rule is found in section 8.3.2p6.

If typedef, a type parameter template, or decltype specifies the type TR is a reference to type T , an attempt to create a type "lvalue reference to cv TR " creates a type "lvalue reference to T ", whereas an attempt to create a type "rvalue reference to cv TR " creates a type TR .

Or in tabular form:

 TR R T& & -> T& // lvalue reference to cv TR -> lvalue reference to T T& && -> T& // rvalue reference to cv TR -> TR (lvalue reference to T) T&& & -> T& // lvalue reference to cv TR -> lvalue reference to T T&& && -> T&& // rvalue reference to cv TR -> TR (rvalue reference to T) 
+4
source share

This is thanks to the rules for dropping links. Suppose U is not a reference type; then:

  T = UT & = U & T && = U && If T = U & , then T & = U & and T && = U & . T = U && T & = U & T && = U && 

Therefore, if your function argument can bind to a laleue reference of type U , then T must be de & shy; duced like U & so that T && becomes U & , and this is just a choice, since lvalues ​​cannot bind to rvalue links. On the other hand, if your argument is an rvalue of type U , then T is de & shy; duced like U , so T && becomes U && , and your argument can be bound.

The key point is that matching the reference type is T && (not T !). However, since arg itself is a named variable and therefore lvalue, you should use std::forward<T>(arg) to create an expression that is identical to the one your function was called with.

+4
source share

All Articles