As better explained by Klaus, your original code doesn't works because std::enable_if_t
need to check a template of the method itself and isn't enough the template list of the class.
I propose a simplified alternative of the Klaus's solution.
First of all, you need a template parameter to check; you can use one with a default value deduced from the template paramenter of the class (Args...
).
Surely you can use a type taking a std::tuple
of the Args...
but, taking in count that you're only interested in the number of Args...
parameters, I find it's simpler to use a std::size_t
template parameter initialized with the number of Args...
template <std::size_t N = sizeof...(Args)>
std::enable_if_t<N> foo (Args const & ... args)
{ std::cout << "N args" << std::endl; }
Regarding the zero args version, there is no need to make it a template version; you can simply write it with zero parameters
void foo ()
{ std::cout << "zero args" << std::endl; }
In case of zero Args...
, the not-template version take the precedence over the template one.
The following is a full compiling example
#include <iostream>
#include <type_traits>
template <typename... Args>
struct C
{
void foo ()
{ std::cout << "zero args" << std::endl; }
template <std::size_t N = sizeof...(Args)>
std::enable_if_t<N> foo(const Args&... args)
{ std::cout << "N args" << std::endl; }
};
int main ()
{
C<> c0;
C<int> c1;
c0.foo();
c1.foo(42);
}