Wenn wir ein Beispiel betrachten, sagen wir für irgendeinen Grund, den Sie eine Template-Klasse haben wollen:
//test_template.h:
#pragma once
#include
template
class DemoT
{
public:
void test()
{
printf("ok\n");
}
};
template <>
void DemoT::test()
{
printf("int test (int)\n");
}
template <>
void DemoT::test()
{
printf("int test (bool)\n");
}
Wenn Sie diesen Code mit Visual Studio kompilieren, funktioniert es direkt. gcc wird einen Linkerfehler produzieren (wenn dieselbe Header-Datei aus mehreren .cpp-Dateien verwendet wird):
Fehler: Mehrfache Definition von 'DemoT::test()'; your.o: .../test_template.h:16: bereits hier definiert
Es ist möglich, die Implementierung in eine .cpp-Datei zu verschieben, aber dann müssen Sie die Klasse so deklarieren -
//test_template.h:
#pragma once
#include
template
class DemoT
{
public:
void test()
{
printf("ok\n");
}
};
template <>
void DemoT::test();
template <>
void DemoT::test();
// Instanziierung parametrisierter Template-Klassen, die Implementierung liegt auf der .cpp-Seite.
template class DemoT;
template class DemoT;
Und dann wird die .cpp-Datei so aussehen:
//test_template.cpp:
#include "test_template.h"
template <>
void DemoT::test()
{
printf("int test (int)\n");
}
template <>
void DemoT::test()
{
printf("int test (bool)\n");
}
Ohne die letzten beiden Zeilen in der Header-Datei - funktioniert gcc problemlos, aber Visual Studio wird einen Fehler produzieren:
Fehler LNK2019: nicht aufgelöstes externes Symbol "public: void __cdecl DemoT::test(void)" (?test@?$DemoT@H@@QEAAXXZ) in Funktion referenziert
Die Syntax der template class ist optional, falls Sie die Funktion über den .dll-Export freigeben wollen, aber das gilt nur für das Windows-System - daher könnte test_template.h so aussehen:
//test_template.h:
#pragma once
#include
template
class DemoT
{
public:
void test()
{
printf("ok\n");
}
};
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif
template <>
void DLL_EXPORT DemoT::test();
template <>
void DLL_EXPORT DemoT::test();
mit einer .cpp-Datei aus dem vorherigen Beispiel.
Dies verursacht jedoch mehr Kopfschmerzen für den Linker, also wird empfohlen, das vorherige Beispiel zu verwenden, wenn Sie keine .dll-Funktion exportieren.
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 :p0 Stimmen
Ich habe etwas Ähnliches mit GCC gemacht, aber ich forsche immer noch.
27 Stimmen
Dies ist kein "Hack", sondern eine Vorwärtsdeklaration. Dies hat seinen Platz im Standard der Sprache; daher ist es in jedem standardkonformen Compiler erlaubt.
1 Stimmen
Was ist, wenn Sie Dutzende von Methoden haben? Können Sie einfach
template class foo;template class foo;
am Ende der .cpp-Datei machen?0 Stimmen
Verwandt: stackoverflow.com/questions/495021/…
0 Stimmen
Bitte korrigiere mich, wenn ich falsch liege, @AhmetIpkin. Ich glaube, das nennt man Template-Spezialisierung.
0 Stimmen
Ich mag es wirklich, Vorlageninstanzdefinitionen in der cpp zu speichern, weil es allen mitteilt, welche Implementierungen verwendet werden.