У меня есть две функции:
void foo(const char * p)
и
template<size_t T_Size>
void foo(const char (& p)[T_Size]) ;
Учитывая вызов:
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 ;
}
Очевидно, вызов foo
со стекомоснованный на правильно объявленный массив ведет себя как положено, тогда как вызов foo
с литералом «liter.: Hello World» не делает, несмотря на то, что два имеют одинаковый тип (согласно RTTI).
Какие именно правилас последующим поиском символа для выбора одной перегрузки над другой?
Почему различное поведение между объявленным массивом и строковым литералом?
Спасибо!
Редактировать
Обратите внимание, что способ получить желаемый результат (то есть, чтобы буквальная строка соответствовала функции foo(const char (& p)[T_Size])
) - это удалить void foo(const char *p)
и добавить вместо него:
struct FooIndirect
{
const char * m_p ;
FooIndirect(const char *p) : m_p(p) {}
} ;
void foo(const FooIndirect & p)
{
// do something with p.m_p
}
Эта косвенность делает шаблонноеfoo лучше подходит для строковых литералов и все еще позволяет пользователю использовать указатели (косвенное обращение будет удалено в оптимизированном режиме компиляции).
Я проверил его на моем g ++ 4.4.3, но я верю, что он будет работатьтак же на еочень компилятор.