I have simple question about the c++ function match priority. Suppose I have such code:
#include <iostream>
void func(const char*)
{
std::cout << "const char*" << std::endl;
}
template<int N>
void func(const char (&) [N])
{
std::cout << "const char (&) [N]" << std::endl;
}
int main(int argc, char* argv[])
{
func("Hello world");
return 0;
}
The result of the code is (with Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
):
const char*
I think the literal type of the "Hello world"
should be const char[]
. Why the const char*
version has a higher priority than the const char (&)[]
version?
Overload resolution attempts to find the best conversion. The following paragraph lists the relevant bullet points that could distinguish both conversions:
Standard conversion sequence
S1
is a better conversion sequence than standard conversion sequenceS2
if
S1
is a proper subsequence ofS2
(comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or, if not that,the rank of
S1
is better than the rank ofS2
, orS1
andS2
have the same rank and are distinguishable by the rules in the paragraph below, or, if not that,[…]
While the specialization of the function template yields a parameter with an identity conversion, the non-template overload with char const*
requires an Array-to-pointer conversion. Intuitively, we'd say that the former is a better match and should thus be selected. However, the array-to-pointer conversion is an Lvalue Transformation, excluded from the first bullet point. And since it has Exact Match Rank, the rank of the conversion isn't different than the rank of the conversion for char const (&)[N]
, which also has Exact Match Rank. "The rules in the paragraph below" cannot distinguish the conversions either, as they solely address derived-to-base conversions and such, but not array-to-pointer.
In fact, the conversion to char const (&)[N]
is not better in any way. But overload resolution discriminates templates:
Given these definitions, a viable function
F1
is defined to be a better function than another viable functionF2
if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
[…]
F1
is not a function template specialization andF2
is a function template specialization, or, if not that,
Hence the non-template overload is selected.
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