gcc jest poprawny, kod jest źle sformułowany, ponieważ specjalizacja nie jest w rzeczywistości bardziej wyspecjalizowana.
Zasada z [temp.class.spec] to (jak na skutek DR 1495, h/t TC link):
Within the argument list of a class template partial specialization, the following restrictions apply: [...] The specialization shall be more specialized than the primary template (14.5.5.2).
W celu określenia, że to byłoby przepisz dwa syntetyzowane szablony funkcji:
template <size_t N, class T, T first, T... rest>
void __f(A<N, T, first, rest...>); // primary
template <class T, T... args>
void __f(A<0, T, args...>); // specialization
a następnie przejdź przez zasady częściowego zamawiania. To z kolei polega na syntezowaniu nowych typów/wartości dla każdego z parametrów szablonu i sprawdzaniu, czy dedukcja może odnieść sukces w którymkolwiek kierunku.
Zdecydowanie dedukcja specjalizacji kończy się niepowodzeniem z pierwotnym (z powodu N
vs 0
). W przeciwnym kierunku, od [temp.deduct.partial]:
If A
was transformed from a function parameter pack and P
is not a parameter pack, type deduction fails.
Ponieważ staramy się wywnioskować T first
na opakowaniu, odliczenie nie tak dobrze w tym kierunku. Oznacza to, że żaden ze zsyntetyzowanych szablonów funkcji nie jest bardziej wyspecjalizowany niż inne, co z kolei oznacza, że specjalizacja szablonu klasy nie jest bardziej wyspecjalizowana niż szablon podstawowy. W związku z tym gcc byłoby prawidłowe do odrzucenia.
Aby umożliwić '' a <0, int>, musisz zmienić pierwszy szablon. jest już za późno na specjalizację. – Jarod42
@ Jarod42 Tak Wiem, że takie tworzenie szablonu jest błędne, pytam o częściową specjalizację z tylko 'T ... args' podnoszącym błąd w' g ++ 'ale nie' clang' (ponownie zorganizuj pytanie do zrobienia jaśniej). – Holt
GCC ma rację. Jest to źle sformułowane na [DR 1495] (http://wg21.link/cwg1495) (nieco nie zaskakujące, ponieważ zostało zgłoszone przez opiekuna GCC). –