Best lookup match between const char * and const char (& p)[T_Size]
I have two functions :
void foo(const char * p)
and
template<size_t T_Size>
void foo(const char (& p)[T_Size]) ;
Given the call:
int main(int argc, char* argv[])
{
char a[21] ; // typeid : A21_c
sprintf(a, "a[21] : Hello World") ;
const char * b = "b : Hello World" ; // typeid : PKc
// note that literal "liter. : Hello World" has a typeid : A21_c
foo(a) ; // calls foo(const char (& p)[T_Size])
foo(b) ; // calls foo(const char * p)
foo("liter. : Hello World") ; // calls foo(const char * p) ???
return 0 ;
}
Apparently, calling foo
with a stack-based correctly declared array behaves as expected, while calling foo
with a literal "liter. : Hello World" does not, despite the two having the same type (according to RTTI).
What are exactly the rules followed by the symbol lookup to choose one overload over the other ?
Why the different behaviour between a declared array and a string literal ?
Thanks !
Edit
Note that a way to have the desired result (i.e. have a litteral string match the foo(const char (& p)[T_Size])
function) is to remove the void foo(const char *p)
and add instead:
struct FooIndirect
{
const char * m_p ;
FooIndirect(const char *p) : m_p(p) {}
} ;
void foo(const FooIndirect & p)
{
// do something with p.m_p
}
This indirection makes the templated foo a better match for string litterals, and still enables开发者_Go百科 the user to use pointers (the indirection will be removed in optimized compilation mode).
I tested it on my g++ 4.4.3, but I believe it will work the same way on every compiler.
Table 9 in Chapter 13(Overload Resolution) of the Standards, ranks "Array to pointer" conversion (for non-template) to be of the same rank (EXACT MATCH) as "no Conversion Required" (for the template version).
Everything else being the same, the non-template version is preferred over the template version.
The compiler will always call non-templated overloads if available in comparison to templated functions. You provided a perfectly adequate non-templated overload, so the compiler calls it.
精彩评论