#include <type_traits>
using namespace std;
int foo(int i) {
return i;
}
struct A
{
int foo(int i) { return i; }
auto bar(int x) -> std::result_of<decltype(&A::foo)(A, int)>::type
{ // see: http://n...content-available-to-author-only...o.edu/2014/ref/cppreference/en/cpp/types/result_of.html
return x;
}
template<typename Func, typename... Args>
auto call(Func func, Args&&... args) const
-> typename std::result_of< decltype(func)(A*, Args...)>::type
{ this->*func(args...);
}
};
int main() {
static_assert(std::is_same<decltype(foo(123)), int>::value, "");
A a;
static_assert(std::is_same<decltype(a.foo(123)), decltype(a.bar(123))>::value, "");
static_assert(std::is_same<decltype(a.foo(123)), decltype(a.bar(123))>::value, "");
auto func = &A::foo;
static_assert(std::is_same<decltype(a.foo(123)), decltype(a.call(func, 123))>::value, "");
static_assert(std::is_same<decltype(a.foo(123)),
std::result_of<decltype(&A::foo)(A, int)>::type
>::value, "");
return 0;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmludCBmb28oaW50IGkpIHsKCXJldHVybiBpOwp9CgoKc3RydWN0IEEKewogICAgaW50IGZvbyhpbnQgaSkgeyByZXR1cm4gaTsgfSAKICAgIAogICAgYXV0byBiYXIoaW50IHgpIC0+IHN0ZDo6cmVzdWx0X29mPGRlY2x0eXBlKCZBOjpmb28pKEEsIGludCk+Ojp0eXBlCiAgICB7ICAvLyBzZWU6IGh0dHA6Ly9uLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5vLmVkdS8yMDE0L3JlZi9jcHByZWZlcmVuY2UvZW4vY3BwL3R5cGVzL3Jlc3VsdF9vZi5odG1sCiAgICAJcmV0dXJuIHg7CiAgICB9CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEZ1bmMsIHR5cGVuYW1lLi4uIEFyZ3M+CiAgICBhdXRvIGNhbGwoRnVuYyBmdW5jLCBBcmdzJiYuLi4gYXJncykgY29uc3QKICAgICAtPiAgdHlwZW5hbWUgc3RkOjpyZXN1bHRfb2Y8IGRlY2x0eXBlKGZ1bmMpKEEqLCBBcmdzLi4uKT46OnR5cGUKIHsgICB0aGlzLT4qZnVuYyhhcmdzLi4uKTsKCiB9Cn07CgoKIAogCmludCBtYWluKCkgewogIAlzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTxkZWNsdHlwZShmb28oMTIzKSksIGludD46OnZhbHVlLCAiIik7CgoKCUEgYTsKCXN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPGRlY2x0eXBlKGEuZm9vKDEyMykpLCBkZWNsdHlwZShhLmJhcigxMjMpKT46OnZhbHVlLCAiIik7CglzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTxkZWNsdHlwZShhLmZvbygxMjMpKSwgZGVjbHR5cGUoYS5iYXIoMTIzKSk+Ojp2YWx1ZSwgIiIpOwoJCgogICAgYXV0byBmdW5jID0gJkE6OmZvbzsKCXN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPGRlY2x0eXBlKGEuZm9vKDEyMykpLCBkZWNsdHlwZShhLmNhbGwoZnVuYywgMTIzKSk+Ojp2YWx1ZSwgIiIpOwoJc3RhdGljX2Fzc2VydChzdGQ6OmlzX3NhbWU8ZGVjbHR5cGUoYS5mb28oMTIzKSksIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpyZXN1bHRfb2Y8ZGVjbHR5cGUoJkE6OmZvbykoQSwgaW50KT46OnR5cGUKCSAgICAgICAgICAgICAgICAgICAgICAgICAgID46OnZhbHVlLCAiIik7CgkKCiAgICAKCXJldHVybiAwOwp9