c++ - 模板化函数和类中的 T&&

标签 c++ c++11 rvalue-reference pass-by-rvalue-reference

我刚刚偶然发现 T&& 在类和函数中有不同的含义。
在函数中:

template<class T> void f(T&& t){};   // t is R or L-value
...
int i=0; 
f(i);   // t in f is lvalue
f(42);  // t in f is rvalue  

在类里面:

template<class T> 
struct S { 
       S(T&& t){}  // t is only R-value? 
};
...
int i;
S<int> ss(i);   // compile error - cannot bind lvalue to ‘int&&’

这是否意味着如果我们在类中有T&& t,那么t 将只是右值?
谁能告诉我在哪里可以获得更多相关信息?
这是否意味着我需要为 L 值和 R 值编写两个方法重载?

回答
正如 Alf 的示例所示,函数和类中的 t 可以是左值或右值。

最佳答案

你在这里处理模板参数推导。

通过使用 f 没有显式定义模板参数,C++ 编译器现在必须决定模板参数的类型 T来自您传递给它的参数。

&& 模板参数推导规则类型是特殊的,可以完美转发。当您使用 f(i) , T推导为 T& .因此,参数 t类型为 T& && ,折叠成 T& .但是,当您使用 f(42) , 类型 T推导为 T&& ,因此 tT&& && ,折叠成 T&& .

一旦你强制 T成为特定类型,所有这些都会有效地消失。崩溃仍然会发生,但是因为你使用了 S<int> , 然后 t将是 int&& 类型. S<int> ss(i)实际上相当于 f<int>(i) ,这也不合法。由于模板参数推导仅适用于函数而不适用于类型,因此您必须为 S 执行类似的操作如果你想要完美转发:

template<class T> 
struct S { 
    template<class U>
    S(U&& t){}
};

当然可以使用SFINAE方法和模板元编程来保证只有T的基本类型才能实例化构造器模板和 U是一样的。

关于c++ - 模板化函数和类中的 T&&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12323308/

相关文章:

c++ - 如果在堆上创建 vector ,是否意味着我可以从任何其他函数访问它?怎么样?

c++ - 寻求对 std::forward 的澄清

c++11:为什么 std::forward 中的 static_assert 是必需的?

c++ - 如何在 C++ 中的 visual studio 2010 中添加 .a 文件

c++ - 如何从 C++ 代码中获取统计分布?

c++ - 使用 std c++11 智能指针转换为非标量类型

c++ - 何时更喜欢 const 左值引用而不是右值引用模板

c++ - 对象、右值引用、常量引用之间的重载解析

c++ - 用于 C++ 运算符重载的 Python 绑定(bind)

c++ - 如何在 C++11 中创建线程对象数组?