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

Reply via email to