template <typename Type, typename ReturnType, typename MemFuncType>
struct mem_fun_ptr_t
{
MemFuncType func;
public:
mem_fun_ptr_t(MemFuncType f) :
func(f) {}
ReturnType operator () (Type *p) const { return (p->*func)(); }
};
// non-const version
template <typename T, typename R>
mem_fun_ptr_t<T, R, R (T::*)()> mem_fun_ptr(R (T::*Func)())
{
return mem_fun_ptr_t<T, R, R (T::*)()>(Func);
}
// const version
template <typename T, typename R>
mem_fun_ptr_t<const T, R, R (T::*)() const> mem_fun_ptr(R (T::*Func)() const)
{
return mem_fun_ptr_t<const T, R, R (T::*)() const>(Func);
}
#include <iostream>
#include <string>
int main()
{
std::string str = "Hello";
auto x = mem_fun_ptr(&std::string::length);
std::cout << x(&str) << std::endl;
const std::string const_str = str + ", world!";
std::cout << x(&const_str) << std::endl;
return 0;
}
dGVtcGxhdGUgPHR5cGVuYW1lIFR5cGUsIHR5cGVuYW1lIFJldHVyblR5cGUsIHR5cGVuYW1lIE1lbUZ1bmNUeXBlPgpzdHJ1Y3QgbWVtX2Z1bl9wdHJfdAp7CiAgICBNZW1GdW5jVHlwZSBmdW5jOwpwdWJsaWM6CiAgICBtZW1fZnVuX3B0cl90KE1lbUZ1bmNUeXBlIGYpIDoKICAgICAgZnVuYyhmKSB7fQogICAgUmV0dXJuVHlwZSBvcGVyYXRvciAoKSAoVHlwZSAqcCkgY29uc3QgeyByZXR1cm4gKHAtPipmdW5jKSgpOyB9Cn07CgovLyBub24tY29uc3QgdmVyc2lvbgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUj4KbWVtX2Z1bl9wdHJfdDxULCBSLCBSIChUOjoqKSgpPiBtZW1fZnVuX3B0cihSIChUOjoqRnVuYykoKSkKewogICAgcmV0dXJuIG1lbV9mdW5fcHRyX3Q8VCwgUiwgUiAoVDo6KikoKT4oRnVuYyk7Cn0KCi8vIGNvbnN0IHZlcnNpb24KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFI+Cm1lbV9mdW5fcHRyX3Q8Y29uc3QgVCwgUiwgUiAoVDo6KikoKSBjb25zdD4gbWVtX2Z1bl9wdHIoUiAoVDo6KkZ1bmMpKCkgY29uc3QpCnsKICAgIHJldHVybiBtZW1fZnVuX3B0cl90PGNvbnN0IFQsIFIsIFIgKFQ6OiopKCkgY29uc3Q+KEZ1bmMpOwp9CgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6c3RyaW5nIHN0ciA9ICJIZWxsbyI7CiAgICBhdXRvIHggPSBtZW1fZnVuX3B0cigmc3RkOjpzdHJpbmc6Omxlbmd0aCk7CiAgICBzdGQ6OmNvdXQgPDwgeCgmc3RyKSA8PCBzdGQ6OmVuZGw7CiAgICBjb25zdCBzdGQ6OnN0cmluZyBjb25zdF9zdHIgPSBzdHIgKyAiLCB3b3JsZCEiOwogICAgc3RkOjpjb3V0IDw8IHgoJmNvbnN0X3N0cikgPDwgc3RkOjplbmRsOwogICAgcmV0dXJuIDA7Cn0K