为什么std :: is_rvalue_reference不做广告宣传?

时间:2018-12-13 09:35:07

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

例如,如果我有

#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。我已经在自己的代码中对此进行了验证,前者可以工作,而后者则不能。

有人可以解释为什么显而易见的东西不起作用吗?

1 个答案:

答案 0 :(得分:4)

由于forwarding referenceT永远不会被推导为右值引用。假设将类型为int的对象传递给OwnershipReceiver,如果该对象是左值,则将推导T作为左值引用,即int&;如果对象是右值,则将T推导为非引用,即int。这就是std::is_rvalue_reference<T>::value不能正常运行的原因,因为它总是false

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

换句话说,此处的要点是区分左值引用和非引用,因此!std::is_reference<T>::value也适用。


顺便说一句:如果您坚持使用std::is_rvalue_reference,则可以使用comment中的std::is_rvalue_reference<T&&>::value,也可以在参数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
}