C++11: Explizite Instanziierung Deklaration vs. explizite Instantiierung definition
Was ist der Unterschied zwischen C++03 die explizite template-Instantiierung definition und C++11, die explizite template-Instantiierung Erklärung ?
Was ich meine ist, warum die Instanziierung definition ist nicht genug, um zu verhindern, dass der compiler generiert die Umsetzung für andere Arten ? Was ist falsch in dem unten angeführten Beispiel: Stell dir vor, ich teilte die template-Deklaration und-definition in zwei separate Dateien:
A. h
#pragma once
template<typename T>
class A
{
public:
A(T t);
private:
T _t;
};
A.cpp
#include "A.h"
template<typename T>
A<T>::A(T t) : _t(t) {}
template class A<int>; //explicit instantiation
main.cpp
#include "A.h"
int main()
{
A<int> a(5); //fine, compiler generates header file,
//linker links with implementation from A.cpp file
//A<float> b(3.14f); //linker error, as expected
}
Gibt es eine Zusammenstellung zusätzlicher Verarbeitungsaufwand im Beispiel oben? Wenn ich das richtig verstehe, in diesem Fall mit expliziter Instanziierung definition in eine separate *.cpp-Datei (zusammen mit der template-Umsetzung) mache ich den compiler nicht implizit instanziieren Sie das template mit anderen Arten. Als solche, weshalb es eine separate syntax für explizite Instanziierung Deklaration ?
Wie kann explizite Instantiierung Erklärung Beschleunigung der Kompilierung, ob ich SCHON versteckt, die Umsetzung in A.cpp Datei explizite Instanziierung definition, und verhindert compiler generiert Körpers für andere Arten. Ist die "explizite Instanziierung Deklaration" irgendwie verwandt "explizite Instantiierung definition", meine ich, sollte ich beide, oder sind das völlig separate Funktionen (z.B. explizite Instanziierung Deklaration kann nur verwendet werden, wenn die explizite Instanziierung definition nicht verwendet wurde) ?
Denke ich Recht, dass die explizite Instantiierung definition ist nur zum Fehler auslösen, wenn kein anderer übersetzungseinheit instantiiert die Vorlage mit gegebenen Typ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn man eine explizite Instanziierung definition in der Datei
A.cpp
, wie ist der compiler, der soll wissen, dass es da beim kompilierenmain.cpp
? Die Antwort ist, dass dies nicht der Fall, so wäre es immer noch instanziieren der templates verwendet, inmain.cpp
, und in Ihrem Fall mit der expliziten Instanziierung definition ist sinnlos und hilft nicht.Einer Erklärung eine explizite Instanziierung sagt der compiler "kümmern Sie sich nicht um die Instanziierung dieser Vorlage, das werde ich tun, mich irgendwo anders im Programm", und die definition ist das, was erfüllt das Versprechen.
Die explizite Instantiierung definiert werden muss, genau einmal, in nur einer Datei, aber es kann erklärt werden, die mehrfach in verschiedenen Dateien. Das ist nichts einzigartiges zu templates in C und C++ die gleichen Regeln gelten auch für (nicht-inline) - Funktionen: können Sie erklären Ihnen mehrmals in verschiedenen Dateien (in der Regel, indem Sie die Deklaration in der header), und bestimmen Sie dann die Funktion genau einmal in einer Datei.
Also, um dein Beispiel richtig funktioniert, sollten Sie das hinzufügen einer Erklärung in
A.h
:A.cpp
bedeutet, dass der compiler muss nur generieren die Klasse nur einmal, sondern zu nutzen, die dem compiler hat, um zu wissen, die explizite Instantiierung vorhanden ist beim kompilierenB.cpp
undmain.cpp
, das ist, warum erklären Sie es. Aber wenn Sie nicht verstehen, die nutzen dann eben nicht die explizite instantiierungen, niemand zwingt dich, Sie zu benutzen.A<int>
imB.cpp
und strahlt eine Undefinierte Referenz auf die FunktionA<int>::A(int)
. Der linker findet die definition im link-Zeit. Wenn Sie eine explizite Instanziierung definition inA.h
dann der compiler nicht instanziiertA<int>
beim kompilierenB.cpp
Hier eine Erklärung in
main.cpp
oderA.h
verhindert hättemain.cpp
von der Erzeugung (zur compile-Zeit) code basierend auf dem, was Teile der Vorlage sind sichtbar, nämlich eineA.h
-basierteA<int>
Spezialisierung:Jedoch die
main.cpp
code nicht braucht, um zu wissen, dassA<int>::A(int)
vorhanden ist, das heißt, es muss führen Sie eine Art der Instanziierung, um zu lernen, alleA<int>
Mitglieder, das ist genau das, was einA.h
-basierteA<int>
Instanziierung tun würde.Also das ist ja nicht genau klar, wie es ist hier nützlich - allerdings unterliegen pro-compiler/platform profiling.