为什么在rvalue的情况下转发引用不演绎为rvalue引用?

abi*_*bir 6 c++ templates perfect-forwarding c++11 template-argument-deduction

我知道,给定一个初始化转发/通用引用的表达式,就可以推断出lvalues是type,T&而rvalues是type T(而不是T&&)。

因此,为了只允许右值,需要写

template<class T, enable_if<not_<is_lvalue_reference<T> >,OtherConds... > = yes>
void foo(T&& x) {}
Run Code Online (Sandbox Code Playgroud)

并不是,

template<class T, enable_if<is_rvalue_reference<T>,OtherConds... > = yes>
void foo(T&& x) {}
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么对于转发引用,右值被推导为类型T而不是T&&?我猜想,如果推论为,T&&则相同的引用折叠规则也与T&& &&相同T&&

How*_*ant 5

因为当时,将右值A参数推导为 asA&&而不是A被视为不必要的复杂化并且背离了正常的推导规则:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm

我们真的不知道我们是否可以得到一个推导规则的例外(对于左值A情况),我们甚至从未想过我们敢于要求两个例外。要做到这一点,好处就必须是:它使不可能的事情成为可能。

毕竟,如果没有针对左值情况的单一特殊推导规则,完美转发是不可能的,正如 N1385 所恰当地证明的那样。

即使在今天看来,添加另一个特殊的扣除规则以便客户可以避免必须否定模板约束,似乎也不是一个非常高的效益/成本比。特别是与 2002 年我们所追求的效益/成本比相比。