为什么std :: is_rvalue_reference没有做广告要做的事情?

bra*_*ing 8 c++ templates enable-if c++11

例如,如果我有

#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
  }
};
Run Code Online (Sandbox Code Playgroud)

复制自如何使模板右值引用参数仅绑定到右值引用?

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

任何人都可以解释为什么明显不起作用?

son*_*yao 6

因为对于转发引用T永远不会推论为右值引用。假设将一个类型int为的对象传递给OwnershipReceiver,如果该对象是左值,T则将推导为左值引用,即int&; 如果对象是右值,T则将其推导为非引用,即int。这就是为什么std::is_rvalue_reference<T>::value它永远不会起作用的原因false

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

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


顺便说一句:如果您坚持使用std::is_rvalue_reference,则可以使用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
}
Run Code Online (Sandbox Code Playgroud)