Prenons un exemple, disons pour une raison quelconque que vous voulez avoir une classe de modèle:
//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");
}
Si vous compilez ce code avec Visual Studio - cela fonctionne immédiatement. gcc produira une erreur de l'éditeur de liens (si le même fichier d'en-tête est utilisé à partir de plusieurs fichiers .cpp):
error : multiple definition of `DemoT<int>::test()'; your.o: .../test_template.h:16: first defined here
Il est possible de déplacer l'implémentation vers un fichier .cpp, mais vous devez ensuite déclarer une classe comme celle-ci -
//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>;
Et puis .cpp ressemblera à ceci:
//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");
}
Sans deux dernières lignes dans le fichier d'en-tête - gcc fonctionnera bien, mais Visual studio produira une erreur:
error LNK2019: unresolved external symbol "public: void __cdecl DemoT<int>::test(void)" (?test@?$DemoT@H@@QEAAXXZ) referenced in function
la syntaxe de classe de modèle est facultative dans le cas si vous souhaitez exposer la fonction via l'exportation .dll, mais cela ne s'applique qu'à la plate-forme Windows - donc test_template.h pourrait ressembler à ceci:
//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();
avec le fichier .cpp de l'exemple précédent.
Cependant, cela donne plus de maux de tête au lieur, il est donc recommandé d'utiliser l'exemple précédent si vous n'exportez pas la fonction .dll.