What's the essential difference between these two variadic functions?
I've been frustrated by a simple variadic template function:
constexpr size_t num_args () {
return 0;
}
template <typename H, typename... T>
constexpr size_t num_args () {
return 1 + num_args <T...> ();
}
int main () {
std :: cout << num_args <int, int, int> ();
}
The above doesn't compile, see above linked question and followup for details, yet the following function DOES compile
template <typename T, typename... Args> void foo (T, Args...);
template <typename... Args> void foo (int, Args...);
void foo () {}
template <typename... Args>
void foo (int x, Args... arg开发者_开发问答s)
{
std :: cout << "int:" << x;
foo (args...);
}
template <typename T, typename... Args>
void foo (T x, Args... args)
{
std :: cout << " T:" << x;
foo (args...);
}
foo (int (123), float (123)); // Prints "int:123 T:123.0"
Both seem to be using the same language mechanism, but why is the first one bad when the second one is good?
The difference is that the first function
constexpr size_t num_args () {
return 0;
}
is not a template, so it can never be called like this
num_args <T...> ();
I'm starting to think that the difference is that
foo (args...);
exploits overloading whereas
num_args <T...> ();
exploits specialisation.
Overloading can handle the base case but specialisation can't for function templates (but it can for classes) which is why auxilliary_class<Args...>::value
is idiomatic.
精彩评论