const T&和T&在模板推导中有什么区别

时间:2019-03-18 08:37:10

标签: c++ templates template-deduction

#for example:

#1:
template <typename T>
void func(T &) {}
int a;
const int b;
func(a);           // T ->  int
func(b);           // T ->  const int
func(5);           // wrong. 5 is a right value

#2:
template <typename T>
void func(const T &) {}
int a;
const int b;
func(a);     // T ->  int
func(b);     // T ->  int   
func(5);     // T ->  int

#3
template <typename T>
void func(T &&) {}
func(5);     // T ->  int

我的问题是:

为什么第一个代码不起作用,为什么这与左/右值有关;

为什么第三行的T不是const int

2 个答案:

答案 0 :(得分:1)

  

为什么第一个代码不起作用;为什么这与左/右值有关;

对于第一种情况,T将推导为int,则参数类型为int &,这是对非常量的左值引用。并且5是一个右值,它不能绑定到对非const的左值引用,然后调用失败。

对于第二种情况,函数的参数类型为const int &,即const的左值引用,可以像5那样绑定到右值。

  

为什么第三行的T不是const int

如果参数不是const类型,则

模板参数推导将不会 add const5的类型为int(这是一个右值),但其类型不是const int

另一方面,我们有forwarding reference用于处理左值/右值。例如

template <typename T>
void func(T &&) {}
int a;
const int b;
func(a);           // T ->  int&;       parameter type -> int&
func(b);           // T ->  const int&; parameter type -> const int&
func(5);           // Fine. T ->  int;  paramter type -> int&&

答案 1 :(得分:0)

所有这些都取决于表达式的属性。 5是一个表达式。它具有类型和值类别。 5的类型是int,而不是const int,而只是普通的int。这是一个prvalue(这是值类别)。

因此,根据T&推论5时,只能推导类型为int。这意味着合成函数接受int&,它不能绑定到右值。

在推论T const&时,根据模板参数推论中的适当规定,类型T仍只能推论为int。但是现在合成函数接受int const&,并且可以绑定到右值。