709 Stimmen

Speichern von C++-Vorlagendefinitionen für Funktionen in einer .CPP-Datei

Ich habe einige Vorlagen-Code, der ich lieber in einer CPP-Datei gespeichert haben möchte, anstatt inline im Header. Ich weiß, dass dies möglich ist, solange man weiß, welche Vorlagentypen verwendet werden. Zum Beispiel:

.h Datei

class foo
{
public:
    template 
    void do(const T& t);
};

.cpp Datei

template 
void foo::do(const T& t)
{
    // Etwas mit t machen
}

template void foo::do(const int&);
template void foo::do(const std::string&);

Beachten Sie die letzten beiden Zeilen - die foo::do-Vorlagenfunktion wird nur mit ints und std::strings verwendet, so dass diese Definitionen bedeuten, dass die App verlinkt wird.

Meine Frage ist - ist das ein hässlicher Hack oder wird es mit anderen Compilern/Linkern funktionieren? Ich benutze diesen Code derzeit nur mit VS2008, möchte aber auf andere Umgebungen portieren.

30 Stimmen

Ich hatte keine Ahnung, dass dies möglich war - ein interessanter Trick! Es hätte bei einigen aktuellen Aufgaben erheblich geholfen, dies zu wissen - Prost!

107 Stimmen

Das Ding, das mich verwirrt, ist die Verwendung von do als Kennung :p

0 Stimmen

Ich habe etwas Ähnliches mit GCC gemacht, aber ich forsche immer noch.

2voto

KronuZ Punkte 389

Keine der obigen Lösungen hat für mich funktioniert, daher hier ist, wie ich es gelöst habe, meine Klasse hat nur eine Vorlage-Methode.

.h

class Model
{
    template 
    void build(T* b, uint32_t number);
};

.cpp

#include "Model.h"
template 
void Model::build(T* b, uint32_t number)
{
    //Implementierung
}

void TemporaryFunction()
{
    Model m;
    m.build(new B1(),1);
    m.build(new B2(), 1);
    m.build(new B3(), 1);
}

Dies vermeidet Linkerfehler und es ist nicht notwendig, TemporaryFunction überhaupt aufzurufen.

1 Stimmen

Deine Antwort ist die gleiche wie die Frage und funktioniert nicht!

1 Stimmen

Down voted, aber dieser Code kompiliert nicht und funktioniert nicht, wenn Sie tatsächlich versuchen, die Header-Datei in einer anderen Quelldatei einzuschließen, um diese Vorlagenklasse zu verwenden. Sie erhalten ungelöste Symbol-Linkerfehler.

1voto

Didii Punkte 1065

Zeit für ein Update! Erstellen Sie eine Inline- (.inl oder wahrscheinlich eine andere) Datei und kopieren Sie einfach alle Ihre Definitionen hinein. Vergewissern Sie sich, dass Sie die Vorlage über jeder Funktion hinzufügen (template ). Anstatt die Header-Datei in der Inline-Datei einzuschließen, machen Sie das Gegenteil. Schließen Sie die Inline-Datei nach der Deklaration Ihrer Klasse ein (#include "file.inl").

Ich weiß nicht wirklich, warum das niemand erwähnt hat. Ich sehe keine unmittelbaren Nachteile.

29 Stimmen

Die unmittelbaren Nachteile bestehen darin, dass es im Wesentlichen dasselbe ist wie die direkte Definition der Template-Funktionen im Header. Sobald du #include "file.inl" machst, wird der Präprozessor den Inhalt von file.inl direkt in den Header einfügen. Aus welchem Grund auch immer du vermeiden wolltest, dass die Implementierung im Header landet, diese Lösung löst das Problem nicht.

5 Stimmen

und bedeutet, dass du dich technisch unnötig mit der Aufgabe belastest, den langwierigen, verwirrenden Boilerplate zu schreiben, den out-of-line template Definitionen benötigen. Ich verstehe, warum Menschen das tun wollen - um die größtmögliche Parität mit nicht-template Deklarationen/Definitionen zu erreichen, um die Schnittstellendeklaration ordentlich aussehen zu lassen, usw. - aber es ist nicht immer den Aufwand wert. Es geht darum, die Kompromisse auf beiden Seiten abzuwägen und das geringste Übel auszuwählen. ... bis namespace class eine Sache wird :O [Bitte sei eine Sache]

2 Stimmen

@Andrew Es scheint in den Rohren des Ausschusses stecken geblieben zu sein, obwohl ich glaube, dass ich gesehen habe, wie jemand sagte, dass das nicht beabsichtigt war. Ich wünschte, es hätte es in C++17 geschafft. Vielleicht im nächsten Jahrzehnt.

0voto

Benoît Punkte 16390

Es ist nichts falsch an dem Beispiel, das du gegeben hast. Aber ich muss sagen, ich glaube, es ist nicht effizient, Funktionsdefinitionen in einer cpp-Datei zu speichern. Ich verstehe nur die Notwendigkeit, die Deklaration und Definition der Funktion zu trennen.

Wenn es zusammen mit expliziter Klasseninstanziierung verwendet wird, kann dir die Boost Concept Check Library (BCCL) helfen, Template-Funktionscode in cpp-Dateien zu generieren.

10 Stimmen

Was ist daran ineffizient?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X