我一直在使用 C++检测习惯用法创建一个元函数来确定任意可调用对象的参数数量。到目前为止,我有这个(完整的、可编译的代码在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> { };
当所有可调用参数都不是左值引用时,这很有效:
void foo(int i, int j) { }
static_assert(count_args<decltype(foo)>::value == 2, "");
但是当任何参数是左值引用时,这会失败(原因很明显,因为可调用原型有替换失败):
void bar(char i, bool j, double& k);
static_assert(count_args<decltype(bar)>::value == 3, "doesn't work");
有谁知道如何概括这个想法以使其也适用于左值引用?