Facciamo un esempio, diciamo per qualche motivo che vuoi avere una classe template:
//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");
}
Se compili questo codice con Visual Studio, funziona immediatamente. gcc produrrà un errore del linker (se lo stesso file di intestazione viene utilizzato da più file .cpp):
error : multiple definition of `DemoT<int>::test()'; your.o: .../test_template.h:16: first defined here
È possibile spostare l'implementazione nel file .cpp, ma è necessario dichiarare la classe in questo modo -
//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>;
E poi .cpp avrà questo aspetto:
//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");
}
Senza le ultime due righe nel file di intestazione - gcc funzionerà bene, ma Visual Studio produrrà un errore:
error LNK2019: unresolved external symbol "public: void __cdecl DemoT<int>::test(void)" (?test@?$DemoT@H@@QEAAXXZ) referenced in function
La sintassi della classe template è facoltativa nel caso in cui si desideri esporre la funzione tramite l'esportazione .dll, ma questo è applicabile solo per la piattaforma Windows - quindi test_template.h potrebbe apparire così:
//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();
con il file .cpp dell'esempio precedente.
Questo, tuttavia, dà più mal di testa al linker, quindi si consiglia di utilizzare l'esempio precedente se non si esporta la funzione .dll.