Первоначальный вопрос был о неоднозначности между двумя специализациями шаблонов, когда второй аргумент не участвовал в разрешении неоднозначности. Чтобы достичь этого, второй аргумент должен иметь тип 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
введите либо. Не удалось.
Шаблон параметров: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?