#include <iostream>
int function (int arg) { return arg; }
typedef int (*function_t) (int arg);
template <typename T_ret, typename... T_args>
class caller {
T_ret (*m_p) (T_args... args);
public:
T_ret call (T_args... args) {
return m_p(args...);
}
caller (T_ret (*p)(T_args...args)) : m_p(p) {}
};
template <typename T_ret, typename... T_args>
caller<T_ret, T_args...> get_caller(T_ret(*prototype)(T_args...))
{
return caller<T_ret, T_args...>(prototype);
}
int main()
{
function_t f = &function;
auto c = get_caller(f);
std::cout << c.call(1) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKaW50IGZ1bmN0aW9uIChpbnQgYXJnKSB7IHJldHVybiBhcmc7IH0KdHlwZWRlZiBpbnQgKCpmdW5jdGlvbl90KSAoaW50IGFyZyk7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVF9yZXQsIHR5cGVuYW1lLi4uIFRfYXJncz4gCmNsYXNzIGNhbGxlciB7CiAgICBUX3JldCAoKm1fcCkgKFRfYXJncy4uLiBhcmdzKTsKcHVibGljOgogICAgVF9yZXQgY2FsbCAoVF9hcmdzLi4uIGFyZ3MpIHsKICAgICAgICByZXR1cm4gbV9wKGFyZ3MuLi4pOwogICAgfQogICAgY2FsbGVyIChUX3JldCAoKnApKFRfYXJncy4uLmFyZ3MpKSA6IG1fcChwKSB7fQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFRfcmV0LCB0eXBlbmFtZS4uLiBUX2FyZ3M+CmNhbGxlcjxUX3JldCwgVF9hcmdzLi4uPiBnZXRfY2FsbGVyKFRfcmV0KCpwcm90b3R5cGUpKFRfYXJncy4uLikpCnsKCXJldHVybiBjYWxsZXI8VF9yZXQsIFRfYXJncy4uLj4ocHJvdG90eXBlKTsKfQoKaW50IG1haW4oKQp7CglmdW5jdGlvbl90IGYgPSAmZnVuY3Rpb247CglhdXRvIGMgPSBnZXRfY2FsbGVyKGYpOwoJc3RkOjpjb3V0IDw8IGMuY2FsbCgxKSA8PCBzdGQ6OmVuZGw7CglyZXR1cm4gMDsKfQo=