Подтвердить что ты не робот

Приоритет соответствия функции С++

У меня есть простой вопрос о приоритете соответствия функции С++. Предположим, что у меня такой код:

#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 (&)[]?

4b9b3361

Ответ 1

Разрешение перегрузки пытается найти наилучшее преобразование. В следующем абзаце перечислены соответствующие пункты, которые могут различать оба преобразования:

Стандартная последовательность преобразования S1 является лучшей последовательностью преобразования, чем стандартная последовательность преобразования S2, если

  • S1 является правильной подпоследовательностью S2 (сравнивая последовательности преобразования в канонической форме, определенные в 13.3.3.1.1, , исключая любые Lvalue Transformation; рассматривается последовательность преобразования идентичности быть подпоследовательностью любой последовательности неидентичного преобразования) или, если не то,

  • ранг S1 лучше ранга S2, или S1 и S2 имеют одинаковый ранг и различаются по правила в параграфе ниже, или, если не это,

  • [...]

В то время как специализация шаблона функции дает параметр с преобразованием идентичности, перегрузка без шаблона с помощью char const* требует преобразования Array-to-pointer. Интуитивно, мы бы сказали, что первое является лучшим совпадением и поэтому должно быть выбрано. Однако преобразование между массивами и указателями представляет собой преобразование Lvalue, исключенное из первой точки маркера. И поскольку у него есть Точный Match Rank, ранг конверсии не отличается от ранга преобразования для char const (&)[N], который также имеет Точный Match Rank. "Правила в нижеследующем параграфе" также не могут отличить конверсии, поскольку они исключительно обращаются к преобразованиям с производной базой и т.д., Но не к массиву-указателю.

Фактически, преобразование в char const (&)[N] не лучше. Но разрешение перегрузки различает шаблоны:

Учитывая эти определения, жизнеспособная функция F1 определяется как лучше, чем другая жизнеспособная функция F2, если для всех аргументов i, ICSi (F1) не хуже схемы преобразования, чем ICSi (F2), а затем

  • для некоторого аргумента j, ICSj (F1) является лучшим преобразованием последовательности, чем ICSj (F2), или, если это не так,

  • [...]

  • F1не является специализированным шаблоном, а F2 является функцией специализация шаблона или, если не это,

Следовательно, выбрана нетрамовая перегрузка.

Ответ 2

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