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.
Kerrek SB
source share