例如如果我有
#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
。我已经在我自己的代码中验证了这一点,前者有效而后者无效。
谁能解释为什么显而易见的方法不起作用?
最佳答案
因为 forwarding reference , 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
正如您在 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
}
关于c++ - 为什么 std::is_rvalue_reference 没有按照广告宣传的那样做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53758796/