I've been using the C++ detection idiom create a metafunction for determining the number of arguments to an arbitrary callable. So far, I have this (full, compilable code at http://ideone.com/BcgDhv):
static constexpr auto max_num_args = 127;
struct any { template <typename T> operator T() { } };
template <typename F, typename... Args>
using callable_archetype = decltype( declval<F>()(declval<Args>()...) );
template <typename F, typename... Args>
using is_callable_with_args = is_detected<callable_archetype, F, Args...>;
template <typename F, size_t I = 0, typename... Args>
struct count_args
: conditional<is_callable_with_args<F, Args...>::value,
integral_constant<size_t, I>,
count_args<F, I+1, Args..., any>
>::type::type
{ };
template <typename F, typename... Args>
struct count_args<F, max_num_args, Args...> : integral_constant<size_t, max_num_args> { };
This works great when none of the callable arguments are lvalue references:
void foo(int i, int j) { }
static_assert(count_args<decltype(foo)>::value == 2, "");
But when any of the arguments are lvalue references, this fails (for obvious reasons, since the callable archetype has a substitution failure):
void bar(char i, bool j, double& k);
static_assert(count_args<decltype(bar)>::value == 3, "doesn't work");
Does anyone know how to generalize this idea to make it work with lvalue references as well?