The problem is only solvable if the functors do not have multiply overloaded operator()
, nor default arguments. Fortunately both are always true of lambdas.
You can discover what arguments a lambda type T
takes by inspecting & T::operator()
.
template< typename sig >
struct ptmf_args_to_tuple;
template< typename c, typename r, typename ... a >
struct ptmf_args_to_tuple< r (c::*)( a ... ) > {
typedef std::tuple< a ... > type;
};
template< typename c, typename r, typename ... a >
struct ptmf_args_to_tuple< r (c::*)( a ... ) const > {
typedef std::tuple< a ... > type;
};
template< typename fn >
struct functor_args_to_tuple {
typedef typename ptmf_args_to_tuple< decltype( & fn::operator () ) >::type type;
};
Use the metafunction to let the overloads discriminate by SFINAE:
template <typename Functor>
typename std::enable_if<
std::tuple_size< typename functor_args_to_tuple< Functor >::type >
::value == 1,
boolean >::type
some_func(Functor functor) {