为什么通用参考被视为 R 值参考?
Why is Universal reference being treated as R-Value reference?
#include <iostream>
class A
{
public:
A() {};
};
template <class T>
class Test
{
public:
void func1(T&& t)
{
}
};
int main()
{
A a;
Test<A> o1;
o1.func1(a);
return 0;
}
编译时出现以下错误
error C2664: 'void Test<A>::func1(T &&)': cannot convert argument 1 from 'A' to 'T &&'
note: You cannot bind an lvalue to an rvalue reference
o1
是用"A"
实例化模板class测试得到的。所以调用 o1.func1(a)
应该知道 void func1(T&& t)
应该解析为 void func1(A&& t)
我认为void func1(T&& t)
中的T&&
应该被推断为通用引用或转发引用,因为它来自模板类型参数。那为什么在上面的错误中它说 "You cannot bind an lvalue to an rvalue reference"
?
我是不是漏掉了一些模板魔法?
I thought T&&
in void func1(T&& t)
should be deduced as a universal reference or a forwarding reference [...]
没有。 t
在您的示例中不是通用参考。要成为通用参考,它必须从调用中推导出来,但在您的示例中 T
只是 A
。这是一个通用参考:
template <class T>
class Test
{
public:
template <typename X>
void func1(X&& t)
{
}
};
重要的细节被“演绎”出来了。在您的示例中,没有任何推论。考虑 Test<A>
等同于
class TestA
{
public:
void func1(A&& t)
{
}
};
一旦你实例化了class模板,它的方法func1
有参数tpyeA&&
,不是别的东西,即没有什么可以推导了。当您没有明确声明模板参数时,就会发生模板参数推导,如
template <typename T> void foo(T&& t) {};
foo(1);
#include <iostream>
class A
{
public:
A() {};
};
template <class T>
class Test
{
public:
void func1(T&& t)
{
}
};
int main()
{
A a;
Test<A> o1;
o1.func1(a);
return 0;
}
编译时出现以下错误
error C2664: 'void Test<A>::func1(T &&)': cannot convert argument 1 from 'A' to 'T &&'
note: You cannot bind an lvalue to an rvalue reference
o1
是用"A"
实例化模板class测试得到的。所以调用 o1.func1(a)
应该知道 void func1(T&& t)
应该解析为 void func1(A&& t)
我认为void func1(T&& t)
中的T&&
应该被推断为通用引用或转发引用,因为它来自模板类型参数。那为什么在上面的错误中它说 "You cannot bind an lvalue to an rvalue reference"
?
我是不是漏掉了一些模板魔法?
I thought
T&&
invoid func1(T&& t)
should be deduced as a universal reference or a forwarding reference [...]
没有。 t
在您的示例中不是通用参考。要成为通用参考,它必须从调用中推导出来,但在您的示例中 T
只是 A
。这是一个通用参考:
template <class T>
class Test
{
public:
template <typename X>
void func1(X&& t)
{
}
};
重要的细节被“演绎”出来了。在您的示例中,没有任何推论。考虑 Test<A>
等同于
class TestA
{
public:
void func1(A&& t)
{
}
};
一旦你实例化了class模板,它的方法func1
有参数tpyeA&&
,不是别的东西,即没有什么可以推导了。当您没有明确声明模板参数时,就会发生模板参数推导,如
template <typename T> void foo(T&& t) {};
foo(1);