I created a metafunction using SFINAE to determine the number of arguments of a function at compile time. It works fine with gcc when used with with function objects, but not with lambda closures, I don't understand why. The metafunction is here below
template < typename T >
int val (T &&){return 0;};
template <int N, typename Functor>
struct has_args {
template <typename F , int ... Args>
static auto test(F, decltype(val(std::declval<F>()( Args ... ))), std::integer_sequence<int, Args ...>){
return std::true_type{};
};
template <typename F, typename Val, typename Seq>
static auto test(F, Val, Seq){
return std::false_type{};
};
using type = decltype (test(std::declval<Functor>(), 0, std::make_integer_sequence<int, N>()));
};
and here is how it should behave
struct func{
template<typename T>
int operator()(T){}
};
int main(){
auto lambda0 = [](auto arg){};
static_assert(has_arg<1, func>::type::value==true, "error");
//static_assert(has_arg<1, decltype(lambda0)>::type::value==true, "error"); // Assertion fails!
}
The full code (with few more examples) is in this git repo: https://github.com/crosetto/has_args/blob/main/number_of_arguments.cpp
Does anybody have an explanation of why this doesn't work with lambdas?