16

I get different behavior when trying to overload function and function template. For function:

void foo(int)
{
    std::cout << "int";
}

void foo(char)
{
    std::cout << "char";
}

foo(42) is int. But for function template:

template <int T>
void bar()
{
    std::cout << "int T";
}

template <char T>
void bar()
{
    std::cout << "char T";
}

bar<42>() is ambiguous call. This happens even if I use a char, like bar<'a'>(). Why does one work and not the other?

jxh
  • 69,070
  • 8
  • 110
  • 193
user6378568
  • 161
  • 3
  • How can the compiler tell the difference between a number and a char? – Fantastic Mr Fox May 24 '16 at 23:26
  • @Ben huh? `42` has type `int`, and `'a'` has type `char` – M.M May 24 '16 at 23:29
  • @M.M But the compiler doesnt know that right? Its not written in c++ so there are no strong type definitions, otherwise [this](http://ideone.com/UawQrT) would be an error or warning or something ... – Fantastic Mr Fox May 24 '16 at 23:46
  • @Ben the compiler knows what the types of expressions are. No idea what you mean by "Its not written in c++" – M.M May 24 '16 at 23:47
  • @M.M but conversions between `char` and `int` obviously happen freely as per the example in my comment above, so how can it tell the difference between `'a'` and `97` ? Honest question? The non-templated example is resolved at run time right, which is the difference? – Fantastic Mr Fox May 24 '16 at 23:50
  • 4
    @Ben you're not making any sense sorry. `'a'` is a `char`, `47` is an int. Those are different. Yes, one can be converted to the other but they are still two different things. Overload resolution happens at compile-time. – M.M May 24 '16 at 23:50
  • 2
    Maybe [related](http://stackoverflow.com/questions/28876228/overloaded-non-type-template-is-ambiguous-while-non-templated-function-is-ok)? – PaperBirdMaster May 25 '16 at 07:38
  • @PaperBirdMaster I'd say this question is a duplicate of the one you linked, which has an excellent answer from T.C. that clarifies everything. – bogdan May 25 '16 at 08:32

3 Answers3

7

The standard N4140 (credit goes to M.M) gives this explanation and sample in 14.8.2 Template argument deduction:

9 Except as described above, the use of an invalid value shall not cause type deduction to fail. [Example: In the following example 1000 is converted to signed char and results in an implementation-defined value as specified in (4.7). In other words, both templates are considered even though 1000, when converted to signed char, results in an implementation-defined value.

template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1>(0);    // ambiguous
int i2 = f<1000>(0); // ambiguous

end example ]

However, note that in following drafts the rules are changed because:

This is no longer correct, even ignoring the fact that some implementations may be able to represent the value 1000 as a signed char: integral and enumeration non-type template arguments are now converted constant expressions (14.3.2 [temp.arg.nontype] paragraph 1), and converted constant expressions disallow narrowing conversions (5.20 [expr.const] paragraph 3).

The proposed sample is:

template <int> int f(int);
template <signed char> int f(int);

int i1 = f<1000>(0); // OK
int i2 = f<1>(0);    // ambiguous; not narrowing
AlexD
  • 32,156
  • 3
  • 71
  • 65
  • In C++14 the line is `int i2 = f<1000>(0); // ambiguous` (both are ambiguous) , not sure where you are getting "OK" from – M.M May 24 '16 at 23:23
  • @M.M I mean 14.8.2/9 of 4296. Which version do you use? – AlexD May 24 '16 at 23:26
  • N4140 (same as C++14) . This is why I suggest to say which document you are quoting. "The standard" is ambiguous, and N4296 is not any standard. It's a draft in between C++14 and C++17. – M.M May 24 '16 at 23:27
  • @M.M Good point, thanks, edited. – AlexD May 24 '16 at 23:33
  • Having said that, it's possible that it was changed for N4296 as the result of a defect report – M.M May 24 '16 at 23:34
  • This situation is not the same as in my question. You're taking a parameter but in my question I'm overloading (specializing) purely on the template parameters. – user6378568 May 24 '16 at 23:39
  • @M.M http://wg21.cmeerw.net/cwg/issue1809 – AlexD May 24 '16 at 23:41
  • @user6378568 the parameter is not ambiguous though so I think it's the same. (But this example doesn't explain the rationale for the `f<1>` case) – M.M May 24 '16 at 23:42
  • On top of that, `42` fits within the range of `char` and `int`. The example has to do with narrowing. – user6378568 May 24 '16 at 23:42
  • @user6378568 I think it is the same. (But it could be better if the standard uses the sample functions without parameters.) – AlexD May 24 '16 at 23:43
  • The examples seem to indicate template expansion relies less on the type of the non-type template arguments and more on the values themselves when creating instantiations. – jxh May 25 '16 at 01:12
3

There's a difference between how overloads and specializations are chosen. Overload resolution ranks implicit conversions. No conversion is required to convert 42 to int, so it is an Exact Match, which beats the implicit conversion required for 42 to char.

On the other hand, function template specialization "overloading" uses partial ordering rules, which uses template argument deduction to determine which is more "specialized" than the other. Without going into too much detail, deduction doesn't fail for either int or char with a value of 42, so they're both equally specialized. If you were to use a value outside the range of an signed char, i.e 128, deduction would fail and the int specialization would be chosen.

  • the rule about out-of-range deduction failing seems to have been added after C++14 (see discussion under AlexD's answer) – M.M May 25 '16 at 00:05
  • It'd be great if you could go into more detail about how the partial ordering process works..:) – M.M May 25 '16 at 00:10
1

According to this website, which has a very good examples and explanation, "function template specializations don't overload." Which is why you are receiving call to 'bar' is ambiguous.

NonCreature0714
  • 5,744
  • 10
  • 30
  • 52