#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>());
}