template <typename T, typename U = int, U N = 0> struct Foo { // ... };但是却不支持函数的默认模板参数:
template <typename T = int> // error in C++98/03: default template arguments void func() { // ... }现在这一限制在 C++11 中被解除了。上面的 func 函数在 C++11 中可以直接使用,代码如下:
int main(void) { func(); //T = int return 0; }此时模板参数 T 的类型就为默认值 int。从上面的例子中可以看出,当所有模板参数都有默认参数时,函数模板的调用如同一个普通函数。但对于类模板而言,哪怕所有参数都有默认参数,在使用时也必须在模板名后跟随
<>
来实例化。template <typename R = int, typename U> R func(U val) { return val; } int main() { func(97); // R=int, U=int func<char>(97); // R=char, U=int func<double, int>(97); // R=double, U=int return 0; }C++11 标准中,我们可以像 func(97) 这样调用模板函数,因为编译器可以根据实参 97 自行推导出模板参数 U 的类型为 int,并且根据返回值 val=97 推导出 R 的类型也为 int;而 func<char>(97) 手动指定了模板参数 R 的类型为 char(默认模板参数将无效),并通过实参 97 推导出了 U = int;最后 func<double,int>(97) 手动指定的 R 和 U 的类型值,因此无需编译器自行推导。
template <typename T, typename U = double> void func(T val1 = 0, U val2 = 0) { //... } int main() { func('c'); //T=char, U=double func(); //编译报错 return 0; }其中,func('c') 的这种调用方式,编译器通过实参 'c' 可以推导出 T=char,但由于未传递第 2 个实参,因此模板参数 U 使用的是默认参数 double;但 func() 的调用方式是不行的,虽然 val1 设置有默认值,但编译器无法通过该默认值推导出模板参数 T 的类型。由此不难看出,编译器的自动推导能力并没有想象的那么强大。
本文链接:http://task.lmcjl.com/news/18562.html