Наилучшее соответствие между const char * и const char (& p) [T_Size] - PullRequest
2 голосов
/ 19 августа 2010

У меня есть две функции:

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, но я верю, что он будет работатьтак же на еочень компилятор.

Ответы [ 2 ]

4 голосов
/ 19 августа 2010

Таблица 9 в Главе 13 (Разрешение перегрузки) Стандартов ранжирует преобразование «массив в указатель» (для не-шаблона) того же ранга (EXACT MATCH), что и «преобразование не требуется» (для версии шаблона)).

При прочих равных, версия без шаблона предпочтительнее версии шаблона.

1 голос
/ 19 августа 2010

Компилятор всегда будет вызывать не шаблонные перегрузки, если они доступны, по сравнению с шаблонными функциями. Вы предоставили вполне адекватную не шаблонную перегрузку, поэтому компилятор вызывает ее.

...