I recently created this example code to illustrate C++11 variadic template function usage.
template <typename Head, typename... Tail> void foo (Head, Tail...);
template <typename... Tail> void foo (int, Tail...);
void foo () {}
template <typename... Tail>
void foo (int x, Tail... tail)
{
std :: cout << "int:" << x;
foo (tail...);
}
template <typename Head, typename... Tail>
void foo (Head x, Tail... tail)
{
std :: cout << " ?:" << x;
foo (tail...);
}
foo (int (123), float (123)); // Prints "int:123 ?:123.0"
If the first two lines which forward-declare foo
are omitted then this prints int:123int:123
instead. This surprised a certain experienced and knowledgeable C++ programmer.
He was convinced the forward-declarations shouldn't be necessary because the body won't be instantiated until the second phase of two-phase lookup. He thinks the compiler (gcc 4.6) has a bug.
I believe the compiler is right because the two foo
are different base template functions and the choice of base template needs to be locked-in during the first phase or else you could violate the one-definition rule by instantiating foo
before all versions of it have been defined and then again afterwards (consider how the linker assumes that redundant template function definitions are identical, interchangeable, and discardable).
So, who is right?
The above-linked GOTW nicely explains how and why function templates don't partially specialise, but the existence of variadic template functions seems to add to the confusion -- the intuition that foo<int,Tail...>
should be a partial specialisation of foo<Head,Tail...>
is stronger than that intuition for non-variadic functions, at least to me.