C++ 0x 使用可变参数模板类 实现 C# 的委托机制
#ifndef _ZTC_DELEGATE_H_
#define _ZTC_DELEGATE_H_ #include <vector>
#include <functional> ///////////////////////////////////////////////
// C++ 使用 可变参数模板类, 来实现
// C#中的 委托
// Anchor: ztc
// Date : 2014-01-10
/////////////////////////////////////////////// template<typename R, typename ...Args>
class Delegate {
public:
template<typename U>
Delegate& operator += (const U &func) {
funcList.push_back(std::function<R(Args...)>(func));
funcPointers.push_back((void*)&func);
return *this;
} template<typename U>
Delegate& operator -= (const U &func) {
int i = -;
for (auto iter = funcPointers.begin(); iter != funcPointers.end(); iter++) {
i++;
if (*iter == (void*)&func) {
funcPointers.erase(iter);
funcList.erase(funcList.begin() + i);
break;
}
}
return *this;
} std::vector<R> operator()(Args...args) {
std::vector<R> ret;
for (auto f : funcList) {
ret.push_back(f(args...));
}
return ret;
}
private:
std::vector<std::function<R(Args...)>> funcList;
std::vector<void*> funcPointers;
}; template<typename ...Args>
class Delegate<void, Args...> {
public:
template<typename U>
Delegate& operator += (const U &func) {
std::cout << "注册方法 " << typeid(func).name() << std::endl;
funcList.push_back(std::function<void(Args...)>(func));
funcPointers.push_back((void*)&func);
return *this;
} template<typename U>
Delegate& operator -= (const U &func) {
std::cout << "卸载方法 " << typeid(func).name() << std::endl;
int i = -;
for (auto iter = funcPointers.begin(); iter != funcPointers.end(); iter++) {
i++;
if (*iter == (void*)&func) {
funcPointers.erase(iter);
funcList.erase(funcList.begin() + i);
break;
}
}
return *this;
} void operator() (Args... args) {
for (auto f : funcList) {
f(args...);
}
}
private:
std::vector<std::function<void(Args...)>> funcList;
std::vector<void*> funcPointers;
}; #endif // _ZTC_DELEGATE_H_
ztc_Delegate.hpp
#include <iostream>
#include "ztc_Delegate.hpp" // 普通函数
int foo(int a, int b) {
return a * a + b * b;
} // 普通无参无返回函数
void kaoo() {
std::cout << "kaooooooo" << std::endl;
}
void kaoo2() {
std::cout << "kaooooo22222oo" << std::endl;
} // 类成员函数
class Test {
public:
void funcInClass() {
std::cout << "Function In Class" << std::endl;
}
}; int main() {
// 定义事件 有返回值
Delegate<int, int, int> OnSomething;
// 定义事件 无返回值
Delegate<void> OnKao; // 注册方法
OnSomething += [](int a, int b) {return a + b; };
OnSomething += [](int a, int b) {return a * b; };
OnSomething += foo; // 类的成员函数 需要 使用 Bind
Test c;
auto cf = std::bind(&Test::funcInClass, c); // 注册类成员函数
OnKao += cf;
// 注册普通函数
OnKao += kaoo;
OnKao += kaoo2;
// 调用事件
OnKao();
// 卸载类成员函数
OnKao -= cf;
// 制裁普通函数
OnKao -= kaoo;
// 调用方法
OnKao(); // 调用事件 得到 结果
auto ret = OnSomething(, ); // 显示结果
for (auto r : ret) {
std::cout << r << std::endl;
} return ;
}
C++ 0x 使用可变参数模板类 实现 C# 的委托机制的更多相关文章
- c++11 可变参数模板类
c++11 可变参数模板类 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #inc ...
- 泛化之美 —— C++11 可变参数模板的妙用
概述 首先这篇文章出自博客园作者:[qicosmos ],我对本文的实例代码进行了学习.思考和整理纠正,理清了文章的全部细节,觉得这是一篇让我受益匪浅的文章.之所以会接触「可变参数模板」这部分的内容, ...
- 第26课 可变参数模板(7)_any和variant类的实现
1. any类的实现 (1)any类: ①是一个特殊的,只能容纳一个元素的容器,它可以擦除类型,可以将何任类型的值赋值给它. ②使用时,需要根据实际类型将any对象转换为实际的对象. (2)实现any ...
- C++反射机制:可变参数模板实现C++反射(使用C++11的新特性--可变模版参数,只根据类的名字(字符串)创建类的实例。在Nebula高性能网络框架中大量应用)
1. 概要 本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在码云的仓库地 ...
- C++反射机制:可变参数模板实现C++反射
1. 概要 本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在Github ...
- 第27课 可变参数模板(8)_TupleHelper
1. TupleHelper的主要功能 (1)打印:由于tuple中的元素是可变参数模板,外部并不知道内部到底是什么数据,有时调试时需要知道其具体值,希望能打印出tuple中所有的元素值. (2)根据 ...
- 第24课 可变参数模板(5)_DllHelper和lambda链式调用
1. dll帮助类 (1)dll的动态链接 ①传统的调用方式:先调用LoadLibrary来加载dll,再定义函数指针类型,接着调用GetProcAddress获取函数地址.然后通过函数指针调用函数, ...
- c++11 可变参数模板函数
c++11 可变参数模板函数 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #in ...
- C++反射机制:可变参数模板实现C++反射(二)
1. 概要 2018年Bwar发布了<C++反射机制:可变参数模板实现C++反射>,文章非常实用,Bwar也见过好几个看了那篇文章后以同样方法实现反射的项目,也见过不少从我的文章抄过去 ...
随机推荐
- hadoop大数据处理平台与案例
大数据可以说是从搜索引擎诞生之处就有了,我们熟悉的搜索引擎,如百度搜索引擎.360搜索引擎等可以说是大数据技处理技术的最早的也是比较基础的一种应用.大概在2015年大数据都还不是非常火爆,2015年可 ...
- Robomongo,Mongo可视化工具
哇唔,其实她是三(阴险脸). 你看你看,界面清新,让人家心旷神怡(害羞),谁还想win+R+mongo呀呀呀?! 哎呀呀,继续···说正事. 在这里···借助SQL进一步理解下MongoDB SQL术 ...
- 转Python 和C#的交互
http://www.cnblogs.com/wilber2013/category/708919.html IronPython和C#交互 IronPython是一个.NET平台上的Python ...
- PHP常用函数总结(二):
//=================图像处理=================================== //=================会话机制================== ...
- 为什么要使用MONO
今天中午我收到一个Email,是关于以前写的一个MONO文章的疑问,我对此做了一些解释,希望与有相同问题的朋友一起分享一下,邮件内容如下: 我在网上找到了您写的一篇关于Mono的“在windows下使 ...
- DataTable 分批处理,每批处理4行
ZZ -- /// <summary> /// 分批处理. /// </summary> public void PartialProc() { ;//每个datatable行 ...
- vue+node+mongoDB前后端分离个人博客(入门向)
最近学习了VUE,自己为了学习做了个小小的博客,功能很简单,不过开发过程中也遇到了很多坑,所以记录下来方便以后使用.欢迎大家交流学习. 功能 实现了用户注册.登录.token检测登录.用户留言.个人中 ...
- 杂项-frame:Rails框架
ylbtech-杂项-frame:Rails框架 Rails框架首次提出是在2004年7月,它的研发者是26岁的丹麦人David Heinemeier Hansson.不同于已有复杂的Web 开发框架 ...
- httpclient 用户名密码认证实例
import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.com ...
- MongoDB整库备份+整库导入
备份前检查: [root@Load29 tmp]# mongo localhost: MongoDB shell version: connecting to: localhost:/test Ser ...