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也见过好几个看了那篇文章后以同样方法实现反射的项目,也见过不少从我的文章抄过去 ...
随机推荐
- css学习日记
相对偏移 指定left top等属性就能够够完美控制一个元素的位置 如: position:relative; left:2px; 今天遇到一个很好玩的问题,当两个并排浮动框,当一个框的长度太大时就会 ...
- python下的类的部分特点
#coding=utf-8 class data: def __init__(self): #构造函数 self.name=' def pp(self): print self.name class ...
- SpringCloud初体验:六、利用 Sleuth 和 Zipkin 给微服务加上链路监控追踪查看功能
首先:装上 Zipkin 服务,收集调用链跟踪数据,体验时装在了本机docker上, 方便快捷 docker run -d -p : openzipkin/zipkin 安装后访问地址也是 9411端 ...
- 转换sql文件的create table语句为drop table语句
package com.csii.pweb.query.action; import java.io.BufferedReader; import java.io.FileNotFoundExcept ...
- .NET : Func委托和Action委托
其实他们两个都是委托[代理]的简写形式. 一.[action<>]指定那些只有输入参数,没有返回值的委托 Delegate的代码: public delegate void myDeleg ...
- MySqli 执行多条SQL语句
使用multi_query(); 去执行SQL语句,执行多条语句多个SQL语句用“;”分开 一:没有结果集的语句: $sql="insert into products (cid,name ...
- DEDECMS ShowMsg()样式修改 提示信息的修改以及美化
织梦DedeCMS系统,处处都在用到提示信息,但是这个提示框,前台后台一层不变,太死板了,可能有很多人都有过去修改它的想法,只是苦于不知道去哪里 改.今天我就来说说这个吧,DedeCMS的所有提示信息 ...
- php对象的实现
1.对象的数据结构非常简单 typedef struct _zend_object zend_object; struct _zend_object { zend_refcounted_h gc; / ...
- ICE简介及C++程序例子(转)
一.ICE简介: 1.ICE是什么? ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象 ...
- k8s1.4.3安装实践记录(1)-etcd、docker、flannel安装配置
虚拟机:VMware® Workstation 12 Pro 系统:CentOS Linux release 7.2.1511 (Core) 3.10.0-327.el7.x86_64 由于刚开始学习 ...