#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# 的委托机制的更多相关文章

  1. c++11 可变参数模板类

    c++11 可变参数模板类 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #inc ...

  2. 泛化之美 —— C++11 可变参数模板的妙用

    概述 首先这篇文章出自博客园作者:[qicosmos ],我对本文的实例代码进行了学习.思考和整理纠正,理清了文章的全部细节,觉得这是一篇让我受益匪浅的文章.之所以会接触「可变参数模板」这部分的内容, ...

  3. 第26课 可变参数模板(7)_any和variant类的实现

    1. any类的实现 (1)any类: ①是一个特殊的,只能容纳一个元素的容器,它可以擦除类型,可以将何任类型的值赋值给它. ②使用时,需要根据实际类型将any对象转换为实际的对象. (2)实现any ...

  4. C++反射机制:可变参数模板实现C++反射(使用C++11的新特性--可变模版参数,只根据类的名字(字符串)创建类的实例。在Nebula高性能网络框架中大量应用)

    1. 概要   本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在码云的仓库地 ...

  5. C++反射机制:可变参数模板实现C++反射

    1. 概要   本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在Github ...

  6. 第27课 可变参数模板(8)_TupleHelper

    1. TupleHelper的主要功能 (1)打印:由于tuple中的元素是可变参数模板,外部并不知道内部到底是什么数据,有时调试时需要知道其具体值,希望能打印出tuple中所有的元素值. (2)根据 ...

  7. 第24课 可变参数模板(5)_DllHelper和lambda链式调用

    1. dll帮助类 (1)dll的动态链接 ①传统的调用方式:先调用LoadLibrary来加载dll,再定义函数指针类型,接着调用GetProcAddress获取函数地址.然后通过函数指针调用函数, ...

  8. c++11 可变参数模板函数

    c++11 可变参数模板函数 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #in ...

  9. C++反射机制:可变参数模板实现C++反射(二)

    1. 概要   2018年Bwar发布了<C++反射机制:可变参数模板实现C++反射>,文章非常实用,Bwar也见过好几个看了那篇文章后以同样方法实现反射的项目,也见过不少从我的文章抄过去 ...

随机推荐

  1. centos6/7安装gitlab

    CentOS/RHEL 6/7安装gitlab新建 /etc/yum.repos.d/gitlab-ce.repo,内容为你的CentOS/RHEL版本:centos6 [gitlab-ce] nam ...

  2. linux下编译GD(freetype+libjpeg+libpng+gd-devel)

    linux下编译GD(freetype+libjpeg+libpng+gd-devel) 1.检查freetype是否安装rpm -qa | grep freetype没有的话编译freetype 这 ...

  3. Net分布式系统整体框架

    Net分布式系统之一:系统整体框架介绍 一.设计目的 从事.Net平台开发系统已有8年多了,一直思考搭建.Net分布式系统架构.基于window平台搭建的大型分布式系统不多,之前了解过myspace. ...

  4. 【python】实例-python实现两个字符串中最大的公共子串

    由于python中的for循环不像C++这么灵活,因此该用枚举法实现该算法: C="abcdefhe" D="cdefghe" m=0 n=len(C) E=[ ...

  5. jeecg中的原生态组件

    <!-- ztree --><link rel="stylesheet" type="text/css" href="plug-in ...

  6. 微信JS-SDK官方示例程序

    示例地址:http://203.195.235.76/jssdk/ /* * 注意: * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能 ...

  7. java IO字符流

    字节流:因为内存中数据都是字节,二进制数据. 字符流:方便处理文本数据.字符流是基于字节流的. ascii 编码表,并且各国都有自己的编码表. unicode码表,世界码表.优化后 utf-8码表. ...

  8. lwip编译选项

    修改默认选项时,不要修改opt.h文件,通过lwipopts.h修改. 和内存管理以及TCP发送性能相关的选项 // 为1时使用系统库malloc/free进行内存管理 #ifndef MEM_LIB ...

  9. 【Spring学习笔记-MVC-1.3】消息转换器HttpMessageConverter

    作者:ssslinppp       参考链接: SpringMVC源码剖析(五)-消息转换器HttpMessageConverter: http://my.oschina.net/lichhao/b ...

  10. bzoj2458 最小三角形

    Description Xaviera现在遇到了一个有趣的问题.平面上有N个点,Xaviera想找出周长最小的三角形.由于点非常多,分布也非常乱,所以Xaviera想请你来解决这个问题.为了减小问题的 ...