#include <iostream>
using namespace std;
template<typename T>
void func(T t) { std::cout << "matched template\n"; }
void func(long x) { std::cout << "matched long\n"; }
int main()
{
func(0);
}
output:
matched template
In other cases, the non-template function is preferred when overload resolution might be ambiguous, why is this one different?
§13.3.3 [over.match.best]/p1-2:
1 Define
ICSi(F)
as follows:
- (1.1) [inapplicable bullet omitted]
- (1.2) let
ICSi(F)
denote the implicit conversion sequence that converts the i-th argument in the list to the type of the i-th parameter of viable functionF
. 13.3.3.1 defines the implicit conversion sequences and 13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.Given these definitions, a viable function
F1
is defined to be a better function than another viable functionF2
if for all argumentsi
,ICSi(F1)
is not a worse conversion sequence thanICSi(F2)
, and then
(1.3) for some argument
j
,ICSj(F1)
is a better conversion sequence thanICSj(F2)
, or, if not that,[several inapplicable bullets omitted]
- (1.6)
F1
is not a function template specialization andF2
is a function template specialization, or, if not that,- [inapplicable bullet omitted]
2 If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed.
§13.3.3.2 [over.ics.rank], bullet 3.2:
- (3.2) Standard conversion sequence
S1
is a better conversion sequence than standard conversion sequenceS2
if
- (3.2.1)
S1
is a proper subsequence ofS2
(comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence)
Let F1 = func<int>(int)
, F2 = func(long)
, there's only one argument, of type int
. So ICS1(F1)
is the identity conversion; ICS1(F2)
is an integer conversion from int
to long
; therefore ICS1(F1)
is a better conversion sequence than ICS1(F2)
per [over.ics.rank]/3.2.1 (and so by definition is not worse than ICS1(F2)
). Thus per bullet 1.3 in [over.match.best], F1 is better than F2. The template/non-template tiebreaker, in bullet 1.6, simply never comes into play.