#include <iostream>
#include <functional>
template<typename T, typename R, typename ... Args>
std::function<R (Args...)> MakeDelegate(T *obj, R (T::*ptr)(Args ...))
{
return [obj, ptr](Args ... args)-> R {return (obj->*ptr)(args...);};
}
template<typename T, typename R, typename ... Args>
auto DelegateType(R (T::*ptr)(Args ...))->decltype(MakeDelegate<T>(nullptr, ptr));
class A
{
public:
void f1(int arg){std::cout << "A::f1(" << arg << ")" << std::endl;};
void f2(int arg1, int arg2){std::cout << "A::f2(" << arg1 << ", " << arg2 << ")" << std::endl;};
};
A a;
class B
{
public:
B() : m_d1(MakeDelegate(&a, &A::f1)), m_d2(MakeDelegate(&a, &A::f2))
{
}
void test()
{
m_d1(40);
m_d2(50, 60);
}
private:
decltype(DelegateType(&A::f1)) m_d1;
decltype(DelegateType(&A::f2)) m_d2;
};
auto Delegate1 = MakeDelegate(&a, &A::f1);
auto Delegate2 = MakeDelegate(&a, &A::f2);
int main()
{
Delegate1(10);
Delegate2(20, 30);
B b;
b.test();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBSLCB0eXBlbmFtZSAuLi4gQXJncz4Kc3RkOjpmdW5jdGlvbjxSIChBcmdzLi4uKT4gTWFrZURlbGVnYXRlKFQgKm9iaiwgUiAoVDo6KnB0cikoQXJncyAuLi4pKQp7CiAgIHJldHVybiBbb2JqLCBwdHJdKEFyZ3MgLi4uIGFyZ3MpLT4gUiB7cmV0dXJuIChvYmotPipwdHIpKGFyZ3MuLi4pO307Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFIsIHR5cGVuYW1lIC4uLiBBcmdzPgphdXRvIERlbGVnYXRlVHlwZShSIChUOjoqcHRyKShBcmdzIC4uLikpLT5kZWNsdHlwZShNYWtlRGVsZWdhdGU8VD4obnVsbHB0ciwgcHRyKSk7CgpjbGFzcyBBIAp7CnB1YmxpYzoKdm9pZCBmMShpbnQgYXJnKXtzdGQ6OmNvdXQgPDwgIkE6OmYxKCIgPDwgYXJnIDw8ICIpIiA8PCBzdGQ6OmVuZGw7fTsgCnZvaWQgZjIoaW50IGFyZzEsIGludCBhcmcyKXtzdGQ6OmNvdXQgPDwgIkE6OmYyKCIgPDwgYXJnMSA8PCAiLCAiIDw8IGFyZzIgPDwgIikiIDw8IHN0ZDo6ZW5kbDt9OyAKfTsKCkEgYTsKCmNsYXNzIEIKewpwdWJsaWM6CiAgIEIoKSA6IG1fZDEoTWFrZURlbGVnYXRlKCZhLCAmQTo6ZjEpKSwgbV9kMihNYWtlRGVsZWdhdGUoJmEsICZBOjpmMikpCiAgIHsKICAgCiAgIH0KCiAgIHZvaWQgdGVzdCgpCiAgIHsKICAgICAgbV9kMSg0MCk7CiAgICAgIG1fZDIoNTAsIDYwKTsKICAgfQpwcml2YXRlOgogICBkZWNsdHlwZShEZWxlZ2F0ZVR5cGUoJkE6OmYxKSkgbV9kMTsKICAgZGVjbHR5cGUoRGVsZWdhdGVUeXBlKCZBOjpmMikpIG1fZDI7Cn07CgphdXRvIERlbGVnYXRlMSA9IE1ha2VEZWxlZ2F0ZSgmYSwgJkE6OmYxKTsKYXV0byBEZWxlZ2F0ZTIgPSBNYWtlRGVsZWdhdGUoJmEsICZBOjpmMik7CgppbnQgbWFpbigpCnsKICAgRGVsZWdhdGUxKDEwKTsKICAgRGVsZWdhdGUyKDIwLCAzMCk7CiAgIAogICBCIGI7CiAgIGIudGVzdCgpOwogICAKICAgcmV0dXJuIDA7Cn0K