Приоритет соответствия функции C++ [дубликат]
этот вопрос уже есть ответ здесь:
у меня есть простой вопрос о приоритете соответствия функции c++. Предположим, у меня есть такой код:
#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;
}
результатом кода является (с Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
):
const char*
Я думаю, что литерал типа "Hello world"
должно быть const char[]
. Почему const char*
версия имеет более высокий приоритет, чем const char (&)[]
версия?
2 ответов
разрешение перегрузки пытается найти лучшее преобразование. В следующем абзаце перечислены соответствующие маркеры, которые могут различать оба преобразования:
стандартное преобразование последовательности
S1
- Это лучше, последовательность конвертации, чем стандартная последовательность преобразованияS2
если
S1
правильная последовательностьS2
(сравнение последовательностей преобразования в канонической форме, определенной 13.3.3.1.1, исключая любые Преобразование Значения; рассматривается последовательность преобразования идентификаторов быть подпоследовательностью любой последовательности преобразования неидентичности) или, если не то,в звании
S1
лучше, чем званиеS2
илиS1
иS2
имеют одинаковый ранг и различимы по правила в абзаце ниже, или, если не это,[...]
в то время как специализация шаблона функции дает параметр с преобразованием идентификатора, перегрузка без шаблона с char const*
требуется преобразование массива в указатель. Интуитивно мы бы сказали, что первое лучше подходит и поэтому должно быть выбрано. Однако преобразование массива в указатель является преобразованием Lvalue, исключенным из первой точки маркера. И поскольку он имеет точный ранг соответствия, ранг преобразования не отличается от ранга преобразование для char const (&)[N]
, который также имеет точный ранг соответствия. "Правила в приведенном ниже абзаце" также не могут различать преобразования, поскольку они касаются только производных преобразований в базу и таких, но не array-to-pointer.
на самом деле, преобразование в char const (&)[N]
не лучше в любом случае. Но разрешение перегрузки различает шаблоны:
учитывая эти определения, жизнеспособная функция
F1
определен лучшая функция, чем другая жизнеспособная функцияF2
если для всех аргументов я, ICSя(F1) не хуже последовательности преобразования, чем ICSя(F2), а затем
для некоторых аргумент j, ICSj(F1) - лучшее преобразование последовательности, чем ICSj(F2), или, если не это,
[...]
F1
не является шаблоном функции специализация иF2
функция специализация шаблона, или, если не это,
следовательно, выбрана перегрузка без шаблона.
в вашем конкретном случае соответствующая часть применяемых правил разрешения заключается в том, что не шаблонные функции имеют приоритет над шаблонными функциями, поэтому вы видите указатель, а не ссылку на массив.