Following code is compiled and print "#1". But I think it should be ambiguous error.
template < typename T > void f(T) { std::cout << "#1" << std::endl ; } template < typename T, typename ... Types > void f( T, Types ... ) { std::cout << "#2" << std::endl ; } int main() { f(0) ;// #print #1 } It looks like gcc thinks Non-Variadic Templates version of f(#1) is the best viable function. However, since overload resolution is performed after the template instantiation. And template parameter pack is defined as follows. In 14.6.3 Variadic templates [temp.variadic] "A template parameter pack is a template parameter that accepts zero or more template arguments." It says that template parameter pack can accept zero template argument. The expression f(0) has zero template argument for template parameter pack. So in the above code, I think Variadic Templates function's signature after instantiated will be "void (int)". Because template parameter pack has zero types. template < typename T, typename ... Types > void f( T, Types ... ) { int status = 0 ; std::cout << abi::__cxa_demangle(typeid(f<T, Types...>).name(), 0, 0, &status) << std::endl ; } int main() { f(0) ;// print "void ()(int)" } It looks like gcc thinks the same way. So if Variadic Templates version of f()'s signature is "void (int)", it's exactly same with Non-Variadic Templates version of f(). Thus, call should be ambiguous. -- Summary: Variadic Templates affects the overload resolution rank Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: boostcpp at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43315