Frage

Ich bin mit Code :: Blocks mein Projekt zu bauen, die drei Dateien enthält: main.cpp, TimeSeries.cpp, TimeSeries.h. TimeSeries.h liefert Erklärungen für die TimeSeries Klasse wie folgt:

template<class XType, class YType> class TimeSeries {
public:
    TimeSeries(void);
    ~TimeSeries(void);
};

Dann TimeSeries.cpp enthält: #include "TimeSeries.h"

template<class XType, class YType>
TimeSeries<XType, YType>::TimeSeries(void) {
}

template<class XType, class YType>
TimeSeries<XType, YType>::~TimeSeries(void) {
}

Und schließlich main.cpp enthält

#include "TimeSeries.h"
typedef TimeSeries<float, float> FTimeSeries;

int main(int argc, char** argv) {
    FTimeSeries input_data;
    return 0;
}

Wenn Sie mit C Aufbau :: B, ich die folgende Fehlermeldung erhalten:

undefined reference to `TimeSeries<float, float>::TimeSeries()'

Was kann ich tun?

Danke,
CFP.

War es hilfreich?

Lösung

Der Grund für die Spaltung Code in Kopf- und Source-Dateien ist so, dass die Erklärung und die Umsetzung getrennt sind. Der Compiler kann die Quelle-Datei (Kompilationseinheit) in eine Objektdatei übersetzen, und andere Kompilation-Einheiten, die die Klassen und Funktionen nur gehören die Kopfdatei und verknüpfen die Objektdatei verwendet werden sollen. Auf diese Weise hat der Code nur einmal erstellt werden und können durch die Verknüpfung sie wiederverwendet werden.

Das Problem mit Vorlagen ist, dass, solange es keine Parameter für diese zur Verfügung gestellt, der Compiler kann sie nicht kompilieren. Die gleiche Vorlage mit unterschiedlichen Parametern instanziiert ergeben sich unterschiedliche Typen. std::vector<int> und std::vector<float> sind aus der Sicht Compiler, nicht in irgendeiner Weise im Zusammenhang. Wegen dieses Template-Klassen müssen in der Regel vollständig in einer Header-Datei befinden, weil, wenn die Vorlage verwendet wird, der Compiler die vollständige Definition benötigt, um die Klasse abhängig von den Parametern zu erzeugen.

Wie @Gabriel Schreiber weist darauf hin, in seiner Antwort , können Sie sagen, der Compiler, dass er die Vorlage mit einem bestimmten Satz von Parametern zusammenstellen soll, dass für andere Kompilierungseinheiten machte nur durch die Verknüpfung. Allerdings bedeutet dies nicht die Vorlage für andere Parametersätze zur Verfügung stellen.

Andere Tipps

Grundsätzlich sind alle Templat-Code sollte in einem Header definiert werden, sonst wird es nicht, da nichts Anwendungen gebaut werden, in der kompilierten Einheit.

Jede CPP-Datei wird als separate Einheit zusammengestellt und damit und Destruktor nicht kompilieren. Der Compiler hat keine Möglichkeit zu wissen, was Art von Template-Argumente Sie in main.cpp verwenden, wenn es kompiliert TimeSeries.cpp.

Sie müssen dies in Ihrer CPP-Datei hinzufügen (unter den Definitionen):

template class TimeSeries<float, float>;

Wenn der Compiler kompiliert TimeSeries.cpp es nicht weiß, welche für die Arten der Vorlage notwendig ist, weil sie in einer anderen Quelldatei verwendet wird. Sie müssen explizit den Compiler sagen.

Lesen Sie mehr über Explizite Template Instanziierung in Ihrer Kopie der Stroustrup oder im Internet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top