【C/C++】C++11 Variadic Templates
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的更多相关文章
- C++11 : variadic templates(可变参数模板)
Introduction: Before the possibilities of the new C++ language standard, C++11, the use of templat ...
- 【正则表达式1】C++11正则表达式
https://www.cnblogs.com/pukaifei/p/5546968.html [正则表达式1]C++11正则表达式 头文件 #include <regex> rege ...
- 【读书笔记】2016.11.19 北航 《GDG 谷歌开发者大会》整理
2016.11.19 周六,我们在 北航参加了<GDG 谷歌开发者大会>,在web专场,聆听了谷歌公司的与会专家的技术分享. 中午免费的午餐,下午精美的下午茶,还有精湛的技术,都是我们队谷 ...
- 【编程篇】C++11系列之——临时对象分析
/*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...
- 【机器学习实战】第11章 使用 Apriori 算法进行关联分析
第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...
- 【STM32H7教程】第11章 STM32H7移植SEGGER的硬件异常分析
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第11章 STM32H7移植SEGGER的硬 ...
- 【C/C++】C++11 Lambda
Lambda C++11 中 lambda 是一个匿名函数对象 最简形式 []{ cout << "lambda" << endl; }(); // pri ...
- 【转帖】iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二
iPhone 11 Pro Max皇帝版物料成本不足3500元 卖一赚二 https://www.cnbeta.com/articles/tech/894449.htm 供应链的掌控力很重要 苹果今年 ...
- 【python基础】第11回 数据类型内置方法 02
本章内容概要 列表内置方法 字典内置方法 元组内置方法 集合内置方法 可变类型与不可变类型 本章内容详细 1.列表内置方法 list 列表在调用内置方法之后不会产生新的值 1.1 统计列表中的数据值的 ...
随机推荐
- 怎么批量删除qq空间说说
1.打开自己的QQ空间 - 说说——右击说说审查元素,打开审查元素.或者直接按f12也可以. 2.在这里我们看到很多分类 3.点击 Console,进入Console项 4.粘贴删除说说的代码,代码为 ...
- vue图片onerror加载路径写法
vue里,img加载错误的时候,onerror属性可以加载错误图片的默认图片写法如下: <img class=avator' :src="data.picture" :one ...
- python基础部分----文件、copy、内存指针
0.来源:https://www.cnblogs.com/jin-xin/articles/9439483.html 1.is VS id() VS == 2.小数据池.代码块缓存机制 3.赋值符号= ...
- [dart学习]第四篇:函数和操作符(本篇未完待续)
接着学习dart的函数和操作符. 1.函数Function dart是一种真正的面向对象的语言,通常一个函数也是Function类型的对象,这也就是说可以把函数赋值给一个变量,或者作为另一个函数的入参 ...
- Java基础总结1
数据类型: byte 1字节 short 2字节 int 4字节 long 8字节 float 4字节 double 8字节 char 2字节 ...
- jquery serializeArray()、serialize()增加数据
转自:http://blog.csdn.net/csdnzhangtao5/article/details/52981541 serialize().serializeArray()方法都是jquer ...
- anaconda中安装mmdetection
1.新建conda环境(有则跳过) conda create -n py36 python=3.6 && source activate py36 2.安装pytorch ...
- 关于matplotlib绘制直方图偏移的问题
在使用pyplot绘制直方图的时候我发现了一个问题,在给函数.hist()传参的时候,如果传入的组数不是刚刚好(就是说这个组数如果是使用(最大值-最小值)/组距计算出来,而这个数字不是整除得来而是取整 ...
- (转)The Evolved Transformer - Enhancing Transformer with Neural Architecture Search
The Evolved Transformer - Enhancing Transformer with Neural Architecture Search 2019-03-26 19:14:33 ...
- bootstrap table 前后端分页(超级简单)
前端分页:数据库查询所有的数据,在前端进行分页 后端分页:每次只查询当前页面加载所需要的那几条数据 下载bootstrap 下载bootstrap table jquery谁都有,不说了 项目结构:T ...