#include <iostream>
#include <string>
template <typename Type, typename ReturnType>
struct mem_fun_ptr_t
{
typedef ReturnType (Type::*Func)();
Func func;
public:
mem_fun_ptr_t(Func f):
func(f) {}
ReturnType operator () (Type *p) { return (p->*func)(); }
ReturnType operator () (Type *p) const { return (p->*func)(); }
};
template <typename T, typename R>
mem_fun_ptr_t<T, R> mem_fun_ptr(R (T::*Func)())
{
return mem_fun_ptr_t<T, R>(Func);
}
template <typename T, typename R>
mem_fun_ptr_t<const T, R> mem_fun_ptr(R (T::*Func)() const)
{
return mem_fun_ptr_t<const T, R>(Func);
}
int main()
{
std::string str = "Hello";
auto str_len = mem_fun_ptr(&std::string::length);
std::cout << str_len(&str);
auto str_clear = mem_fun_ptr(&std::string::clear);
str_clear(&str);
std::cout << std::endl << str.empty();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGUsIHR5cGVuYW1lIFJldHVyblR5cGU+CnN0cnVjdCBtZW1fZnVuX3B0cl90CnsKICAgIHR5cGVkZWYgUmV0dXJuVHlwZSAoVHlwZTo6KkZ1bmMpKCk7CiAgICBGdW5jIGZ1bmM7CnB1YmxpYzoKICAgIG1lbV9mdW5fcHRyX3QoRnVuYyBmKToKICAgICAgICBmdW5jKGYpIHt9CiAgICBSZXR1cm5UeXBlIG9wZXJhdG9yICgpIChUeXBlICpwKSB7IHJldHVybiAocC0+KmZ1bmMpKCk7IH0KICAgIFJldHVyblR5cGUgb3BlcmF0b3IgKCkgKFR5cGUgKnApIGNvbnN0IHsgcmV0dXJuIChwLT4qZnVuYykoKTsgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFI+Cm1lbV9mdW5fcHRyX3Q8VCwgUj4gbWVtX2Z1bl9wdHIoUiAoVDo6KkZ1bmMpKCkpCnsKICAgIHJldHVybiBtZW1fZnVuX3B0cl90PFQsIFI+KEZ1bmMpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUj4KbWVtX2Z1bl9wdHJfdDxjb25zdCBULCBSPiBtZW1fZnVuX3B0cihSIChUOjoqRnVuYykoKSBjb25zdCkKewogICAgcmV0dXJuIG1lbV9mdW5fcHRyX3Q8Y29uc3QgVCwgUj4oRnVuYyk7Cn0KCmludCBtYWluKCkKewogICAgc3RkOjpzdHJpbmcgc3RyID0gIkhlbGxvIjsKICAgIGF1dG8gc3RyX2xlbiA9IG1lbV9mdW5fcHRyKCZzdGQ6OnN0cmluZzo6bGVuZ3RoKTsKICAgIHN0ZDo6Y291dCA8PCBzdHJfbGVuKCZzdHIpOwogICAgYXV0byBzdHJfY2xlYXIgPSBtZW1fZnVuX3B0cigmc3RkOjpzdHJpbmc6OmNsZWFyKTsKICAgIHN0cl9jbGVhcigmc3RyKTsKICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGwgPDwgc3RyLmVtcHR5KCk7CiAgICByZXR1cm4gMDsKfQ==