Hello I have this example:
#include <iostream>
template <typename T>
int compare(T const&, T const&);
template <typename T>
int compare(T*, T*);
template <>
int compare(char const * const&, char const* const&);
template <unsigned N, unsigned M>
int compare(char const (&)[N], char const(&)[M]);
template <unsigned N>
int compare(char const (&)[N], char const(&)[N]);
template <typename T>
int compare(T const& lhs, T const& rhs){
std::cout << "compare(T const&, T const&)\n";
if(std::less<T>()(lhs, rhs))
return -1;
if(std::less<T>()(rhs, lhs))
return 1;
return 0;
}
template <typename T>
int compare(T* p1, T* p2){
std::cout << "compare(T*, T*)\n";
if( std::less<T>()(*p1, *p2) )
return -1;
if( std::less<T>()(*p2, *p1) )
return 1;
return 0;
}
template <>
int compare(char const * const& p1, char const* const& p2){
std::cout << "compare(char const * const &, char const * const &)\n";
return strcmp(p1, p2);
}
template <unsigned N, unsigned M>
int compare(char const (&ra)[N], char const(&rb)[M]){
std::cout << "compare(char const(&)[N], char const(&)[M])\n";
return strcmp(ra, rb);
}
template <unsigned N>
int compare(char const (&ra)[N], char const(&rb)[N]){
std::cout << "compare(char const(&)[N], char const(&)[N])\n";
return strcmp(ra, rb);
}
int main(){
int a = 10, b = 57;
char const* const cp1 = "Hello";
char const* const cp2 = "World";
std::cout << compare(a, b) << '\n';
std::cout << compare(&a, &b) << '\n';
std::cout << compare(cp1, cp2) << '\n';
// std::cout << compare("Hi", "Hi") << '\n'; // error: ambiguous
// std::cout << compare("Hi", "World!") << '\n'; // error: ambiguous
cout << '\n';
}
Why the call to
compare
passing two arrays of of constant characters is ambiguous even the arrays of different lengths?In fact the second overload that has a single non-type parameter
N
is just for compatibility with C++ 11 because on C++14 and above I can usestd::enable_if
. pleaseWhy also passing
compare(cp1, cp2);
invokescompare(T*, T*)
and notcompare(char const* const&, char const * const&)
?One final question: Does my order of declaring the function templates here affects which function is preferred? Thank you.
Update:
I've manged to make it work by only changing the signature of the version taking two pointers to the parameter type: compare(T*, T*)
to :
template <typename T>
int compare(T const * const&, T const* const&);
Now It works fine so can you explain why?