【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 统计列表中的数据值的 ...
随机推荐
- web接口文档apidoc的使用
1.安装 npm install apidoc -g 2.新建src文件夹,里面放2个文件,test.js和apidoc.json 3.test.js /** * @api {get} /query_ ...
- java串口通信丢包
java串口通信丢包问题 前段时间公司要求做一个java应用和pos串口通信的工具,调试好了好久每次都是只能接收到一包数据后续的数据都丢失了. 经过修改读写的流的缓存大小亲测都正常代码如下: seri ...
- 第十七节 Cookie基础与应用
什么是cookie:其实就是页面用来保存信息:比如,自动登录.记住用户名 cookie的特性:(以域名为单位的) 同一个网站(同一个域名)中所有页面共享一套cookie 数量.大小有限,跟浏览器有关, ...
- linux执行jmeter脚本解决响应数据为空
Linux服务器用命令执行了jmeter脚本,在本地查看结果时发现结果树种的“请求.响应数据”都显示为空,有错误日志中也看不出所以然,请看演示! 1 ,先执行脚本:执行成功(...end of run ...
- 【题解】Luogu P5313 僕たちはひとつの光([Ynoi2012]D2T2)
原题传送门 lovelive好评 比赛时只拿到了60pts,还是自己太菜了 这题的思想实际有点像Luogu P3674 小清新人渣的本愿与Luogu P5071 [Ynoi2015]此时此刻的光辉 这 ...
- 爬坑系列----Redis查询key报空指针异常,而redis中确实存在该key
现象: 1.在A方法中根据key查询一个list,可以获取到相应的值 2.在B方法中同样调用此方法,传入相同的key,查询不到值,为null,报空指针异常 起初我也一脸懵逼,到现在虽然解决了,还是不知 ...
- mongodb副本集基于centos7部署
安装mongodb,基于端口的安装三个节点 下载安装MongoDB安装包 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel ...
- android源码编译出现No private recovery resources for TARGET_DEVICE解决方法
mmm或mm出现以下提示的解决方法:Terminal log:No private recovery resources for TARGET_DEVICE xxxxxxmake: Entering ...
- 使用telnet进行Dubbo接口测试
telnet进入dubbo 查看pid $ jps -l 26048 org.apache.catalina.startup.Bootstrap 12388 org.jetbrains.jps.cmd ...
- Lintcode228-Middle of Linked List-Naive
228. Middle of Linked List Find the middle node of a linked list. Example Example 1: Input: 1->2- ...