C++ Primer 5th ed: function template overloading vs specialization

70 Views Asked by At

I have this example from C++ primer 5th ed:

template <typename T>
int compare(T const& x, T const& y) // in the book const T&
{
    cout << "primary template\n"; // I've added print statements
    if(std::less<T>()(x, y))
        return -1;
    if(std::less<T>()(y, x))
        return 1;
    return 0;
}

template <unsigned N, unsigned M>
int compare(char const(&rArr1)[N], char const(&rArr2)[M])
{
    cout << "overload for arrays\n";
    return strcmp(rArr1, rArr2);
}

template <>
int compare(char const* const &p1, char const* const &p2)
{
    cout << "specilization for char* const\n";
    return strcmp(p1, p2);
}


int main()
{
    std::cout << compare("Hi", "Mom") << '\n';
}

"Whether we define a particular function as a specialization or as an independent, non-template function can impact function matching. For example, we have defined two versions of our compare function template, one that takes references to array parameters and the other that takes const T&. The fact that we also have a specialization for character pointers has no impact on function matching. When we call compare on a string literal:

compare("hi", "mom");

both function templates are viable and provide an equally good (i.e., exact) match to the call. However, the version with character array parameters is more specialized (§ 16.3, p. 695) and is chosen for this call."

  • I think the it is incorrect: "compare("hi", "mom"); both templates are viable" because as I see the first version that takes T const&, T const& is not viable because it is instantiated as:

      compare(char const(&rArra1)[3], char const(&rArr2)[4]);
    

In which case sizes are different and as we know the size of an array is a part of its type thus here the two literal strings have two different types thus the Template Argument Deduction will fail thus this instantiation is rejected. it is as if we wrote: compare(5, 0.); // int, double so the compiler cannot deduce a unique type as it is required here.

  • To confirm what I am saying if I comment out the version taking array types then the code won't compile for that call with two literal strings with different sizes.

  • What confuses me too is that if I comment out the arrays-type version the code doesn't compile even if I have the third version (taking pointer to character strings)! Is this because of the fact that a Specialization doesn't affect function matching? and what was rejected by a primary template is rejected by all of its specializations?

Please clarify. Thank you!

0

There are 0 best solutions below