18

(sollte 0 sein) Während der letzten g ++ experimentieren - 5 Compiler, schrieb ich unter Anweisung in einer Datei:C++ 14 Warnung: Zu viele Template-Header für variable

template<T> T a; 
template<> int a = 1; 

was dazu führt:

Warnung: zu viele Template-Header für a (sollte 0 sein)

auch effektiv, ist es nicht wirklich a<int> spezialisiert. z.B.

template<typename T> T a; 
template<> int a = 1; 

int main() { 
    std::cout << a<double> << "\n"; // prints 0; OK 
    std::cout << a<int> << "\n"; // prints 0! why not 1? 
} 

Was ist das Geheimnis dieser Syntax?

+4

Das ist eine irreführende Warnung. Ich bin überrascht, dass es kein Fehler war. War es die einzige Diagnose? – Yakk

+0

@Yakk, ja in g ++ - 5 das ist die einzige Diagnose. Bin mir nicht sicher, ob ich klingeln könnte. – iammilind

+0

Ah, ich denke ich bekomme jetzt die Warnung! Es heißt 'int a = 1;' sollte 0 Template-Header haben, wobei 'template <' whatever '>' ein Template-Header ist. Stellen Sie sich vor, Sie hätten die 'Vorlage T a;' davor gelöscht - die Warnung ist sinnvoll. Immer noch schockierend, dass es eine Warnung ist, kein Fehler. – Yakk

Antwort

22

Template-Argumente können nur in expliziter Spezialisierung Funktion Vorlagen weggelassen werden. Sie haben eine variable Schablone, also müssen Sie umfassen die <int>:

template<> int a<int> = 1; 

C++ 14 (n4140) Zitiert, 14.7.3/10 (Hervorhebung von mir):

Eine Hinter Vorlage -argument kann nicht angegeben werden in der Vorlage-ID Benennung einer expliziten Funktionsvorlage Spezialisierung vorausgesetzt, es kann von der Funktion Argument Typ abgeleitet werden.

Wenn Sie nicht die Art wiederholen möchten, können Sie auto verwenden:

template<> auto a<int> = 1; 

[Live example] Clang verwenden.

Eines ist dabei zu beachten: Bei der Verwendung von wird der Typ der spezialisierten Variablen vom Initialisierer abgeleitet, nicht vom Template-Argument. Und da eine Spezialisierung einen anderen Typ als die primäre Vorlage haben kann, akzeptiert der Compiler sie gerne, auch wenn sie sich unterscheiden.

+0

Interessant, das dazwischen 'int' scheint überflüssig zu sein :-). Wie auch immer, 'template <> auto a = 1;' funktioniert auch! – iammilind

+2

Seien Sie vorsichtig mit 'Auto' hier. Wenn Sie erwarten, dass die Variable den gleichen Typ wie das Template-Argument hat (was nicht unbedingt mit dem Initialisierer übereinstimmt), haben Sie vielleicht eine Überraschung. –

+0

@MikeSeymour Wahr in der Tat, ich werde der Antwort einen Vorbehalt hinzufügen. – Angew

Verwandte Themen