#include <iostream>
#include <utility>
using namespace std;

template<typename T, typename M, M Method>
class ProxyObject
{
public:

    template<typename... Args>
    void Invoke (T& Object, Args&&... A)
    {
        (void)(Object.*Method)(std::forward<Args>(A)...);
    }
};

class Object
{
public:

    int MyMethod (int Val)
    {
        cout << "Hello!" << endl;
        return Val;
    }
};

template<typename T, typename M, typename... Args>
void invoke (T& Object, M Method, Args&&... A)
{
    (void)(Object.*Method)(std::forward<Args>(A)...);
}

int main ()
{
    Object myObj;
    ProxyObject<Object, decltype(&Object::MyMethod), &Object::MyMethod> obj;

    obj.Invoke(myObj, 10);
    
    invoke(myObj, &Object::MyMethod, 10);

    return 0;
}