die Verwendung von extern-templates (C++11)
Abbildung 1: Funktion Vorlagen
TemplHeader.h
template<typename T>
void f();
TemplCpp.cpp
template<typename T>
void f(){
//...
}
//explicit instantation
template void f<T>();
Main.cpp
#include "TemplHeader.h"
extern template void f<T>(); //is this correct?
int main() {
f<char>();
return 0;
}
Ist dies die richtige Art und Weise zu verwenden extern template
oder verwende ich dieses Schlüsselwort nur für die Klasse Vorlagen, wie in Abbildung 2?
Abbildung 2: Klassen-templates
TemplHeader.h
template<typename T>
class foo {
T f();
};
TemplCpp.cpp
template<typename T>
void foo<T>::f() {
//...
}
//explicit instantation
template class foo<int>;
Main.cpp
#include "TemplHeader.h"
extern template class foo<int>();
int main() {
foo<int> test;
return 0;
}
Ich weiß, es ist gut, dies alles in einer header-Datei, aber wenn wir instanziieren von templates mit den gleichen Parametern in mehrere Dateien, dann haben wir mehrere gleichen Definitionen und der compiler entfernen Sie alle (außer einem), um Fehler zu vermeiden. Wie verwende ich extern template
? Können wir es verwenden, nur für die Klassen, oder können wir es verwenden, für Funktionen auch?
Auch Abbildung 1 und Abbildung 2 kann erweitert werden, um eine Lösung, wo die Vorlagen sind in einer einzigen header-Datei . In diesem Fall brauchen wir das extern template
Stichwort, damit nicht mehrere gleiche instantations. Dies ist nur für Klassen oder Funktionen zu?
Könnten Sie einige Zeit dauern, zu formulieren, die (eine) Frage klarer? Was stellst du den code für? Ich sehe nicht, eine Frage im Zusammenhang. Auch
extern template class foo<int>();
scheint wie ein Fehler.es stellt so gut auf meinem visual studio 2010, außer die Warnmeldung:Warnung 1 Warnung C4231: Nichtstandard-Erweiterung verwendet : 'extern' vor der Vorlage explizite Instantiierung
Frage ist sehr einfach: wie, und bei der Verwendung von extern-templates Schlüsselwort? (extern-template ist C++0x neue Zukunft btw) Sie sagte: "Auch extern template class foo<int>(); scheint wie ein Fehler." Nein ist es nicht, ich habe die neue C++ - Buch und das Beispiel aus meinem Buch.
dann visual studio ist echt doof.. in der zweiten der Prototyp nicht mit der Umsetzung, und auch wenn ich das beheben, dass er sagt 'erwartet unqualified-id" in der Nähe
()
auf der extern-Linie. sowohl Ihr Buch und visual studio sind falsch, versuchen Sie es mit mehr standard-konformen compiler wie g++ oder clang und Sie werden sehen, das problem.InformationsquelleAutor codekiddy | 2011-11-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie nur verwenden
extern template
um den compiler zu zwingen nicht instanziieren einer Schablone, wenn Sie wissen, die es instanziert, woanders. Es wird verwendet, um die Kompilierung und Objekt-Datei Größe.Beispiel:
Dadurch werden die folgenden Objekt-Dateien:
Wenn beide Dateien miteinander verknüpft werden, eine
void ReallyBigFunction<int>()
verworfen werden, was verschwendet compile-Zeit Objekt und Datei-Größe.Nicht zu verschwenden compile-Zeit und Objekt, Datei-Größe, es ist ein
extern
Schlüsselwort, das macht der compiler nicht kompilieren eine template-Funktion. Sie sollten diese , wenn, und nur wenn Sie wissen es ist in der gleichen binären woanders.Ändern
source2.cpp
:Wird in dem folgenden Objekt-Dateien:
Wenn beides miteinander verbunden sein, das zweite Objekt-Datei wird nur das symbol von der ersten Objekt-Datei. Keine Notwendigkeit zu verwerfen und verschwendet keine compile-Zeit-und Objekt-Datei Größe.
Sollte dies nur innerhalb eines Projektes, wie in Zeiten, wenn Sie eine Vorlage verwenden, wie
vector<int>
mehrere Male, die Sie verwenden solltenextern
in allen, aber eine Quellcode-Datei.Dies gilt auch für Klassen und Funktion, wie man ist, und auch template-member-Funktionen.
die beste Erklärung, die von extern-templates, die ich bisher gelesen habe!
"wenn Sie wissen, verwendet in der gleichen binären woanders.". Das ist weder ausreichend noch erforderlich. Ihr code ist "schlecht ausgebildet, keine Diagnose erforderlich". Sie sind nicht erlaubt zu bauen auf eine implizite Instanziierung eines anderen TU (der compiler darf optimieren Sie Weg, ähnlich wie eine inline-Funktion). Eine explizite Instanziierung bereitgestellt werden muss, in einem anderen TU.
Ich möchte darauf hinweisen, dass diese Antwort wohl falsch, und ich habe gebissen. Zum Glück ist Johannes' Kommentar hatte eine ganze Reihe von Abstimmungen, und ich mehr Aufmerksamkeit, um es dieses mal. Ich kann nur davon ausgehen, dass die überwiegende Mehrheit der Wähler auf diese Frage eigentlich gar nicht implementieren diese Arten von Vorlagen in mehreren compilation-units (wie ich heute)... zumindest für das Geräusch, die einzige todsichere Methode ist, um die template-Definitionen in den header! Gewarnt werden!
könnten Sie etwas näher oder vielleicht eine bessere Antwort? Ich bin mir nicht sicher, ob ich vollständig verstanden Ihre Einwände.
InformationsquelleAutor Dani
Wikipedia hat das beste Beschreibung
Warnung:
nonstandard extension used...
Microsoft VC++ verwendet werden, um eine non-standard version dieses feature bereits einige Jahre (in C++03). Der compiler warnt davor, dass zu verhindern, die Portabilität Probleme mit code, der benötigt zum kompilieren auf anderen Compilern auch.
Betrachten Sie das Beispiel in der verlinkten Seite zu sehen, dass es funktioniert etwa auf die gleiche Weise. Sie können erwarten, dass die Nachricht gehen Weg, um mit zukünftigen Versionen von MSVC, außer natürlich, wenn mit anderen nicht-standard-compiler-Erweiterungen bei der gleichen Zeit.
"... was sagt der compiler nicht zu instanziieren Sie das template in dieser übersetzungseinheit." Ich glaube nicht, dass dies wahr ist. Jede Methode in der Klasse definiert definition zählt als inline, also wenn die STL-Implementierung verwendet inline-Methoden für die
std::vector
(ziemlich sicher, dass alle von Ihnen tun),extern
hat keine Wirkung.Ja, diese Antwort ist irreführend. MSFT doc: "Das extern-Schlüsselwort in der Spezialisierung gilt nur für member-Funktionen definiert, um außerhalb des Körpers der Klasse. Definierten Funktionen innerhalb der Klassendeklaration sind als inline-Funktionen und werden immer instanziiert werden." Alle STL-Klassen in VS (zuletzt überprüft wurde 2017) haben nur inline-Methoden leider.
Das gilt für alle inline-Deklarationen unabhängig davon, wo Sie auftreten, immer @0kcats
Der Verweis auf Wiki mit std::vector Beispiel und eine Referenz auf MSVC in der gleichen Antwort macht man glauben, dass es möglicherweise einige Vorteile in der Verwendung von extern std::vector in MSVC, während es ist nicht so weit. Nicht sicher, ob dies ist die Forderung des Standards, vielleicht andere Compiler haben dasselbe Problem.
InformationsquelleAutor sehe
Das bekannte problem mit den Vorlagen ist der code, den Blähungen, die Folge der Generierung der Klassendefinition in jedem Modul, das ruft die Klasse template Spezialisierung. Um dies zu verhindern, beginnend mit " C++0x, könnte man Sie mit dem Schlüsselwort extern in der Klasse über template-Spezialisierung
#include <MyClass>
extern template class CMyClass<int>;
Ausdrückliche instantion der template-Klasse sollte nur geschehen, in eine einzige übersetzungseinheit, vorzuziehen, die mit einer template-definition (MyClass.cpp)
InformationsquelleAutor damirlj
Wenn Sie verwendet haben, extern für Funktionen vor, genau den gleichen Philosophie folgt für Vorlagen. wenn nicht, gehe zwar extern für einfache Funktionen kann helfen. Auch, möchten Sie vielleicht zu setzen, die extern(s) in einer header-Datei, und schließen Sie die Kopfzeile, wenn Sie es brauchen.
InformationsquelleAutor qqqqq