本文主要是介绍模版实参推断和引用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
模版参数推断包含函数指针及引用等部分,此处只介绍有关引用的模版参数推断。
考虑下面的例子:
template<typename T> void f(T &p);
其中函数参数p是一个模版类型参数T的引用,记住以下两点:
i、编译器会应用正常的引用绑定规则;
ii、const是底层的,不是顶层的。
1、从左值引用函数参数推断类型
当一个函数参数是模版类型参数的一个普通(左值)引用时(即,形如T&),绑定规则:只能传递给它一个左值(如,一个变量或一个返回引用类型的表达式)。实参可以是const类型,也可以不是。如果实参是const的,则T将被推断为const类型。
举例如下:
template<typename T> void f1(T&);//实参必须是一个左值
//对f1的调用使用实参所引用的类型作为模版参数类型
f1(i);//i是一个int;模版参数类型T是一个int
f1(ci);//ci是一个const int;模版参数T是const int
f1(5);//错误:传递给一个&参数的实参必须是一个左值
当一个函数参数的类型是const T&,正常的绑定规则:可以传递给它任何类型的实参——一个对象(const或非const)、一个临时对象或是一个字面常量值。
举例如下:
template<typename T> void f2(const T&);//实参可以是一个左值,也可以是一个右值
//对f1的调用使用实参所引用的类型作为模版参数类型
f2(i);//i是一个int;模版参数类型T是一个int
f2(ci);//ci是一个const int;模版参数T是int
f2(5);//一个const &参数可以绑定到一个右值;T是int
2、从右值引用函数参数推断类型
当一个函数参数是一个右值引用(即,形如T&&)时,正常绑定规则:可以传递给它一个右值。当传递右值时,类型推断过程类似普通左值引用函数参数的推断过程。
举例如下:
template<typename T> void f3(T&&);
f3(42);//实参是一个int类型的右值;模版参数T是int
3、规则例外:引用折叠和右值引用参数
个人总结:除遵循上述两条规则外,主要是&的折叠及右值引用的推断,其根据结果为导向推断T的实际类型,遵守的规则如下:
记X为给定类型,
i、X& &、X& &&和X&& &都折叠成类型X&
ii、X&& &&折叠成X&&(给右值引用传递右值时,最后的的类型为X&&)(仅此折叠生成右值引用)
第3点例外规则导致如下几个重要结果:
a、如果一个函数参数是一个指向模板类型参数的右值引用(如,T&&),则它可以被绑定到一个左值;且(见b)
b、(接a)如果实参是一个左值,则推断出的模版实参类型将是一个左值引用,且函数参数将被实例化为一个(普通)左值引用参数(T&)
c、可以将任意类型的实参传递给T&&类型的函数参数。
举例如下:
template<typename T> void f3(T&&);
f3(i);//实参是一个左值;模版参数T是int&
f3(ci);//实参是一个左值;模版参数T是一个const int&
f3(42);//实参是一个右值;模版参数T是一个int
这篇关于模版实参推断和引用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!