【问题标题】:Why does std::is_rvalue_reference not do what it is advertised to do?为什么 std::is_rvalue_reference 不做它宣传的事情?
【发布时间】:2018-12-13 09:35:06
【问题描述】:

例如,如果我有

#include <type_traits>

struct OwnershipReceiver
{
  template <typename T,
            class = typename std::enable_if
            <
                !std::is_lvalue_reference<T>::value
            >::type
           >
  void receive_ownership(T&& t)
  {
     // taking file descriptor of t, and clear t
  }
};

复制自How to make template rvalue reference parameter ONLY bind to rvalue reference?

海报使用!std::is_lvalue_reference,而不是更明显的std::is_rvalue_reference。我已经在我自己的代码中验证了这一点,前者有效,后者无效。

谁能解释为什么显而易见的方法不起作用?

【问题讨论】:

  • 您是否阅读了有关您已链接问题的已接受答案的 cmets?似乎对我来说已经很好地回答了你的问题。如果没有,在您的问题中至少包含一个您希望不起作用的具体示例可能会很有用。
  • 你读过cmets吗?最后一条评论问为什么,没有答案。值得提出一个额外的问题来澄清推理。
  • 好的,有一个建议使用 is_rvalue_reference::value 代替,我想我可以结合@songyuanyao的回答来理解为什么

标签: c++ c++11 templates enable-if


【解决方案1】:

因为对于forwarding referenceT 永远不会被推断为右值引用。假设将int类型的对象传递给OwnershipReceiver,如果对象是左值,T将被推导出为左值引用,即int&amp;;如果对象是右值,T 将被推断为非引用,即int。这就是为什么std::is_rvalue_reference&lt;T&gt;::value 不起作用的原因,因为它总是false

请注意,代码的目的是确保OwnershipReceiver 的参数类型是右值引用,并不意味着T 的类型也是右值引用。

换句话说,这里的重点是区分左值引用和非引用,所以!std::is_reference&lt;T&gt;::value也可以。


顺便说一句:如果你坚持std::is_rvalue_reference,你可以使用std::is_rvalue_reference&lt;T&amp;&amp;&gt;::value,就像你在comment中找到的那样,或者在参数t上使用它,例如

template <typename T>
auto receive_ownership(T&& t) -> typename std::enable_if<std::is_rvalue_reference<decltype(t)>::value>::type      
{
   // taking file descriptor of t, and clear t
}

【讨论】:

  • 你能举一些具体的例子来澄清一下吗?
  • @bradgonesurfing 对不起,我走错了方向。固定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 2014-06-16
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多