The following code compiles and runs fine as long as someFuncTemplate(func1)
is commented out. However, once it is uncommented, compilation fails with the error " 'value' is not a member of 'Arity<int (*)(int, int)>' " compile error, which I believe is due to the compiler selecting the first template instead of the second one at Arity<F>::value
. I tried removing the brackets from the first template, but the issue remains, just this time with an "incomplete type" compilation error.
How can I force the compiler to select the correct template when I use Arity<F>
?
#include <iostream>
template <typename T>
struct Arity {};
template <typename Ret, typename... Args>
struct Arity<Ret(Args...)>
: std::integral_constant<size_t, sizeof...(Args)>
{};
int func1(int a, int b) { return a + b; }
template <typename F>
void someFuncTemplate(F)
{
std::cout << Arity<F>::value;
}
int main()
{
std::cout << Arity<decltype(func1)>::value << '\n';
//someFuncTemplate(func1);
}
You need to add another specialization for the second case:
template <typename Ret, typename... Args>
struct Arity<Ret (*)(Args...)> : Arity<Ret(Args...)> {};
// ^^^
You could also add
template <typename Ret, typename... Args>
struct Arity<Ret (&)(Args...)> : Arity<Ret(Args...)> {};
in order to make a function declaration such as the below working:
template <typename F>
void someFuncTemplate(F&&) {
std::cout << Arity<F>::value;
}