先来看一道C++二级真题+未来教育解析:
关于在调用模板函数时模板实参的使用,下列表述中正确的是()。
A)对于虚拟类型参数所对应的模板实参,如果能从模板函数的实参中获得相同的信息,则都可以省略
B)对于虚拟类型参数所对应的模板实参,如果它们是参数表中的最后的若干个参数,则都可以省略
C)对于虚拟类型参数所对应的模板实参,若能够省略则必须省略
D)对于常规参数所对应的模板实参,任何情况下都不能省略
【未来教育解析】
在调用一个模板函数时,编译系统需要足够的信息来判别每个虚拟类型参数所对应的实际类型,可以从两个不同的渠道获得这样的信息:从模板实参表(用“<>”括起来的参数表)或从模板函数实参表(用“()”括起来的参数表)(这句话表述不准确,应该表述为:从模板函数的形参表(用“()”括起来的参数表)中的形参所对应的实参) 。如果从后者获得的信息已经能够判定其中部分或全部虚拟类型参教所对应的实际参数,而且它们又正好是参数表中最后的若干参数,则模板实参表中的那几个参数可以省略。如果模板实参表中的实参都被省略了,则空表“<>”也可以不要,因此选项D错误。反之,对于某个模板实参,如果从模板函数的实参表中无法获得同样的信息,就不能省略;或者虽然能够获得同样的信息,但在它后面还有其他不能省略的实参,则其自身还是不能省略。本题答案为A选项。
【个人解析】
代码举例:
#include <iostream>
using namespace std;
template<typename T1, typename T2> //<>里的是虚拟类型参数
T1 f(T2 n){ return n*5.6; }
int main(){
int a = 3;
cout << f<double>(a) << endl; //1,<>括起来的是模板实参表,()括起来的是模板函数形参表,这里模板实参表省略了int
cout << f<double, int>(a) << endl; //2
cout << f<int>(a) << endl; //3,这里模板实参表省略了int
cout << f<>(a) << endl; //4,报错
double b = 2.3;
cout << f<double>(b) << endl; //5,这里模板实参表省略了double
cout << f<int>(b) << endl; //6,这里模板实参表省略了double
cout << f<>(b) << endl; //7,报错
return 0;
}
a、b分别是模板函数的实参,从实参中获得的信息已经能够判定模板函数的模板实参表中部分或全部虚拟类型参教所对应的实际参数,而且它们又正好是模板实参表中最后的若干参数,则模板实参表中的那几个参数可以省略。