This is impossible in the general case for functors, i.e. class types using operator() . This also includes lambda objects. Consider the case when operator() overloaded:
struct functor { double operator()(double) const; int operator()(int) const; }; typedef function_traits<functor>::result_type result_type;
What should be result_type ?
Note that as a workaround, some protocols (for example, boost::apply_visitor from Boost.Variant) require that the result_type be present in the class, provided that all overloads, when accepting different types, return a type compatible with this result_type .
And, of course, with some types T0 ... Tn , std::result_of<functor(T0, ..., Tn)>::type sets the return type associated with the parameter types.
In the case where one operator() [1] overload is present, you can take the operator() member and check this.
struct not_overloaded { double operator()(double) const; }; template<typename T> struct functor_traits { typedef decltype(&T::operator()) type; };
functor_traits<not_overloaded>::type is of type double (not_overloaded::*)(double) const here, and with a little effort you can extract what you want from it. (for example, specialization of the form Ret (T::*)(Args...) const will correspond to this type.)
[1]: but a functor can provide functionality by implicitly converting to a function pointer / link so you can skip this.
Luc danton
source share