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 ADL (a.k.a the Koenig's 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 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.