Приоритет соответствия функции 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 функция специализация шаблона, или, если не это,

следовательно, выбрана перегрузка без шаблона.


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