• C++ 0x 使用可变参数模板类 实现 C# 的委托机制


     1 #ifndef _ZTC_DELEGATE_H_
     2 #define _ZTC_DELEGATE_H_
     3 
     4 #include <vector>
     5 #include <functional>
     6 
     7 ///////////////////////////////////////////////
     8 // C++ 使用 可变参数模板类, 来实现
     9 // C#中的 委托
    10 // Anchor: ztc
    11 // Date  : 2014-01-10
    12 ///////////////////////////////////////////////
    13 
    14 template<typename R, typename ...Args>
    15 class Delegate {
    16 public:
    17     template<typename U>
    18     Delegate& operator += (const U &func) {
    19         funcList.push_back(std::function<R(Args...)>(func));
    20         funcPointers.push_back((void*)&func);
    21         return *this;
    22     }
    23 
    24     template<typename U>
    25     Delegate& operator -= (const U &func) {
    26         int i = -1;
    27         for (auto iter = funcPointers.begin(); iter != funcPointers.end(); iter++) {
    28             i++;
    29             if (*iter == (void*)&func) {
    30                 funcPointers.erase(iter);
    31                 funcList.erase(funcList.begin() + i);
    32                 break;
    33             }
    34         }
    35         return *this;
    36     }
    37 
    38     std::vector<R> operator()(Args...args) {
    39         std::vector<R> ret;
    40         for (auto f : funcList) {
    41             ret.push_back(f(args...));
    42         }
    43         return ret;
    44     }
    45 private:
    46     std::vector<std::function<R(Args...)>> funcList;
    47     std::vector<void*> funcPointers;
    48 };
    49 
    50 template<typename ...Args>
    51 class Delegate<void, Args...>  {
    52 public:
    53     template<typename U>
    54     Delegate& operator += (const U &func) {
    55         std::cout << "注册方法 " << typeid(func).name() << std::endl;
    56         funcList.push_back(std::function<void(Args...)>(func));
    57         funcPointers.push_back((void*)&func);
    58         return *this;
    59     }
    60 
    61     template<typename U>
    62     Delegate& operator -= (const U &func) {
    63         std::cout << "卸载方法 " << typeid(func).name() << std::endl;
    64         int i = -1;
    65         for (auto iter = funcPointers.begin(); iter != funcPointers.end(); iter++) {
    66             i++;
    67             if (*iter == (void*)&func) {
    68                 funcPointers.erase(iter);
    69                 funcList.erase(funcList.begin() + i);
    70                 break;
    71             }
    72         }
    73         return *this;
    74     }
    75 
    76     void operator() (Args... args) {
    77         for (auto f : funcList) {
    78             f(args...);
    79         }
    80     }
    81 private:
    82     std::vector<std::function<void(Args...)>> funcList;
    83     std::vector<void*> funcPointers;
    84 };
    85 
    86 #endif // _ZTC_DELEGATE_H_
    ztc_Delegate.hpp
     1 #include <iostream>
     2 #include "ztc_Delegate.hpp"
     3 
      // 普通函数
    4 int foo(int a, int b) { 5 return a * a + b * b; 6 } 7   // 普通无参无返回函数
    8 void kaoo() { 9 std::cout << "kaooooooo" << std::endl; 10 } 11 void kaoo2() { 12 std::cout << "kaooooo22222oo" << std::endl; 13 } 14   // 类成员函数
    15 class Test { 16 public: 17 void funcInClass() { 18 std::cout << "Function In Class" << std::endl; 19 } 20 }; 21 22 int main() { 23 // 定义事件 有返回值 24 Delegate<int, int, int> OnSomething; 25 // 定义事件 无返回值 26 Delegate<void> OnKao; 27 28 // 注册方法 29 OnSomething += [](int a, int b) {return a + b; }; 30 OnSomething += [](int a, int b) {return a * b; }; 31 OnSomething += foo; 32 33 // 类的成员函数 需要 使用 Bind 34 Test c; 35 auto cf = std::bind(&Test::funcInClass, c); 36 37 // 注册类成员函数 38 OnKao += cf; 39 // 注册普通函数 40 OnKao += kaoo; 41 OnKao += kaoo2; 42 // 调用事件 43 OnKao(); 44 // 卸载类成员函数 45 OnKao -= cf; 46 // 制裁普通函数 47 OnKao -= kaoo; 48 // 调用方法 49 OnKao(); 50 51 // 调用事件 得到 结果 52 auto ret = OnSomething(2, 6); 53 54 // 显示结果 55 for (auto r : ret) { 56 std::cout << r << std::endl; 57 } 58 59 return 0; 60 }
  • 相关阅读:
    Linux命令发送Http的get或post请求(curl和wget两种方法)
    大数据面试题以及答案整理(一)
    大数据面试题及答案-汇总版
    Linux shell之打印输出
    Java开发中常见的危险信号(上)
    sencha touch笔记(5)——DataView组件(1)
    sencha touch(7)——list组件
    sencha touch笔记(6)——路由控制(1)
    [置顶] Android源码分析-点击事件派发机制
    UVa 10330 Power Transmission / 最大流
  • 原文地址:https://www.cnblogs.com/easyfrog/p/3513487.html
Copyright © 2020-2023  润新知