繁体   English   中英

当参数类型为C ++ 11中的常量左值引用与非常量左值引用时,函数模板类型推导的工作方式

[英]How function template type deduction works when parameter type is const lvalue reference vs non-const lvalue refernce in 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左值引用),不为T推导 const int cx ,即使在实例化时传递了const int cxconst int& rx ,但为fun推导了const int(T)类型(函数模板)?
  2. T类型的推导是否取决于功能模板的param(参数)类型。

当您具有模板功能时

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

如果传递的参数实际上是constvolatile ,则在模板实例化中, T也将被适当地“ cv限定”。

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

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

那么T 绑定为const 但是如果参数volatile ,它将是volatile volatile

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

同样,如果我的功能是

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

那么如果我传递一个int *T将被绑定为int

C ++ 11标准[temp.deduct.call](14.8.2.1)进行了详细描述,有关CV限定词的信息,请参见第三部分:

[临时扣除通知](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是引用类型,则将P引用的类型用于类型推导。

由于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 |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM