有人可以帮助我理解为什么输出以下代码
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&
从我的观点来看,似乎更直观的是,r值引用保留为r值引用,l值引用保留为l值引用,但似乎只有l值引用仍为l值引用和r值变为非参考值。 这背后的动机/想法是什么?
答案 0 :(得分:4)
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&&
为{ {1}}只是add_rvalue_reference_t<int&&>
。