Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ function match priority [duplicate]

Tags:

c++

function

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?

like image 829
jayatubi Avatar asked Apr 30 '15 07:04

jayatubi


Video Answer


1 Answers

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 sequence S2 if

  • S1 is a proper subsequence of S2 (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 of S2, or S1 and S2 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 function F2 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 and F2 is a function template specialization, or, if not that,

Hence the non-template overload is selected.

like image 187
Columbo Avatar answered Oct 06 '22 11:10

Columbo