#include <functional>
template<class T>
class Ptr {
public:
Ptr(T* ptr) : p(ptr) {}
~Ptr() { if(p) delete p; }
template<class Ret, class... Args>
auto operator ->* (Ret (T::*method)(Args...)) -> std::function<Ret(Args...)>
{
return [this, method](Args&&... args) -> Ret { return (this->p->*method)(std::forward<Args>(args)...); };
}
private:
T *p;
};
class Foo {
public:
void foo(int) {}
int bar() { return 3; }
};
int main() {
Ptr<Foo> p(new Foo());
void (Foo::*method)(int) = &Foo::foo;
int (Foo::*method2)() = &Foo::bar;
(p->*method)(5);
(p->*method2)();
return 0;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+Cgp0ZW1wbGF0ZTxjbGFzcyBUPgpjbGFzcyBQdHIgewpwdWJsaWM6CiAgUHRyKFQqIHB0cikgOiBwKHB0cikge30KICB+UHRyKCkgeyBpZihwKSBkZWxldGUgcDsgfQoKICB0ZW1wbGF0ZTxjbGFzcyBSZXQsIGNsYXNzLi4uIEFyZ3M+CiAgYXV0byBvcGVyYXRvciAtPiogKFJldCAoVDo6Km1ldGhvZCkoQXJncy4uLikpIC0+IHN0ZDo6ZnVuY3Rpb248UmV0KEFyZ3MuLi4pPgogIHsKICAgIHJldHVybiBbdGhpcywgbWV0aG9kXShBcmdzJiYuLi4gYXJncykgLT4gUmV0IHsgcmV0dXJuICh0aGlzLT5wLT4qbWV0aG9kKShzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOyB9OwogIH0KCnByaXZhdGU6CiAgVCAqcDsKfTsKCmNsYXNzIEZvbyB7CnB1YmxpYzoKICB2b2lkIGZvbyhpbnQpIHt9CiAgaW50IGJhcigpIHsgcmV0dXJuIDM7IH0KfTsKCmludCBtYWluKCkgewogIFB0cjxGb28+IHAobmV3IEZvbygpKTsKCiAgdm9pZCAoRm9vOjoqbWV0aG9kKShpbnQpID0gJkZvbzo6Zm9vOwogIGludCAoRm9vOjoqbWV0aG9kMikoKSA9ICZGb286OmJhcjsKCiAgKHAtPiptZXRob2QpKDUpOwogIChwLT4qbWV0aG9kMikoKTsKCiAgcmV0dXJuIDA7Cn0K