【问题标题】:Why forwarding reference does not deduce to rvalue reference in case of rvalue?为什么在右值的情况下转发引用不会推断为右值引用?
【发布时间】:2013-04-28 17:46:41
【问题描述】:

我知道,给定一个初始化转发/通用引用的表达式,左值被推断为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&amp;&amp; 类型?我猜,如果它们被推断为T&amp;&amp;,那么同样的引用折叠规则也适用于T&amp;&amp; &amp;&amp;T&amp;&amp; 相同。

【问题讨论】:

  • enable_if&lt;is_rvalue_reference&lt;T&amp;&amp;&gt;, ...&gt; 可以。 :) 但至于为什么它被推断为T - 因为这就是它与左值引用一起工作的方式? T&amp; -> U 参数 -> U&amp;。特殊的是左值情况,而不是右值情况。

标签: c++ c++11 templates perfect-forwarding template-argument-deduction


【解决方案1】:

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

【讨论】:

  • 我浏览了那些论文,也浏览了其他一些完美转发的特殊语法,但从未清楚地理解为什么选择T而不是T&amp;&amp;。通过 n1385,即使提案 #7 也提到了引用折叠,并说“当参数是左值时将 A1 推导出为引用类型,否则推导出为非引用类型”,但没有给出任何理由为什么不是右值引用类型。我只是想知道历史,因为对我来说,T&amp;&amp; 而不是T 的演绎看起来更加对称,并且看起来也适用于所有情况,包括std::forward
  • 是的,我同意,我认为它会起作用。但这种额外的变化很可能导致委员会接受的“变化太大”。它可能会破坏 C++11 中的右值引用。而且没有冒险的动机。
猜你喜欢
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多