Warum sollten die Implementierung und die Deklaration einer Template-Klasse in derselben Header-Datei stehen? [duplicate]

Lesezeit: 4 Minuten

Warum sollten die Implementierung und die Deklaration einer Template Klasse in
Haiyuan Zhang

Warum sollten die Implementierung und die Deklaration einer Template-Klasse in derselben Header-Datei stehen? Kann das jemand von euch anhand eines Beispiels erklären?

  • sie müssen innerhalb derselben Kompilationseinheit sichtbar sein. Sie können sich in verschiedenen Dateien befinden, wenn beide enthalten sind

    – Irgendein Korn

    20. September 2010 um 6:31 Uhr

  • Tatsächlich ist es nicht ungewöhnlich, Deklaration und Implementierung in zwei Dateien aufzuteilen. Der Header enthält normalerweise die Implementierungsdatei.

    – MSalter

    20. September 2010 um 7:05 Uhr

  • @MSalters: Was bei Vorlagenklassen problematisch ist, darum geht es in dieser Frage. Ich wünschte, ich könnte Kommentare ablehnen.

    – Leichtigkeitsrennen im Orbit

    3. März 2011 um 12:23 Uhr

  • @Tomalak Geret’kal: Überhaupt nicht. Sie haben eine Deklaration in “Foo.h” und Definitionen in “Foo.impl”. Die letzte Zeile von “foo.h” vor dem Header Guard ist “#include “Foo.impl”. Nachdem der Präprozessor gelaufen ist, gibt es keinen Unterschied mehr. Sie können in verschiedenen Dateien sein, aber sie enden in derselben Übersetzungseinheit (s) – und darauf kommt es Compilern an.

    – MSalter

    3. März 2011 um 12:26 Uhr

  • @MSalters: Richtig, ok. Eigentlich habe ich es geschafft, Ihren letzten Satz komplett rückwärts zu lesen. 🙂

    – Leichtigkeitsrennen im Orbit

    3. März 2011 um 12:28 Uhr


Der Compiler muss Zugriff auf die gesamte Vorlagendefinition haben (nicht nur auf die Signatur), um Code für jede Instanziierung der Vorlage zu generieren, daher müssen Sie die Definitionen der Funktionen in Ihren Header verschieben.

Weitere Einzelheiten finden Sie unter Das Inklusionsmodell.

  • Nein, tust du nicht. Sie könnten die Definition manuell in jede TU schreiben, aber natürlich soll die Header-Konvention Ihnen helfen, solchen Unsinn zu vermeiden. 🙂

    – Leichtigkeitsrennen im Orbit

    4. September 2011 um 13:57 Uhr


  • @LightnessRacesinOrbit darf ich fragen, was TU ist?

    – Athos

    1. Januar 2015 um 9:03 Uhr

  • @athos en.wikipedia.org/wiki/Translation_unit_%28programming%29

    – Leichtigkeitsrennen im Orbit

    1. Januar 2015 um 14:31 Uhr

  • @LightnessRacesinOrbit hat es verstanden, danke!

    – Athos

    1. Januar 2015 um 15:12 Uhr

Die Definition eines Klassen-Templates und die Implementierung seiner Member-Funktionen muss für jeden Ort sichtbar sein, der es mit einem eindeutigen Typ instanziiert. dh um zu instanziieren myTemplate<int> Sie müssen die vollständige Definition und Implementierung von sehen myTemplate.

Der einfachste Weg, dies zu tun, besteht darin, die Definition der Vorlage und ihrer Member-Funktionen in denselben Header zu setzen, aber es gibt auch andere Möglichkeiten. Beispielsweise könnten Sie die Implementierungen von Memberfunktionen in eine separate Datei einfügen, die separat eingeschlossen wurde. Sie können es dann aus dem ersten Header einfügen oder die Implementierungsdatei nur dort einfügen, wo Sie sie benötigen.

Eine Vorgehensweise besteht beispielsweise darin, explizit eine Vorlage für einen bestimmten Satz von Parametern in einer .cpp-Datei zu instanziieren und diese Instanziierungen zu deklarieren extern in der Kopfzeile. Auf diese Weise können diese Instanziierungen in anderen Quelldateien verwendet werden, ohne dass die Implementierung der Vorlagenelementfunktionen sichtbar sein muss. Wenn Sie jedoch die Implementierungsdatei nicht einschließen, können Sie keine anderen Sätze von Vorlagenparametern verwenden.

dh wenn Sie haben myTemplate<int> und myTemplate<std::string> definiert als extern dann kannst du sie gut verwenden, aber wenn myTemplate<double> ist nicht definiert extern dann können Sie das nicht ohne die Implementierung verwenden.

Das müssen sie nicht.

Notwendig ist, dass die Template-Definition zum Zeitpunkt der Instanziierung (wo sie verwendet wird) sichtbar ist, damit der Compiler an dieser Stelle die Klasse/Funktion aus dem Template ableiten kann.

Es ist jedoch sehr üblich, zwei Header-Dateien für Template-Klassen zu verwenden:

// foo_fwd.hpp
template <typename T, typename U> struct Foo;

// foo.hpp
#include "foo_fwd.hpp"

template <typename T, typename U> struct Foo { typedef std::pair<T,U> type; };

Dies ermöglicht es denjenigen, die nicht die vollständige Vorlagendefinition benötigen, einen etwas leichteren Header einzufügen, zum Beispiel:

//is_foo.hpp
#include <boost/mpl/bool.hpp>
#include "foo_fwd.hpp"

template <typename Z>
struct is_foo: boost::mpl::false_ {};

template <typename T, typename U>
struct is_foo< Foo<T,U> >: boost::mpl::true_ {};

was die Kompilierungszeit etwas beschleunigen kann.

Warum sollten die Implementierung und die Deklaration einer Template Klasse in
liaK

Im Fall einer normalen Klasse reicht die Deklaration gerade für die Kompilierung, und die entsprechenden Definitionen werden es sein verknüpft.

Bei Templates benötigt der Compiler auch die Definition dazu generieren der Code.

Der Unterschied wird besser in der erklärt Häufig gestellte Fragen zu C++.

995980cookie-checkWarum sollten die Implementierung und die Deklaration einer Template-Klasse in derselben Header-Datei stehen? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy