1.模板实参推断的概念
对于函数模板和类模板,编译器利用调用中的实参函数来确定其模板参数。 从函数实参来确定模板实参的过程,称为模板实参推断。
模板实参的推断和常规的函数实参推断的规则不一样,尤其是在类型转换这一方面,两者大不相同。
2. 模板实参推断过程中的类型转换
同非模板函数,在一次调用中传递给函数模板的实参来初始化函数的形参。如果函数形参类型是泛型,采用特殊的初始化规则。
1.const转换 : 可以将非const对象的引用或者指针传递给const的引用或指针形参。
2.数组、函数指针转换:如果函数形参不是引用类型(前提!),则可以对数组或者函数类型的实参应用正常的指针转换。(详细解释看例子)
- 3.其他类型的转换 : 算术转换(
double -> int
等)、派生类向基类的转换、用户自定义的转换,都不可以用于模板实参推断
考虑以下两个例子:
template<typename T>
void funObj(T x, T y)
{
cout << typeid(x).name() << endl;
cout << typeid(y).name() << endl;
}
int a[10], b[42];
string s1("a value");
const string s2("another value");
funObj(s1, s2);
funObj(a, b);
这两次调用都是合法的。
- 在
funObj(s1,s2)
的调用中,传递了一个string和const string**(s2的值不可改变,是顶层const,编译器会忽略掉),因为T不是引用类型,所以实参被拷贝**,因此原对象是否为const都不影响。
不过考虑下面这组调用:
int i = 0, j = 0;
const int *cp = &i;
int * p = &i;
funObj(cp, p);
对函数funObj(cp,p)
的调用是失败的。
等等,这和我们刚才说的好像有点矛盾,实参被拷贝,因此原对象是否为const不是不影响么?
注意,我们说的原对象是否为const不影响指的是原对象是否为顶层const&#x