7

我知道,给定一个初始化转发/通用引用的表达式,左值被推断为类型T&和右值类型T(而不是T&&)。

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

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

并不是,

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

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

4

1 回答 1

4

因为在当时,将右值A参数推导为A&&而不是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 年所追求的收益/成本比率相比。

于 2013-05-04T15:42:52.250 回答