Search code examples
c++templatesoverloadingtemplate-specializationoverload-resolution

C++ Overloading takes precedence over Specialization?


Given the following code:

#include <iostream>

using namespace std;

template<typename T> void Print(T t) {
    cout << t << endl;
}

template<> void Print<int>(int t) {
    cout << "int = " << t << endl;
}

void Print(int i) {
    cout << "int2 = " << i << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    Print(1.3);
    Print("tese");
    Print(2);

    char c;

    cin >> c;

return 0;
}

Why is the call Print(2) not ambiguous, but instead calling void Print(int i) ?

ps: Tested with bcc64.exe and cl.exe.


Solution

  • This is because non-template functions are first-class citizens. See this article by Herb Sutter or this SO post for details.

    From Herb Sutter's article:

    Nontemplate functions are first-class citizens. A plain old nontemplate function that matches the parameter types as well as any function template will be selected over an otherwise-just-as-good function template.

    If there are no first-class citizens to choose from that are at least as good, then function base templates as the second-class citizens get consulted next. Which function base template gets selected depends on which matches best and is the "most specialized" (important note: this use of "specialized" oddly enough has nothing to do with template specializations; it's just an unfortunate colloquialism) according to a set of fairly arcane rules: