Рассмотрим следующий код:
#include<iostream>
template<class..., class... T>
int f(T...) { return 1; }
template<class... T>
int f(T...) { return 2; }
int main()
{
std::cout << f(1);
}
Он компилирует и печатает 1
на gcc 8.2, но не может скомпилировать на clang 7 из-за неоднозначности вызова f(1)
.
Если вызов заменен на f()
, оба компилятора не могут скомпилировать, утверждая, что вызов является неоднозначным.
Если пакеты параметров class... T
заменены простым параметром class T
(и T...
с T
), оба компилятора также заявляют о неоднозначности.
Какой из компиляторов являетсясоответствовать стандарту в первом примере?Я предполагаю, что это сводится к определенным правилам частичного упорядочения для шаблонов функций, или это уже плохо сформировано, чтобы использовать пакет двойных параметров таким образом?
Редактировать:
Насколько я понимаю, чтодвойной пакет сам по себе не является неправильным, потому что [temp.param] 17.1 / 15 в моем чтении явно разрешает это, если второй пакет выводится из аргументов функции, что, по-видимому, имеет место из-за T...
Пакет параметров функции.
Можно также явно указать аргументы первого пакета параметров, но не вторые, и поэтому не всегда (после вычета аргументов шаблона) хотя бы один пакет параметров пуст,Я не уверен, делает ли это программу плохо сформированной, потому что я не знаю, как читать, например, [temp.res] 17.7 / 8.3 в этом контексте.
Как gcc, так и clang кажутся хорошими ссам пакет двойных параметров, например, когда устранена перегрузка второго шаблона функции, оба компилятора печатают 1
.Но это может быть случай плохо сформированный, диагностика не требуется .
Кроме того, я предполагаю, что с выводом аргумента шаблона класса шаблон класса variadic может иметь определенный шаблон конструктора variadic, которыйподразумевает кандидата-конструктора, похожего на мой пример пакета с двумя параметрами, и, насколько я понимаю, в этом контексте имеет место одно и то же разрешение перегрузки и вывод аргумента шаблона.Этот вопрос был мотивирован другим вопросом с такой настройкой: Сбой вывода шаблона класса Variadic с gcc 8.2, компилируется с помощью clang и msvc См. Также обсуждение по следующим темам: Руководства по дедукции и шаблоны класса variadic сконструкторы шаблонов переменных - несоответствующие длины пакета аргументов
Теперь я также нашел ответ на вопрос Руководство по дедукции и шаблоны переменных , которые, как я предполагаю, подразумевают, что gcc неверен, и вызов долженможно считать неоднозначным, но я бы хотел, чтобы он подтвердил, что это применимо и здесь.Я также хотел бы более подробно изложить обоснование, поскольку правила частичного упорядочения шаблона функции кажутся мне очень неясными.