#include <iostream>
template<class T, T> struct proxy;
template <typename T, typename R, typename... Args, R(T::*mf)(Args...)>
struct proxy<R(T::*)(Args...), mf>
{
proxy(T& host) : m_Host(host) {}
template <typename... CArgs>
R call(CArgs&&... args)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return (m_Host.*mf)(std::forward<CArgs>(args)...);
}
private:
proxy& operator=(const proxy&);
T& m_Host;
};
class SomeHost
{
public:
int SomeGetter()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return 42;
}
void SomeSetter(int var)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
m_Var = var;
}
private:
int m_Var;
};
void test()
{
SomeHost obj;
proxy<void(SomeHost::*)(int), &SomeHost::SomeSetter> g(obj);
g.call(5);
proxy<int(SomeHost::*)(), &SomeHost::SomeGetter> f(obj);
f.call();
}
int main()
{
test();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8Y2xhc3MgVCwgVD4gc3RydWN0IHByb3h5OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEFyZ3MsIFIoVDo6Km1mKShBcmdzLi4uKT4Kc3RydWN0IHByb3h5PFIoVDo6KikoQXJncy4uLiksIG1mPgp7CiAgICBwcm94eShUJiBob3N0KSA6IG1fSG9zdChob3N0KSB7fQogICAgCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQ0FyZ3M+CiAgICBSIGNhbGwoQ0FyZ3MmJi4uLiBhcmdzKQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCBfX1BSRVRUWV9GVU5DVElPTl9fIDw8ICdcbic7CiAgICAgICAgcmV0dXJuIChtX0hvc3QuKm1mKShzdGQ6OmZvcndhcmQ8Q0FyZ3M+KGFyZ3MpLi4uKTsKICAgIH0KICAgIApwcml2YXRlOgogICAgcHJveHkmIG9wZXJhdG9yPShjb25zdCBwcm94eSYpOwogICAgVCYgbV9Ib3N0Owp9OwoKY2xhc3MgU29tZUhvc3QKewpwdWJsaWM6CiAgICBpbnQgU29tZUdldHRlcigpCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgJ1xuJzsKICAgICAgICByZXR1cm4gNDI7CiAgICB9CiAgICAKICAgIHZvaWQgU29tZVNldHRlcihpbnQgdmFyKQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCBfX1BSRVRUWV9GVU5DVElPTl9fIDw8ICdcbic7CiAgICAgICAgbV9WYXIgPSB2YXI7CiAgICB9CiAgICAKcHJpdmF0ZToKICAgIGludCBtX1ZhcjsKfTsKCnZvaWQgdGVzdCgpCnsKICAgIFNvbWVIb3N0IG9iajsKICAgIHByb3h5PHZvaWQoU29tZUhvc3Q6OiopKGludCksICZTb21lSG9zdDo6U29tZVNldHRlcj4gZyhvYmopOwogICAgZy5jYWxsKDUpOwoKICAgIHByb3h5PGludChTb21lSG9zdDo6KikoKSwgJlNvbWVIb3N0OjpTb21lR2V0dGVyPiBmKG9iaik7CiAgICBmLmNhbGwoKTsKfQoKaW50IG1haW4oKQp7CiAgICB0ZXN0KCk7CiAgICByZXR1cm4gMDsKfQo=