Первоначальный вопрос был о неоднозначности между двумя специализациями шаблонов, когда второй аргумент не участвовал в разрешении неоднозначности. Чтобы достичь этого, второй аргумент должен иметь тип std :: size_t. Ваш образец не отвечает на вопрос и не доказывает, что «объявления шаблона не являются неоднозначными», потому что первый или второй аргумент становится более специализированным. Если вы попытаетесь вызвать ваш шаблон как «func (buf, static_cast <std :: size_t> (2))», вы получите оригинальную проблему.

у следующие два объявления шаблона неоднозначны (поэтому ни один не является более специализированным, чем другой)? Я знаю, что этот вопрос много раз поднимался на Stack Overflow, но обычно люди отвечают, как решить двусмысленность, а не почему это произошло.

Я.template <class T> void func(char* buf, T size) {}

II.template <std::size_t N> void func(char (&buf)[N], std::size_t size) {}

Попытка пройти шаги стандарта C ++ 14 для разрешения частичного упорядочения шаблонов функций (14.5.6.2):

Чтобы создать преобразованный шаблон, для каждого типа, не типового или шаблонного параметра шаблона (включая его пакеты параметров шаблона (14.5.3)) синтезируйте уникальный тип, значение или шаблон класса соответственно и подставьте его для каждого вхождения этого параметра. в типе функции шаблона.

Тип функции преобразованной функции I шаблона:void func(char*, U1), гдеU1 это какой-то уникальный синтетический тип.

Преобразованная функция Тип функции шаблона II:void func(char (&buf)[N1], std::size_t), гдеN1 это какая-то уникальная синтетическая ценность.

Используя тип функции преобразованного шаблона функции, выведите тип из другого шаблона, как описано в 14.8.2.4.

Итак, давайте попробуем выполнить вывод типа с одной стороны (используя первый шаблон в качестве аргумента, а второй - как шаблон параметра) и с другой стороны.

Дело 1.

Шаблон параметров:template <std::size_t N> void func(char (&buf)[N], std::size_t size), Преобразованный шаблон аргумента:void func(char*, U1).

Попытка вывести параметры шаблона. "char (&buf)[N]"не может быть выведено из"char*"тип. U1 не соответствуетstd::size_t введите либо. Не удалось.

Случай 2

Шаблон параметров:template <class T> void func(char* buf, T size), Преобразованный шаблон аргумента:void func(char (&buf)[N1], std::size_t).

Попытка вывести параметры шаблона. Первый аргумент шаблона параметра не является типом вообще, и он совместим сchar[]. T должно быть выведеноstd::size_t.

Поэтому шаблон II должен быть более специализированным и должен быть выбран в следующем коде:

char buf[16];
func(buf, static_cast<std::size_t>(16));

Почему это не относится к GCC 5.3 и Clang 4.0?

Ответы на вопрос(1)

Ваш ответ на вопрос