c++functiontemplatestemplate-function

Weird behaviour in calling template function


I have written the following code:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
template <class T> T Min(T a, T b)
{
    cout<<"template function: ";
    if(a<b)
        return a;
    return b;
}
char *Min(char *a, char *b)
{
    cout<<"non-template function: ";
    if(strcmp(a,b)==0)
        return a;
    return b;
}
int main()
{
    char c[]="x",d[]="y";

    cout<<Min('x','y')<<endl;
    cout<<Min("x","y")<<endl;
    cout<<Min(c,d)<<endl;

    return 0;
}

output:

template function: x
template function: y
non-template function: y

The 1st function call is ok, it's calling the template function. But, why the 2nd function is also calling the template function while it's a string constant. Shouldn't it call the non-template function ???

Also why the output for 2nd function calling is y, shouldn't it be x ? What's the difference between calling a function with string constant and a char type array though both are string?


Solution

  • Literals in C++ have type array of N constant char, and that will decay into pointer to constant char, which cannot be converted to char*. If you want to provide an overload for C style strings, you should do:

    const char *Min(const char *a, const char *b)
    

    In C++ it is technically undefined to compare pointers that don't belong to the same complete object. In practical terms it means that the result of comparing two pointer for inequality might go one way or another and it is not guaranteed. When the template is selected it will compare the values of the pointers obtained after decaying the string literals, and it just happens that the address of "y" in this case happens to be smaller than the address of "x", but there is no guarantee whatsoever.