Это CWG1395, для которого дефект resolution был недавно проголосован за проект стандарта C++ 17. Далее был добавлен в [temp.deduct.partial]:
... [если] шаблон функции F
, по меньшей мере, специализировался в качестве матрицы G
функции, и наоборот, и если G
имеет параметр трейлинг пакет для которых F
не имеет соответствующего параметра, и если F
не имеет завершающего пакета параметров, то F
более специализирован, чем G
.
Стандарт не явно определить, что это означает, что с помощью «трейлинг параметров пакета», но, судя по существующим контексты, в которых используется этот термин, он относится к параметру шаблона пакета, который появляется в качестве крайнего правого параметра список параметров шаблона:
template<class T, class... U> struct X;
// ^^^^^^^^^^
Или параметр функции пакета, который появляется в качестве крайнего правого параметра в списке параметров:
template<class T, class... U> void y(T, U...);
// ^^^^
текущий проект все еще содержит это устаревший пример в [temp.deduct.type]:
template<class T, class... U> void f(T, U...);
template<class T> void f(T);
f(&i); // error: ambiguous
Этого стандартном отчете дефект был вокруг в течение нескольких лет, и оба GCC и Clang внедрили решения этого. Они оба согласны с тем, что приведенный выше пример является действительным вызовом второй перегрузки f
.
Где GCC и Clang не согласны с объемом разрешения дефекта. Это понятно, поскольку он был недавно обновлен, чтобы включить предлагаемую стандартную формулировку. В вашем примере, пакет не разлагаются в списке параметров функции, но в список аргументов шаблона из типа параметра функции:
template<class T, class... U> void g(tuple<T, U...>);
template<class T> void g(tuple<T>);
g(tuple<int>{});
ССАГПЗ рассматривает это как действительный вызов второй перегрузки g
; Кланг рассматривает это как неоднозначное.Правильность Clang может зависеть от того, должен ли «trailing parameter pack» включать в себя завершающий набор шаблонов или только завершающий набор параметров .
Обратите внимание, что оба составителей согласны, что C<int>
относится ко второй частичной специализации шаблона класса C
в следующем примере:
template<class...> struct C;
template<class T, class... U> struct C<T, U...> {};
template<class T> struct C<T> {};
Это кажется несогласованность в Clang, так как стандартные правила для частичного упорядочения специализация шаблонов классов определяется в части частичного упорядочения шаблонов функций. См. CWG1432.
Lol, эти два комментария противоречат друг другу! Поэтому есть что обсудить. – Walter
@ Jarod42 Итак, вы говорите, что «trailing parameter pack» относится к аргументам функции, а не параметрам шаблона? – Walter
Действительно, clang и gcc не согласны [Demo] (http://coliru.stacked-crooked.com/a/6f67a0a696424a56). – Jarod42