#include <functional>
#include <iostream>
using namespace std;
template <typename Arg, typename Result>
void ho_fun(Result(*argFun)(Arg)) {
Arg arg = 13;
argFun(arg);
}
template <typename Arg1, typename Arg2, typename Result>
void ho_fun(Result (*argFun)(Arg1, Arg2)) {
Arg1 arg1 = 13;
Arg2 arg2 = 42;
argFun(arg1, arg2);
}
template <typename T, typename Arg, typename Result>
void ho_fun(Result(T::*argFun)(Arg)) {
T myClass;
Arg arg = 13;
(myClass.*argFun)(arg);
}
template <typename T, typename Arg1, typename Arg2, typename Result>
void ho_fun(Result(T::*argFun)(Arg1, Arg2)) {
T myClass;
Arg1 arg1 = 13;
Arg2 arg2 = 42;
(myClass.*argFun)(arg1, arg2);
}
template <typename T, typename Arg, typename Result>
void ho_fun(Result(T::*argFun)(Arg) const) {
T myClass;
Arg arg = 13;
(myClass.*argFun)(arg);
}
template <typename T, typename Arg1, typename Arg2, typename Result>
void ho_fun(Result(T::*argFun)(Arg1, Arg2) const) {
T myClass;
Arg1 arg1 = 13;
Arg2 arg2 = 42;
(myClass.*argFun)(arg1, arg2);
}
template <class T>
void ho_fun(T argFun) {
ho_fun(&T::operator());
}
int oneFun(int a) { return -a; }
int twoFun(int a, int b) { return a + b; }
struct Foo {
int oneFun(int a) { return -a; }
int twoFun(int a, int b) { return a + b; }
};
int main() {
ho_fun(oneFun);
ho_fun(twoFun);
ho_fun(&Foo::oneFun);
ho_fun(&Foo::twoFun);
ho_fun(negate<int>());
ho_fun(plus<int>());
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnLCB0eXBlbmFtZSBSZXN1bHQ+CnZvaWQgaG9fZnVuKFJlc3VsdCgqYXJnRnVuKShBcmcpKSB7CglBcmcgYXJnID0gMTM7CgoJYXJnRnVuKGFyZyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBBcmcxLCB0eXBlbmFtZSBBcmcyLCB0eXBlbmFtZSBSZXN1bHQ+CnZvaWQgaG9fZnVuKFJlc3VsdCAoKmFyZ0Z1bikoQXJnMSwgQXJnMikpIHsKCUFyZzEgYXJnMSA9IDEzOwoJQXJnMiBhcmcyID0gNDI7CgoJYXJnRnVuKGFyZzEsIGFyZzIpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnLCB0eXBlbmFtZSBSZXN1bHQ+CnZvaWQgaG9fZnVuKFJlc3VsdChUOjoqYXJnRnVuKShBcmcpKSB7CglUIG15Q2xhc3M7CglBcmcgYXJnID0gMTM7CgoJKG15Q2xhc3MuKmFyZ0Z1bikoYXJnKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIFJlc3VsdD4Kdm9pZCBob19mdW4oUmVzdWx0KFQ6OiphcmdGdW4pKEFyZzEsIEFyZzIpKSB7CglUIG15Q2xhc3M7CglBcmcxIGFyZzEgPSAxMzsKCUFyZzIgYXJnMiA9IDQyOwoKCShteUNsYXNzLiphcmdGdW4pKGFyZzEsIGFyZzIpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgQXJnLCB0eXBlbmFtZSBSZXN1bHQ+CnZvaWQgaG9fZnVuKFJlc3VsdChUOjoqYXJnRnVuKShBcmcpIGNvbnN0KSB7CglUIG15Q2xhc3M7CglBcmcgYXJnID0gMTM7CgoJKG15Q2xhc3MuKmFyZ0Z1bikoYXJnKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZzEsIHR5cGVuYW1lIEFyZzIsIHR5cGVuYW1lIFJlc3VsdD4Kdm9pZCBob19mdW4oUmVzdWx0KFQ6OiphcmdGdW4pKEFyZzEsIEFyZzIpIGNvbnN0KSB7CglUIG15Q2xhc3M7CglBcmcxIGFyZzEgPSAxMzsKCUFyZzIgYXJnMiA9IDQyOwoKCShteUNsYXNzLiphcmdGdW4pKGFyZzEsIGFyZzIpOwp9Cgp0ZW1wbGF0ZSA8Y2xhc3MgVD4Kdm9pZCBob19mdW4oVCBhcmdGdW4pIHsKCWhvX2Z1bigmVDo6b3BlcmF0b3IoKSk7Cn0KCmludCBvbmVGdW4oaW50IGEpIHsgcmV0dXJuIC1hOyB9CmludCB0d29GdW4oaW50IGEsIGludCBiKSB7IHJldHVybiBhICsgYjsgfQoKc3RydWN0IEZvbyB7CglpbnQgb25lRnVuKGludCBhKSB7IHJldHVybiAtYTsgfQoJaW50IHR3b0Z1bihpbnQgYSwgaW50IGIpIHsgcmV0dXJuIGEgKyBiOyB9Cn07CgppbnQgbWFpbigpIHsKCWhvX2Z1bihvbmVGdW4pOwoJaG9fZnVuKHR3b0Z1bik7Cglob19mdW4oJkZvbzo6b25lRnVuKTsKCWhvX2Z1bigmRm9vOjp0d29GdW4pOwoJaG9fZnVuKG5lZ2F0ZTxpbnQ+KCkpOwoJaG9fZnVuKHBsdXM8aW50PigpKTsKfQ==