Der folgende Code:
%Vor% ... kompiliert nicht mit g++
(version 5.1.0
und 5.3.0
) aufgrund:
Fehler: Teilspezialisierung ist nicht spezialisierter als die primäre Vorlage, da sie mehrere Parameter durch eine Stapelerweiterung ersetzt
... aber kompiliert mit clang
.
Darf man solche Teilspezialisierungen deklarieren?
Randnotiz: Eigentlich ist die Spezialisierung gefährlich, da A<0, int>
nicht mit beiden Compilern kompiliert werden kann (falsche Anzahl von Template-Argumenten).
gcc ist korrekt, der Code ist schlecht formuliert, weil die Spezialisierung nicht spezialisierter ist.
Die Regel aus [temp.class.spec] ist (als Ergebnis von DR 1495 , h / t TC für den Link) ):
Innerhalb der Argumentliste einer partiellen Spezialisierung der Klassenvorlage gelten folgende Einschränkungen: [...] Die Spezialisierung muss spezialisierter sein als die primäre Vorlage (14.5.5.2).
Um das zu bestimmen, würden wir die beiden als synthetisierte Funktionsschablonen neu schreiben:
%Vor%und gehen Sie dann durch die Teilordnungsregeln. Dies beinhaltet wiederum das Synthetisieren neuer Typen / Werte für jeden der Template-Parameter und das Sehen, ob der Abzug in jeder Richtung erfolgreich sein kann.
Definitiv scheitert der Abzug der Spezialisierung mit dem primären (wegen N
vs 0
). In der anderen Richtung, von [temp.deduct.partial]:
Wenn
A
von einem Funktionsparameterpaket umgewandelt wurde undP
kein Parameterpaket ist, schlägt die Typableitung fehl.
Da wir versuchen, T first
für ein Paket abzuleiten, schlägt der Abzug auch in dieser Richtung fehl. Dies bedeutet, dass keine der synthetisierten Funktionsvorlagen spezialisierter ist als andere, was wiederum bedeutet, dass die Spezialisierung der Klassenvorlage nicht spezialisierter ist als die primäre Vorlage. Daher wäre gcc korrekt zu verwerfen.
betrachten:
%Vor% Genau der gleiche Fehler.
Da first
als erstes Element des rest
-Packs interpretiert werden kann, spielt es bei dieser Spezialisierung keine Rolle. Wenn Sie in der Spezialisierung first
hinzufügen - nun, das ist die primäre Vorlage. In Ihrer Spezialisierung können Sie jedoch first
hinzufügen:
Tags und Links c++ c++11 variadic-templates template-specialization