谁能帮我理解为什么会输出以下代码
template< typename T >
void check()
{
std::cout << "unknow type" << std::endl;
}
template<>
void check<int>()
{
std::cout << "int" << std::endl;
}
template<>
void check<int&>()
{
std::cout << "int&" << std::endl;
}
template<>
void check<int&&>()
{
std::cout << "int&&" << std::endl;
}
template< typename T >
void bar( T&& a )
{
check<T>();
}
int main()
{
bar(0);
int a = 0;
bar( a );
}
是
int
int&
不是
int&&
int&
从我的角度来看,右值引用保留为右值引用,左值引用保留为左值引用似乎更直观,但是,似乎只有左值引用保留为左值引用和右值成为非引用值。 这背后的动机/想法是什么?
最佳答案
bar(0);
调用特化 bar<int>(int&&)
即 T
推导为 int
, 所以 check<T>()
是check<int>()
.参数类型为T&&
这是 int&&
,但这是参数的类型,而不是类型 T
.
这与非转发引用完全一致。如果你定义:
template<typename T> void baz(T&);
然后你用 int
类型的左值调用它然后 T
推导为 int
, 不是 int&
像您的示例使用的转发引用的唯一特殊之处在于 T&&
该类型可以推导为左值引用,称它为R
, 在这种情况下参数类型是 R&&
与 add_rvalue_reference_t<R>
相同这就是 R
.所以调用电话bar(a)
你叫专业bar<int&>(int&)
即 T
推导为 int&
当您调用 bar<int&&>(0)
时对于显式模板参数列表,没有参数推导,因此 T
被 int&&
取代, 所以参数类型 T&&
是add_rvalue_reference_t<int&&>
这就是 int&&
.
关于c++ - 使用通用引用时的类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40554575/