Betrachten Sie die folgenden Header- und Quelldateien:
%Vor% %Vor% %Vor% Ich bekomme einen Verknüpfungsfehler bezüglich der foo<float>
Spezialisierung. Wenn ich die Definition der Spezialisierung in die Header-Datei lege, dann funktioniert alles wie erwartet.
Ich dachte mir, dass der Grund dafür sein könnte, dass die Methode nicht explizit instanziiert wird (obwohl die vollständige Spezialisierung von template class
keine explizite Instanziierung für eine korrekte Verknüpfung benötigt). Wenn ich versuche, die Methode explizit zu instanziieren, erhalte ich folgende Fehlermeldung:
Fehler C3416: 'MyClass :: foo': eine explizite Spezialisierung darf nicht explizit instanziiert werden
Die Fragen lauten also:
cpp
Datei zu definieren und richtig zu verlinken? Obwohl die Antwort von WhozCraig (jetzt gelöscht) den richtigen Code zur Lösung Ihres Problems enthält, finden Sie hier einige direkte Antworten auf Ihre Fragen, einschließlich der Kommentare zu Ihrem Code:
foo<int>()
und foo<float>()
sind explizite Spezialisierungen einer Mitgliedervorlage. Diese dürfen nicht innerhalb der Definition der Klasse erscheinen, zu der sie gehören. Der Standard sagt:
(§14.7.3 / 3) [...] Die Definition einer Klassen- oder Klassenvorlage muss vor der Deklaration einer expliziten Spezialisierung für eine Mitgliedervorlage der Klassen- oder Klassenvorlage stehen. [...]
Sie müssen sie also nach der Klassendefinition einfügen.
Im Fall von foo<int>
, das vollständig in der Header-Datei definiert ist, bedeutet dies, dass Sie das Wort inline
vor der Definition einfügen müssen; Andernfalls werden Sie Probleme mit dem Linker bekommen, wenn die Headerdatei in mehr als einer Übersetzungseinheit enthalten ist.
Die Spezialisierung für foo<float>()
wird in einer separaten Datei definiert, die später mit main.cpp
verknüpft wird. Dies ist möglich, erfordert aber, dass eine Deklaration in der Header-Datei angegeben wird (Sie tun dies bereits, aber Sie müssen dies außerhalb der Klassendefinition tun):
Dies ist wegen einer anderen Aussage im Standard erforderlich:
(§14.7.3 / 6) Wenn eine Vorlage, eine Mitgliedervorlage oder ein Mitglied einer Klassenvorlage explizit spezialisiert ist, muss diese Spezialisierung vor der ersten Verwendung dieser Spezialisierung deklariert werden, damit eine implizite Instantiierung stattfinden kann in jeder Übersetzungseinheit, in der eine solche Verwendung stattfindet; keine Diagnose ist erforderlich. [...]
Da alle Spezialisierungen explizit sind (d. h. vollständige Spezialisierungen, um Ihr Wort zu verwenden), sind keine expliziten Instanziierungen erforderlich, aber sie sind möglich (§14.7.2). Sie würden sie am Ende der CPP-Datei platzieren, und die Syntax wäre:
%Vor%Auch dies ist nur für Typen nützlich, die nicht eigene explizite Spezialisierungen haben.
Der korrekte Code für die Header- und Implementierungsdatei sieht daher so aus:
.h-Datei:
%Vor%.cpp:
%Vor%