使用通用引用时的类型推导

Type deduction while using universal references

谁能帮我理解为什么会输出下面的代码

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&

从我的角度来看,右值引用保留为右值引用,左值引用保留为左值引用似乎更直观,但是,似乎只有左值引用保留为左值引用,右值变为非引用值。 这背后的motivation/idea是什么?

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) 时,没有参数推导,因此 Tint&& 替代,因此参数类型 T&&add_rvalue_reference_t<int&&> 这只是 int&&.