For the following code:
#include <iostream>
using std::cout; using std::endl;
template <typename T>
int compare(const T&, const T&) {
cout << __PRETTY_FUNCTION__ << endl;
return 0;
}
template <size_t N, size_t M>
int compare(const char (&)[N], const char (&)[M]) {
cout << __PRETTY_FUNCTION__ << endl;
return 0;
}
int main(int argc, char *argv[]) {
compare("hi", "is");
}
When I compiles the code with g++ -std=c++1y
, it complains:
error: call of overloaded ‘compare(const char [3], const char [3])’ is ambiguous
compare("hi", "is");
According to the rules of template overloading, viable functions are:
compare(const T&, const T&) with T = char [3]
compare(const char (&)[N], const char (&)[M]) with N = 3ul, M = 3ul
They both provide an equally good (i.e., exact) match to the call. So I should check which one is more specialized.
But according to my limited knowledge, const T&
is more general than const char (&)[N]
. So I think that compare(const char (&)[N], const char (&)[M])
is more specialized. But why is this call ambiguous?
The first overload compare(const T&, const T&)
forces both parameters to be the same type, while the second overload doesn't. So in this regard the first overload is more specific.
However, the second overload forces both parameters to be char
arrays, so it is more specific in that regard.
Therefore, neither overload can be said to be more specialized than the other, and the result is the ambiguity error.
Another way to look at it is that each overload can accept an input that the other doesn't: Only the first overload will accept a call where both arguments are int&
. And only the second overload will accept a call where the arguments are char (&)[2]
and char (&)[3]
.
If you change the second overload to
template <size_t N> int compare(const char (&)[N], const char (&)[N])
it will fix the error, as this is now strictly more specific than the first overload.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With