Last active
April 29, 2019 09:27
-
-
Save xueliu/b129fe3d59e6f66e6460732a0eb39d6e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef DELEGATE_HPP_INCLUDED | |
#define DELEGATE_HPP_INCLUDED | |
#include <functional> | |
#include <vector> | |
// general case | |
template<typename R, typename... Args> | |
class delegate | |
{ | |
public: | |
using DelegateFunc = std::function<R(Args...)>; | |
template<typename U> | |
delegate& operator += (const U &func) | |
{ | |
funcs.emplace_back(std::function<R(Args...)>(func)); | |
return *this; | |
} | |
std::vector<R> operator () (Args... params) | |
{ | |
std::vector<R> ret; | |
for (auto f : funcs) | |
{ | |
ret.push_back(f(params...)); | |
} | |
return ret; | |
} | |
// template<typename U> | |
// delegate& operator -= (const U &func) | |
// { | |
// funcs.remove(std::function<R(Args...)>(func)); | |
// return *this; | |
// } | |
// template<typename U> | |
// void register(const U &func) { | |
// funcs.push_back(std::function<R(Args...)>(func)); | |
// } | |
private: | |
std::vector<std::function<R(Args...)>> funcs; | |
}; | |
// specialization when return type is void | |
template<typename... Args> | |
class delegate<void, Args...> | |
{ | |
public: | |
template<typename U> | |
delegate& operator += (const U &func) | |
{ | |
funcs.push_back(std::function<void(Args...)>(func)); | |
return *this; | |
} | |
void operator () (Args... params) | |
{ | |
for (auto f : funcs) | |
{ | |
f(params...); | |
} | |
} | |
private: | |
std::vector<std::function<void(Args...)>> funcs; | |
}; | |
#endif // DELEGATE_HPP_INCLUDED |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "delegate.hpp" | |
using namespace std; | |
void func1(int x, int y) { | |
cout << "from func1 " << x + y << endl; | |
} | |
void func2(int x, int y) { | |
cout << "from func2 " << x * y << endl; | |
} | |
class A { | |
public: | |
void func1(int x, int y) { | |
cout << "from class A::func1 " << x + y << endl; | |
} | |
void func2(int x, int y) { | |
cout << "from class A::func2 " << x * y << endl; | |
} | |
}; | |
int main() | |
{ | |
// delegate with Lambda functions without return value | |
delegate<void, int, int> d1; | |
d1 += [](int x, int y){cout << x + y << endl;}; | |
d1 += [](int x, int y){cout << x * y << endl;}; | |
d1(3, 5); | |
delegate<int, int, int> d2; | |
d2 += [](int x, int y){return x + y;}; | |
d2 += [](int x, int y){return x * y;}; | |
for (auto ret : d2(3, 5)) | |
{ | |
cout << ret << endl; | |
} | |
// delegate with normal functions without return value | |
delegate<void, int, int> d3; | |
d3 += func1; | |
d3 += func2; | |
d3(3, 5); | |
// delegate with class member functions without return value | |
A a = A(); | |
using delegateFunc = std::function<void(int, int)>; | |
delegateFunc delegateFunc1 = std::bind(&A::func1, a, std::placeholders::_1, std::placeholders::_2); | |
delegateFunc delegateFunc2 = std::bind(&A::func2, a, std::placeholders::_1, std::placeholders::_2); | |
delegate<void, int, int> d4; | |
d4 += delegateFunc1; | |
d4 += delegateFunc2; | |
d4(3, 5); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment