为什么 std::is_rvalue_reference 不做它所宣传的事情?

2023-12-29

例如,如果我有

#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
  }
};

复制自如何使模板右值引用参数仅绑定到右值引用? https://stackoverflow.com/questions/7863603/how-to-make-template-rvalue-reference-parameter-only-bind-to-rvalue-reference

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

有人能解释一下为什么显而易见的方法不起作用吗?


因为对于转发参考 https://en.cppreference.com/w/cpp/language/reference#Forwarding_references, T永远不会被推导为右值引用。假设传递一个类型的对象int to 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正如你在comment https://stackoverflow.com/questions/7863603/how-to-make-template-rvalue-reference-parameter-only-bind-to-rvalue-reference#comment9594188_7863645,或者在参数上使用它t, e.g.

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
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 std::is_rvalue_reference 不做它所宣传的事情? 的相关文章

随机推荐