Template use without angle brackets – Overloading?

I’m a little confused about the idea of using template with <> brackets and without them. When I compiled the code I got the output I wasn’t expecting, and didn’t figure out why.

For example, let’s say I have 2 functions and a template with the same prototype:

using namespace std;

template<typename T> void copy(T a, T b)
{
    cout << "template copy" << endl;
}
void copy(int a, int b)
{
    cout << "int copy" << endl;
}
void copy(string a, string b)
{
    cout << "string copy" << endl;
}

And after compiling the main function:

int main()
{
    copy<int>(1, 2);
    copy<string>("ha", "ha");
    copy("ab", "bc");
    copy(1, 2);
    
    return 0;
}

the output looked like this:

template copy
template copy
template copy
int copy

for the record all the code is written on the same CPP file.

Answer

You have to remember that literal strings are really (constant) arrays of characters, which decays to (constant) pointers to char, i.e. const char*.

Since your function taking std::string arguments is not a direct match, and the compiler will not do a conversion, the template overload will be used (as copy<const char*>).