Tomemos un ejemplo, digamos por alguna razón que desea tener una clase de plantilla:
//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 compila este código con Visual Studio, funciona de forma inmediata. gcc producirá un error de enlazador (si se usa el mismo archivo de encabezado de múltiples archivos .cpp):
error : multiple definition of `DemoT<int>::test()'; your.o: .../test_template.h:16: first defined here
Es posible mover la implementación al archivo .cpp, pero luego debe declarar una clase como esta:
//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>;
Y luego .cpp se verá así:
//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");
}
Sin dos últimas líneas en el archivo de encabezado, gcc funcionará bien, pero Visual Studio producirá un error:
error LNK2019: unresolved external symbol "public: void __cdecl DemoT<int>::test(void)" (?test@?$DemoT@H@@QEAAXXZ) referenced in function
la sintaxis de clase de plantilla es opcional en caso de que desee exponer la función a través de la exportación .dll, pero esto es aplicable solo para la plataforma de Windows, por lo que test_template.h podría verse así:
//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 el archivo .cpp del ejemplo anterior.
Sin embargo, esto le da más dolor de cabeza al enlazador, por lo que se recomienda usar el ejemplo anterior si no exporta la función .dll.