C++11新特性·笔记四·函数模板支持默认模板参数

总结:c++98支持struct模板中,定义默认模板参数类型,但不支持模板函数的模板参数的默认类型,使用时,必须后缀< 类型 >告诉编译器模板参数的类型,C++11支持默认的类型,当所有参数都有默认类型时,如typename T = int,即可作为普通参数直接使用!

  1. template <typename T = int> // error in C++98/03: default template arguments
  2. void func()
  3. {
  4. // ...
  5. }

现在这一限制在 C++11 中被解除了。上面的 func 函数在 C++11 中可以直接使用,代码如下:

  1. int main(void)
  2. {
  3. func(); //T = int
  4. return 0;
  5. }

        

此时模板参数 T 的类型就为默认值 int。从上面的例子中可以看出,当所有模板参数都有默认参数时,函数模板的调用如同一个普通函数。但对于类模板而言,哪怕所有参数都有默认参数,在使用时也必须在模板名后。

  1. template <typename R = int, typename U>
  2. R func(U val)
  3. {
  4. return val;
  5. }
  6. int main()
  7. {
  8. func(97); // R=int, U=int
  9. func<char>(97); // R=char, U=int
  10. func<double, int>(97); // R=double, U=int
  11. return 0;
  12. }

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 的类型值,因此无需编译器自行推导。

再次强调,当默认模板参数和自行推导的模板参数同时使用时,若无法推导出函数模板参数的类型,编译器会选择使用默认模板参数;如果模板参数即无法推导出来,又未设置其默认值,则编译器直接报错。例如:

  1. template <typename T, typename U = double>
  2. void func(T val1 = 0, U val2 = 0)
  3. {
  4. //...
  5. }
  6. int main()
  7. {
  8. func('c'); //T=char, U=double
  9. func(); //编译报错
  10. return 0;
  11. }

其中,func('c') 的这种调用方式,编译器通过实参 'c' 可以推导出 T=char,但由于未传递第 2 个实参,因此模板参数 U 使用的是默认参数 double;但 func() 的调用方式是不行的,虽然 val1 设置有默认值,但编译器无法通过该默认值推导出模板参数 T 的类型。由此不难看出,编译器的自动推导能力并没有想象的那么强大。

总的来说,C++11 支持为函数模板中的参数设置默认值,在实际使用过程中,我们可以选择使用默认值,也可以尝试由编译器自行推导得到,还可以亲自指定各个模板参数的类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值