#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;
}
