走进C++11(十四)变长参数模板

 

解释

 

C++03只有固定模板参数。C++11 加入新的表示法,允许任意个数、任意类别的模板参数,不必在定义时将参数的个数固定。

 

变长模板、变长参数是依靠C++11新引入的参数包的机制实现的。

 

参数包

 

  • 一个模板形参包(template parameter pack)是一个接受零个或多个模板实参的模板形参。

 

template<class ... Types> struct Tuple { };Tuple<> t0;    // Types不含任何实参Tuple<int> t1;    // Types含有一个实参:intTuple<int, float> t2;    // Types含有两个实参:int和floatTuple<0> error;    // 错误:0不是一个类型

 

  • 一个函数形参包(function parameter pack)是一个接受零个或多个函数实参的函数形参

     

template<class ... Types> void f(Types... args);f();    // OK:args不含有任何实参f(1);    // OK:args含有一个实参:intf(2, 1.0);    // OK:args含有两个实参int和double

 

  • 一个形参包要么是一个模板形参包,要么是一个函数形参包。

  • 一个包扩展(expansion)由一个模式(pattern)和一个省略号组成。包扩展的实例中一个列表中产生零个或多个模式的实例。模式的形式依赖于扩展所发生的上下文中

template <typename... TS>   // typename... TS为模板形参包,TS为模式static void MyPrint(const char* s, TS... args)  // TS... args为函数形参包,args为模式{    printf(s, args...);}

 

解包

 

一个常用的技巧是:利用模板推导机制,每次从参数包里面取第一个元素,缩短参数包,直到包为空。

 

template <typename T>void fun(const T& t){  cout << t << '\n';}template <typename T, typename ... Args>void fun(const T& t, Args ... args){  cout << t << ',';  fun(args...);//递归解决,利用模板推导机制,每次取出第一个,缩短参数包的大小。}

 

 

在C++17标准中,可以使用fold expression,更直接地表达,并且确保正序展开:

 

// C++17template<typename T0, typename... T>void printf(T0 t0, T... t) {  std::cout << t0 << std::endl;  if constexpr (sizeof...(t) > 0) printf(t...);}// C++11#include <iostream>template <typename T0>void printf(T0 value){  std::cout << value << std::endl;}template <typename T, typename... Args>void printf(T value, Args... args){  std::cout << value << std::endl;  printf(args...);}int main(){  printf(1, 2, "123", 1.1);  return 0;}

 

关注公众号获取更多信息:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值