c++ - 为什么 std::is_rvalue_reference 没有按照广告宣传的那样做?

标签 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。我已经在我自己的代码中验证了这一点,前者有效而后者无效。

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

最佳答案

因为 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/

相关文章:

c++ - 按值或引用传递容器

c++ - 使用指定的初始值设定项进行模板参数推导

c++ - std::cin 到 char 数组会跳过空格吗?

c++ - 我的第一个 Qt 应用程序,c++(小 opencv)

lambda - 很多函数还是很多 Lambda?

c++ - 只有当值尾随字母 'e'(大写和小写)时,使用 std::cin 的输入才不适用于 float

c++ - g++ 和 clang++ 具有完整模板参数的不同行为

c++ - 模板重载和 SFINAE 仅适用于函数而不适用于类

c++ - 如何将参数的数组初始值设定项迁移到 C++11 中的可变模板参数

loops - 包含循环的 Powershell 文本/html 模板