Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't these overloads ambiguous?

The following code compiles fine with gcc and clang.

template <typename T>
struct identity
{
    typedef T type;
};

template <typename T>
void foo(typename identity<T>::type);

template <typename T>
void foo(T);

int main()
{
    foo<int>(0);
}

It looks like overload resolution is choosing the first overload (the identity<T>::type one).

Could someone explain why the overloads aren't ambiguous? As far as I can tell, the only difference between them is that the argument of the first one is a non-deduced context and the argument of the second one isn't, but since I'm providing the template argument explicitly, I don't see why that should matter.

like image 431
HighCommander4 Avatar asked May 26 '13 22:05

HighCommander4


1 Answers

Both overloads are viable, but the former is more specialized than the latter, and therefore it gets picked by overload resolution.

Per paragraph 13.3.3/1 of the C++11 Standard on overload resolution:

[...] a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then

— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,

— the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type. [ ... ] or, if not that,

F1 is a non-template function and F2 is a function template specialization, or, if not that,

F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.6.2.

The process of determining which of two function templates is more specialized than the other is outlined in paragraph 14.5.6.2/2:

Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type. The deduction process determines whether one of the templates is more specialized than the other. If so, the more specialized template is the one chosen by the partial ordering process.

like image 146
Andy Prowl Avatar answered Sep 28 '22 12:09

Andy Prowl