#include <functional>
#include <iostream>
template <class... CALLARGS>
class Closure{
public:
template <class OBJ, typename M, class... CAPARGS>
Closure(OBJ* obj, M (OBJ::*fct), CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
(obj->*fct)(capArgs..., callArgs...);
};
}
template <typename F, class... CAPARGS>
Closure(F fct, CAPARGS... capArgs){
callback =
[=] (CALLARGS... callArgs) -> void{
fct(capArgs..., callArgs...);
};
}
void operator () (CALLARGS... callArgs){
callback(callArgs...);
}
private:
std::function<void(CALLARGS...)> callback;
};
class A{
public:
void fct(int a){ std::cout << "A::fct " << a << std::endl; }
};
void plusF(int a){std::cout << "plusF " << a << std::endl;}
int main(void) {
A a;
Closure<int> callF(plusF);
Closure<int> callA(&a, &A::fct);
callF(1);
callA(2);
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnRlbXBsYXRlIDxjbGFzcy4uLiBDQUxMQVJHUz4KY2xhc3MgQ2xvc3VyZXsKcHVibGljOgoKICAgIHRlbXBsYXRlIDxjbGFzcyBPQkosIHR5cGVuYW1lIE0sIGNsYXNzLi4uIENBUEFSR1M+CiAgICBDbG9zdXJlKE9CSiogb2JqLCBNIChPQko6OipmY3QpLCBDQVBBUkdTLi4uIGNhcEFyZ3MpewogICAgICAgIGNhbGxiYWNrID0KICAgICAgICAgICAgWz1dIChDQUxMQVJHUy4uLiBjYWxsQXJncykgLT4gdm9pZHsKICAgICAgICAgICAgICAgIChvYmotPipmY3QpKGNhcEFyZ3MuLi4sIGNhbGxBcmdzLi4uKTsKICAgICAgICAgICAgfTsKICAgIH0KCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgY2xhc3MuLi4gQ0FQQVJHUz4KICAgIENsb3N1cmUoRiBmY3QsIENBUEFSR1MuLi4gY2FwQXJncyl7CiAgICAgICAgY2FsbGJhY2sgPQogICAgICAgICAgICBbPV0gKENBTExBUkdTLi4uIGNhbGxBcmdzKSAtPiB2b2lkewogICAgICAgICAgICAgICAgZmN0KGNhcEFyZ3MuLi4sIGNhbGxBcmdzLi4uKTsKICAgICAgICAgICAgfTsKICAgIH0KCiAgICB2b2lkIG9wZXJhdG9yICgpIChDQUxMQVJHUy4uLiBjYWxsQXJncyl7CiAgICAgICAgY2FsbGJhY2soY2FsbEFyZ3MuLi4pOwogICAgfQoKcHJpdmF0ZToKICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChDQUxMQVJHUy4uLik+IGNhbGxiYWNrOwp9OwoKY2xhc3MgQXsKcHVibGljOgogICAgdm9pZCBmY3QoaW50IGEpeyBzdGQ6OmNvdXQgPDwgIkE6OmZjdCAiIDw8IGEgPDwgc3RkOjplbmRsOyB9Cn07Cgp2b2lkIHBsdXNGKGludCBhKXtzdGQ6OmNvdXQgPDwgInBsdXNGICIgPDwgYSA8PCBzdGQ6OmVuZGw7fQoKaW50IG1haW4odm9pZCkgewogICAgQSBhOwoKICAgIENsb3N1cmU8aW50PiBjYWxsRihwbHVzRik7CiAgICBDbG9zdXJlPGludD4gY2FsbEEoJmEsICZBOjpmY3QpOwoKICAgIGNhbGxGKDEpOwogICAgY2FsbEEoMik7Cgp9