Nehmen wir ein Beispiel, aus irgendeinem Grund möchten Sie eine Vorlagenklasse haben:
//test_template.h:
#pragma once
#include <cstdio>
template <class T>
class DemoT
{
public:
void test()
{
printf("ok\n");
}
};
template <>
void DemoT<int>::test()
{
printf("int test (int)\n");
}
template <>
void DemoT<bool>::test()
{
printf("int test (bool)\n");
}
Wenn Sie diesen Code mit Visual Studio kompilieren, funktioniert er sofort. gcc erzeugt einen Linkerfehler (wenn dieselbe Header-Datei aus mehreren CPP-Dateien verwendet wird):
error : multiple definition of `DemoT<int>::test()'; your.o: .../test_template.h:16: first defined here
Es ist möglich, die Implementierung in eine CPP-Datei zu verschieben, aber dann müssen Sie die Klasse wie folgt deklarieren:
//test_template.h:
#pragma once
#include <cstdio>
template <class T>
class DemoT
{
public:
void test()
{
printf("ok\n");
}
};
template <>
void DemoT<int>::test();
template <>
void DemoT<bool>::test();
// Instantiate parametrized template classes, implementation resides on .cpp side.
template class DemoT<bool>;
template class DemoT<int>;
Und dann sieht .cpp so aus:
//test_template.cpp:
#include "test_template.h"
template <>
void DemoT<int>::test()
{
printf("int test (int)\n");
}
template <>
void DemoT<bool>::test()
{
printf("int test (bool)\n");
}
Ohne zwei letzte Zeilen in der Header-Datei funktioniert gcc einwandfrei, aber Visual Studio erzeugt einen Fehler:
error LNK2019: unresolved external symbol "public: void __cdecl DemoT<int>::test(void)" (?test@?$DemoT@H@@QEAAXXZ) referenced in function
Die Syntax der Vorlagenklasse ist optional, wenn Sie die Funktion über den DLL-Export verfügbar machen möchten. Dies gilt jedoch nur für die Windows-Plattform. Daher könnte test_template.h folgendermaßen aussehen:
//test_template.h:
#pragma once
#include <cstdio>
template <class T>
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<int>::test();
template <>
void DLL_EXPORT DemoT<bool>::test();
mit .cpp-Datei aus dem vorherigen Beispiel.
Dies bereitet dem Linker jedoch mehr Kopfschmerzen. Es wird daher empfohlen, das vorherige Beispiel zu verwenden, wenn Sie die DLL-Funktion nicht exportieren.