当参数类型是c ++ 11中的const lvalue reference vs non-const lvalue refernce时,函数模板类型推导如何工作

时间:2016-01-17 14:58:20

标签: c++ templates c++11

template<typename T>
void fun(T& param) // param is a reference
{
   T abc;
   abc=1;//cannot change abc value because T is deduced as const int
//It gives compilation error because T is deduced as const int       
}

template<typename T>
void fun1(const T& param) // param is a reference
{
   T abc;
   abc=1;//can change abc value because T is deduced as int
//why T is deduced int here
}


int main()
{
int x = 2; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
fun(x); // T is int, param's type is int&
fun(cx); // T is const int, param's type is const int&
fun(rx); // T is const int,param's type is const int&


fun1(x); // T is int, param's type is int&
fun1(cx); // T is int, param's type is const int&
fun1(rx); // T is int,param's type is const int&
return 0;
}

更新

  1. 为什么在fun1模板函数的情况下(当函数模板参数类型是常量参考时)不推导出 const int 偶数const int cxconst int& rx实例化但是const int(T)类型是为了娱乐而推导出来的(函数模板)?
  2. T类型推导是否取决于函数模板参数(参数)类型。

2 个答案:

答案 0 :(得分:3)

当你有像

这样的模板功能时
template<typename T>
void fun(T & param)

如果传递的参数实际上是constvolatile,那么在模板实例化中,T也将适当地“cv-qualified”。

当你将cv-qualifier放在模板函数声明中时,就像这样,

template<typename T>
void fun(const T & param)

然后T 绑定为const。但如果参数volatile

,则为volatile

它实际上非常直观 - T是最简单的类型,它将使函数调用工作,即使函数参数的预期类型与传递的相匹配。

同样,如果我的功能是

template <typename T>
void fun(T * param)

然后,如果我将int *传递给T,则int将被绑定为[temp.deduct.call](14.8.2.1)

这在C ++ 11标准Uint8Array中有详细描述,请参阅第三部分关于CV限定符的内容:

  

[temp.deduct.call](14.8.2.1)
  (1)模板参数推导是通过比较每个函数模板参数类型(称之为P)来完成的   调用的相应参数的类型(称之为A),如下所述。 ...   (2)如果P不是参考类型:
  (2.1) - 如果A是数组类型,则数组到指针标准转换(4.2)产生的指针类型是   代替A代替类型扣除;否则,
  (2.2) - 如果A是函数类型,则函数到指针标准转换产生的指针类型(4.3)   用于代替A进行类型扣除;否则,
  (2.3) - 如果A是cv限定类型,则类型扣除将忽略A类型的顶级cv限定符。
  (3)如果P是cv限定类型,则类型推导忽略P类型的顶级cv限定符。如果P是a   引用类型,P引用的类型用于类型推导。

答案 1 :(得分:2)

由于此处cxrx表现出相同的行为,我们仅使用cx

cxconst int

  • fun的情况:

T&const int匹配,因此T被推断为const int,因为const不属于T &param的类型为const int&

  • fun1的情况:

const T&const int匹配,因此T被推断为int,因为const已经在const T&中。 param的类型为const int&

让我们通过类型匹配在视觉上水平对齐,也许这更清楚:

fun    param type:  | T         |  &
       receives  :  | const int |

fun1   param type:  | const | T   |  &
       receives  :  | const | int |