变长参数模版函数初探
来源:互联网 发布:如何用java编写小游戏 编辑:程序博客网 时间:2024/05/17 06:12
最开始在写一个 命令模块, 涉及到 简单命令 和 复合命令。
所有的命令 是通过字符串组装的。
命令的调用是通过注册机制 实现绑定的。
具体的功能封装在对应的 功能类里面。
由于复合命令的存在,会导致一条命令 执行多个处理。
所以希望在 注册的时候,能够直接将多个对象直接保存到一个容器内。
这就会涉及到 不定长参数 保存的 过程。
在这里我才用了变长参数模版。
我先定义一个通用的 key-value 的 变长模版, 用于构造一个容器对象。
指定 当输入类型 为 key-value:string-string时,对应的处理方法。
当然也可以指定其他类型的参数和对应的处理函数。
template<typename... Params>MapSet Register(string key, string value, Params... params) { auto map_set = Register(params...); map_set.add(key, value); return map_set;}
设定模版扩展的终止条件
template<typename... Params>MapSet Register() { return MapSet("null");}
这样 就能把想要的参数保存在对应的容器中。
在使用变长模版函数的过程中,我在想 每个函数都构造一个对象, 会导致接收的时候都调用拷贝构造。
所以我在定义容器的时候,定义了拷贝构造,和右值引用构造,方便查看调用过程。
最开始,我没有实现 右值引用,只是实现拷贝构造
MapSet(const MapSet& map_set) { dictory_ = map_set.dictory_; index = AddRef(); cout << "construct from : const Copy, index :" << index << endl; } MapSet(MapSet& map_set) { dictory_ = map_set.dictory_; index = AddRef(); cout << "construct from : Copy, index :" << index << endl; }
结果如图:
后来加入 右值引用
MapSet(MapSet&& map_set) { dictory_.swap(map_set.dictory_); index = AddRef(); cout << "construct from : Swap, index :" << index << endl; }}
结果如图:
发现 没有触发右值引用
再次修改代码
template<typename... Params>MapSet Register(string key, string value, Params... params) { auto map_set = Register(params...); map_set.add(key, value); return std::move(map_set);}
结果如图:
现在已经触发了 右值引用, 其中8次构造 发生了 7次交换。
后来朋友告诉我 c++ 有返回值优化,于是 去掉std::move,把debug 编译 换成release 编译 再次尝试。
template<typename... Params>MapSet Register(string key, string value, Params... params) { auto map_set = Register(params...); map_set.add(key, value); return map_set;}
结果如图:
这里产生2次构造,其中发生一次交换。
这里不同的编译器优化效果可能不一样,下面使用 blade 编译的
完整代码:
#include <iostream>#include <string>#include <map>using namespace std;int AddRef() { static int ref = 0; return ref++;}class MapSet{public: MapSet(string info = "") { index = AddRef(); cout << "construct from : " << info << ", index :" << index << endl; } MapSet(const MapSet& map_set) { dictory_ = map_set.dictory_; index = AddRef(); cout << "construct from : const Copy, index :" << index << endl; } MapSet(MapSet& map_set) { dictory_ = map_set.dictory_; index = AddRef(); cout << "construct from : Copy, index :" << index << endl; } MapSet(MapSet&& map_set) { dictory_.swap(map_set.dictory_); index = AddRef(); cout << "construct from : Swap, index :" << index << endl; } void add(string key, string value) { dictory_.emplace(std::make_pair(key, value)); } void print() { cout << "output" << endl; for (auto it : dictory_) { cout << it.first << " : " << it.second << endl; } }private: map<string, string> dictory_; int index;};template<typename... Params>MapSet Register() { return MapSet("null");}template<typename... Params>MapSet Register(string key, string value, Params... params) { auto map_set = Register(params...); map_set.add(key, value); return map_set;}int main() { Register("a", "a", "b", "b", "c", "c", "d", "d", "e", "e", "f", "f").print(); getchar(); return 0;}
阅读全文
0 0
- 变长参数模版函数初探
- 变长参数函数
- 变长参数列表函数
- 变长参数函数
- 函数的变长参数
- 变长参数函数
- 变长参数的函数
- 变长参数的函数
- 变长函数参数
- 变长参数函数
- 变长参数函数说明
- 变长参数的函数定义
- 变长参数的函数写法
- 变长参数的函数写法
- C语言函数 变长参数
- 变长参数函数(转载)
- c语言变长参数函数
- 变长参数函数(转载)
- 用C++实现俄罗斯方块
- Phyton安装MySQL驱动
- 201712月如何买到阿里云免费SSL证书(0元SSL证书)
- MySQL 5.6 not in 和表关联性能测试对比
- java的enum作用
- 变长参数模版函数初探
- Android gralde 更换不同资源
- windows搭建laravel开发环境
- 博客搬家
- 【Linux使用及问题解决】用户登录时显示 -bash-4.2$ 问题
- R语言实现层次聚类分析
- 服务器模型——从单线程阻塞到多线程非阻塞(上)
- 事件分发前的拦截过程
- IntelliJ IDEA创建java项目