カッとなってやった。
Delegate.h
template <class T, typename... Args>
class Delegate {
private:
typedef void (T::*Func)(Args... args);
std::list<std::tuple<T*, Func> > _funcs;
public:
void add(T* pObj, Func func) {
assert(!isExists(pObj, func));
_funcs.push_back(std::make_tuple(pObj, func));
}
void remove(T* pObj, Func func) {
for (auto it = _funcs.begin(); it != _funcs.end(); ++it) {
if (pObj == std::get<0>(*it) && func == std::get<1>(*it)) {
_funcs.erase(it);
break;
}
}
}
void clear() {
_funcs.clear();
}
bool isExists(T* pObj, Func func) {
for (auto it = _funcs.begin(); it != _funcs.end(); ++it) {
if (pObj == std::get<0>(*it) && func == std::get<1>(*it)) {
return true;
}
}
return false;
}
void call(Args... args) {
for (auto it = _funcs.begin(); it != _funcs.end(); ++it) {
auto pObj = std::get<0>(*it);
auto func = std::get<1>(*it);
(pObj->*func)(args...);
}
}
};
こんな感じに使う。
class Test {
public:
void foo(int v1, float v2) {}
void bar(int v1, float v2) {}
};
Test t;
Delegate<Test, int, float> d;
d.add(&t, &Test::foo);
d.add(&t, &Test::bar);
d.call(1, 2.0f);
同じインスタンスの同じメンバ関数は同時に登録できない。
リストの中身はタプルにしたけどもっと良い方法は無いかな?
もちろんお仕事では使えない。(コンパイラが云々かんぬん)