#include <iostream>
#include <vector>
#include <functional>
template<typename ReturnType, typename... Args>
class Signal {
std::vector<std::function<ReturnType(Args...)>> function;
public:
template<typename... Args2>
ReturnType operator()(Args2&&... args2) {
ReturnType ret;
for (auto& func : function)
ret = func(std::forward<Args2>(args2)...);
return ret;
}
template<typename Func>
void func(Func const &func) {
function.push_back(std::function<ReturnType(Args...)>(func));
}
template<typename Class, typename Instance>
void mfunc(ReturnType(Class::*func)(Args...), Instance &instance) {
function.push_back([&instance, func](Args&&... args) {
return (instance.*func)(std::forward<Args>(args)...);
});
}
};
struct foo {
int bar(int i, double d) { std::cout << i << ' ' << d; return 0; }
};
int main()
{
Signal<int, int, double> sig;
foo f;
sig.mfunc(&foo::bar, f);
sig(5, 3.);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnRlbXBsYXRlPHR5cGVuYW1lIFJldHVyblR5cGUsIHR5cGVuYW1lLi4uIEFyZ3M+CmNsYXNzIFNpZ25hbCB7CiAgICBzdGQ6OnZlY3RvcjxzdGQ6OmZ1bmN0aW9uPFJldHVyblR5cGUoQXJncy4uLik+PiBmdW5jdGlvbjsKcHVibGljOgogICAgdGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJnczI+CiAgICBSZXR1cm5UeXBlIG9wZXJhdG9yKCkoQXJnczImJi4uLiBhcmdzMikgewogICAgICAgIFJldHVyblR5cGUgcmV0OwogICAgICAgIGZvciAoYXV0byYgZnVuYyA6IGZ1bmN0aW9uKQogICAgICAgICAgICByZXQgPSBmdW5jKHN0ZDo6Zm9yd2FyZDxBcmdzMj4oYXJnczIpLi4uKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEZ1bmM+CiAgICB2b2lkIGZ1bmMoRnVuYyBjb25zdCAmZnVuYykgewogICAgICAgIGZ1bmN0aW9uLnB1c2hfYmFjayhzdGQ6OmZ1bmN0aW9uPFJldHVyblR5cGUoQXJncy4uLik+KGZ1bmMpKTsKICAgIH0KCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBDbGFzcywgdHlwZW5hbWUgSW5zdGFuY2U+CiAgICB2b2lkIG1mdW5jKFJldHVyblR5cGUoQ2xhc3M6OipmdW5jKShBcmdzLi4uKSwgSW5zdGFuY2UgJmluc3RhbmNlKSB7CiAgICAgICAgZnVuY3Rpb24ucHVzaF9iYWNrKFsmaW5zdGFuY2UsIGZ1bmNdKEFyZ3MmJi4uLiBhcmdzKSB7IAogICAgICAgIAlyZXR1cm4gKGluc3RhbmNlLipmdW5jKShzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOyAKICAgICAgICB9KTsKICAgIH0KICAgIAp9OwoKc3RydWN0IGZvbyB7CglpbnQgYmFyKGludCBpLCBkb3VibGUgZCkgeyBzdGQ6OmNvdXQgPDwgaSA8PCAnICcgPDwgZDsgcmV0dXJuIDA7IH0KfTsKCmludCBtYWluKCkKewogICAgU2lnbmFsPGludCwgaW50LCBkb3VibGU+IHNpZzsKICAgIGZvbyBmOwogICAgc2lnLm1mdW5jKCZmb286OmJhciwgZik7CiAgICBzaWcoNSwgMy4pOwp9