#include <iostream>
#include <utility> //std::forward
#include <memory> //std::shared_ptr
using namespace std;
template<class C, class T, class... Args>
struct Proxy
{
shared_ptr<C> _objC;
typedef T (C::*funcptr_t)(Args...);
funcptr_t _fp;
Proxy(shared_ptr<C> objC, funcptr_t fp): _objC(objC), _fp(fp) {}
T operator()(Args&&... args)
{
return ((*_objC).*_fp)(std::forward<Args>(args)...);
}
};
template<class C, class T, class... Args>
Proxy<C,T,Args...> operator ->* (shared_ptr<C> c, T (C::*fp)(Args...))
{
return Proxy<C,T,Args...>(c, fp);
}
struct Clazz
{
int v;
Clazz(int x) : v(x) {}
int foo(int w) {return v + w;}
int bar(int x, int y) {return v * x + y;}
void qux(int* p) {*p = v * v;}
};
int main(void)
{
shared_ptr<Clazz> pObj (new Clazz(42));
auto fp1 = &Clazz::foo;
auto fp2 = &Clazz::bar;
auto fp3 = &Clazz::qux;
int *w;
cout << (pObj->*fp1)(58) << endl;
cout << (pObj->*fp2)(132, 22) << endl;
(pObj->*fp3)(w);
cout << w << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4JLy9zdGQ6OmZvcndhcmQKI2luY2x1ZGUgPG1lbW9yeT4JLy9zdGQ6OnNoYXJlZF9wdHIKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPGNsYXNzIEMsIGNsYXNzIFQsIGNsYXNzLi4uIEFyZ3M+CnN0cnVjdCBQcm94eQp7CglzaGFyZWRfcHRyPEM+IF9vYmpDOwoJdHlwZWRlZiBUIChDOjoqZnVuY3B0cl90KShBcmdzLi4uKTsKCWZ1bmNwdHJfdCBfZnA7CgkKCVByb3h5KHNoYXJlZF9wdHI8Qz4gb2JqQywgZnVuY3B0cl90IGZwKTogX29iakMob2JqQyksIF9mcChmcCkge30KCQoJVCBvcGVyYXRvcigpKEFyZ3MmJi4uLiBhcmdzKQoJewoJCXJldHVybiAoKCpfb2JqQykuKl9mcCkoc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKCX0KfTsKCnRlbXBsYXRlPGNsYXNzIEMsIGNsYXNzIFQsIGNsYXNzLi4uIEFyZ3M+ClByb3h5PEMsVCxBcmdzLi4uPiBvcGVyYXRvciAtPiogKHNoYXJlZF9wdHI8Qz4gYywgVCAoQzo6KmZwKShBcmdzLi4uKSkKewoJcmV0dXJuIFByb3h5PEMsVCxBcmdzLi4uPihjLCBmcCk7Cn0KCnN0cnVjdCBDbGF6egp7CglpbnQgdjsKCQoJQ2xhenooaW50IHgpIDogdih4KSB7fQoJCglpbnQgZm9vKGludCB3KSB7cmV0dXJuIHYgKyB3O30KCWludCBiYXIoaW50IHgsIGludCB5KSB7cmV0dXJuIHYgKiB4ICsgeTt9Cgl2b2lkIHF1eChpbnQqIHApIHsqcCA9IHYgKiB2O30KfTsKCmludCBtYWluKHZvaWQpCnsKCXNoYXJlZF9wdHI8Q2xheno+IHBPYmogKG5ldyBDbGF6eig0MikpOwoJCglhdXRvIGZwMSA9ICZDbGF6ejo6Zm9vOwoJYXV0byBmcDIgPSAmQ2xheno6OmJhcjsKCWF1dG8gZnAzID0gJkNsYXp6OjpxdXg7CgkKCWludCAqdzsKCQoJY291dCA8PCAocE9iai0+KmZwMSkoNTgpIDw8IGVuZGw7Cgljb3V0IDw8IChwT2JqLT4qZnAyKSgxMzIsIDIyKSA8PCBlbmRsOwoJKHBPYmotPipmcDMpKHcpOwoJY291dCA8PCB3IDw8IGVuZGw7CgkKCXJldHVybiAwOwp9Cg==
prog.cpp: In function 'int main()':
prog.cpp:50:16: error: cannot bind 'int*' lvalue to 'int*&&'
(pObj->*fp3)(w);
^
prog.cpp:15:4: note: initializing argument 1 of 'T Proxy<C, T, Args>::operator()(Args&& ...) [with C = Clazz; T = void; Args = {int*}]'
T operator()(Args&&... args)
^