Variadic Templates

1、function template:利用“参数个数逐一递减”的特性,实现递归函数调用

template <typename T, typename... Types>
void func(const T& firstArg, const Types&... args) {
处理 firstArg
func(args...);
}

例一、实现类似 python 3 的 print()

 void print() { cout << endl; }    // 边界条件,当args为0个时调用

 template <typename T, typename... Types>
void print(const T& firstArg, const Types&... args) {  
cout << firstArg << ' ';
print(args...);
} int main() {
print(7.5, "hello", bitset<>(), ); // print "7.5 hello 0000000101111001 42"
return ;
}

如果同时存在函数

template <typename... Types>
void print(const Types&... args) {
...
}

void print(const T& firstArg, const Types&... args) 与 void print(const Types&... args) 可以共存,可以编译通过。

但前者比较特化,后者比较泛化,共存时永远不会调用后者。

例二、模拟 C <cstdio> 的 printf(),引自 stackoverflow

 void Printf(const char* s) {
while (*s) {
if (*s == '%' && *(++s) != '%')
throw runtime_error("invalid format string: missing arguments.");
cout << *s++;
}
} template <typename T, typename... Types>
void Printf(const char* s, const T& firstArg, const Types&... args) {
while (*s) {
if (*s == '%' && *(++s) != '%') {
cout << firstArg;
Printf(++s, args...);
return;
}
cout << *s++;
}
} int main() {
int* pi = new int;
Printf("[%p] %s = %f\n", pi, "This is pi", 3.1415926); // print "[0x21fcc20] This is pi = 3.14159"
return ;
}

2、class template:利用“参数个数逐一递减”导致“参数类型也逐一递减”的特性,实现递归继承或递归复合

例一、对 first 和 last(头尾元素)的特别处理(模板偏特化+递归)

 // 使用tuple index和max index打印元素
template <int IDX, int MAX, typename... Args>
struct print_tuple {
static void print(ostream& os, const tuple<Args...>& args) {
os << get<IDX>(args) << (IDX + == MAX ? "" : ", ");
print_tuple<IDX + , MAX, Args...>::print(os, args);
}
}; // 递归结束的偏特化
template <int MAX, typename... Args>
struct print_tuple<MAX, MAX, Args...> {
static void print(ostream&, const tuple<Args...>&) {}
}; // output operator for tuple
template <typename... Args>
ostream& operator<<(ostream& os, const tuple<Args...>& args) {
os << '[';
// 需要知道tuple的元素index,用sizeof...(Args)获得元素个数
print_tuple<, sizeof...(Args), Args...>::print(os, args);
return os << ']';
} int main() {
cout << make_tuple(7.5, string("hello"), bitset<>(), ); // print "[7.5, hello, 0000000101111001, 42]"
return ;
}

例二、C++STL 中 tuple 的实现(类的递归继承)

template <typename... Values> class tuple;
template <> class tuple<> { }; template <typename Head, typename... Tail>
class tuple<Head, Tail...> : private tuple <Tail...> {
typedef tuple<Tail...> inherited;
public:
tuple() { }
tuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) { } // 调用base ctor
...
protected:
Head m_head;
};

例三、模拟 tuple(类的递归复合)

template <typename... Values> class tup;
template <> class tup<> { }; template <typename Head, typename... Tail>
class tup<Head, Tail...> {
typedef tup<Tail...> composited;
public:
tup() { }
tup(Head v, Tail... vtail) : m_head(v), m_tail(vtail...) { } // 递归复合
...
protected:
Head m_head;
composited m_tail;
};

只是这种实现 tuple 的方式内存消耗较大

【C/C++】C++11 Variadic Templates的更多相关文章

  1. C++11 : variadic templates(可变参数模板)

      Introduction: Before the possibilities of the new C++ language standard, C++11, the use of templat ...

  2. 【正则表达式1】C++11正则表达式

    https://www.cnblogs.com/pukaifei/p/5546968.html [正则表达式1]C++11正则表达式   头文件 #include <regex> rege ...

  3. 【读书笔记】2016.11.19 北航 《GDG 谷歌开发者大会》整理

    2016.11.19 周六,我们在 北航参加了<GDG 谷歌开发者大会>,在web专场,聆听了谷歌公司的与会专家的技术分享. 中午免费的午餐,下午精美的下午茶,还有精湛的技术,都是我们队谷 ...

  4. 【编程篇】C++11系列之——临时对象分析

    /*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...

  5. 【机器学习实战】第11章 使用 Apriori 算法进行关联分析

    第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...

  6. 【STM32H7教程】第11章 STM32H7移植SEGGER的硬件异常分析

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第11章       STM32H7移植SEGGER的硬 ...

  7. 【C/C++】C++11 Lambda

    Lambda C++11 中 lambda 是一个匿名函数对象 最简形式 []{ cout << "lambda" << endl; }(); // pri ...

  8. 【转帖】iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二

    iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二 https://www.cnbeta.com/articles/tech/894449.htm 供应链的掌控力很重要 苹果今年 ...

  9. 【python基础】第11回 数据类型内置方法 02

    本章内容概要 列表内置方法 字典内置方法 元组内置方法 集合内置方法 可变类型与不可变类型 本章内容详细 1.列表内置方法 list 列表在调用内置方法之后不会产生新的值 1.1 统计列表中的数据值的 ...

随机推荐

  1. 博客系统(cnblog)

    1.用户表:Userinfo 2.博客站点表:Blog 3.标签表:Tag 4.分类表:Category 5.文章表:Article 6.点赞踩表:ArticelUpDown 7.评论表:Commen ...

  2. JQuery小知识

    一.禁用鼠标右键 $(document).ready(function() { $(document).bind("contextmenu", function(e) { retu ...

  3. html中div标签怎么用?

    div现在一般网页的布局都是使用的div+css来布局,div的话,就是通过. <div> <div><p></p></div> </ ...

  4. console.log在IE浏览器中会有异常

    因为在IE浏览器无此方法,故此重写 方法一: var console = console || { log: function () { return false; } }; 方法二:window.c ...

  5. Ubuntu 无界面使用selenium chrome + headless

    1. 安装 selenium : sudo pip install selenium 2. 安装 chromdriver: 进入 淘宝镜像源 下载 chromdriver, 可以查看 notes.tx ...

  6. 为基于OpenCV的图像处理程序编写界面—关于QT\MFC\CSharp的选择以及GOCW的介绍

            基于OpenCV编写图像处理项目,除了算法以外,比较重要一个问题就是界面设计问题.对于c++语系的程序员来说,一般来说有QT/MFC两种考虑.QT的确功能强大,特别是QML编写andr ...

  7. Xml & Tomcat

    文档声明: 简单声明, version : 解析这个xml的时候,使用什么版本的解析器解析 <?xml version="1.0" ?> encoding : 解析xm ...

  8. testng timeout ant

    问题:使用ant 指令运行testng.xml文件,@Test注释timeout未生效 解决:添加以下几个jar包

  9. 20175312 2018-2019-2 《Java程序设计》第6周学习总结

    20175312 2018-2019-2 <Java程序设计>第6周学习总结 教材学习内容总结 已依照蓝墨云班课的要求完成了第七.十章的学习,主要的学习渠道是PPT,和书的课后习题. 总结 ...

  10. mysql学习(一)

    mysql学习,这篇博文是关于目前市面上火热的关系型数据库mysql的学习记录. 1,关于mysql的安装,自行百度. 2,sql:structure query language 结构化查询语言. ...