我刚刚偶然发现 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&&
,因此 t
是T&& &&
,折叠成 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/