Consider the following function:
template
void register_handler( F& f ) // any callable object
{
// find out T - the argument type of f
This blogpost shows how to implement some function type traits. These should work with everything callable (exception: polymorphic functors :P). You could iterate over the arguments, and use their type to do some sfinae or as a additional template argument.
Function traits as copied from blogpost:
#include
// as seen on http://functionalcpp.wordpress.com/2013/08/05/function-traits/
template
struct function_traits;
// function pointer
template
struct function_traits : public function_traits
{};
template
struct function_traits
{
using return_type = R;
static constexpr std::size_t arity = sizeof...(Args);
template
struct argument
{
static_assert(N < arity, "error: invalid parameter index.");
using type = typename std::tuple_element>::type;
};
};
// member function pointer
template
struct function_traits : public function_traits
{};
// const member function pointer
template
struct function_traits : public function_traits
{};
// member object pointer
template
struct function_traits : public function_traits
{};
// functor
template
struct function_traits
{
private:
using call_type = function_traits;
public:
using return_type = typename call_type::return_type;
static constexpr std::size_t arity = call_type::arity - 1;
template
struct argument
{
static_assert(N < arity, "error: invalid parameter index.");
using type = typename call_type::template argument::type;
};
};
template
struct function_traits : public function_traits
{};
template
struct function_traits : public function_traits
{};
Testcode:
#include
class A
{
};
template
struct Functor
{
void operator()(const T& t)
{}
};
struct Register
{
//int parameters
template
static void RegisterFunctor(const T& /*functor*/, typename std::enable_if::template argument<0>::type, const int&>::value>::type* = 0)
{
std::cout << "Register int func" << std::endl;
}
//A parameters
template
static void RegisterFunctor(const T& /*functor*/, typename std::enable_if::template argument<0>::type, const A&>::value>::type* = 0)
{
std::cout << "Register int func" << std::endl;
}
};
void intFunc(const int&) {}
void aFunc(const A&){}
int main(int /*argc*/, char */*argv*/[])
{
Functor intFunctor;
Functor aFunctor;
Register::RegisterFunctor(intFunctor);
Register::RegisterFunctor(&intFunc);
Register::RegisterFunctor(aFunctor);
Register::RegisterFunctor(&aFunc);
return 0;
}