让我们举一个例子,假设出于某种原因你想要一个模板类:
//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");
}
如果你用Visual Studio编译这段代码,它可以开箱即用。
GCC将产生链接器错误(如果从多个.cpp文件中使用相同的头文件):
error : multiple definition of `DemoT<int>::test()'; your.o: .../test_template.h:16: first defined here
可以将实现移动到.cpp文件,但随后需要像这样声明类-
//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>;
然后。cpp看起来是这样的:
//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");
}
如果头文件中没有最后两行- gcc可以正常工作,但是Visual studio会产生一个错误:
error LNK2019: unresolved external symbol "public: void __cdecl DemoT<int>::test(void)" (?test@?$DemoT@H@@QEAAXXZ) referenced in function
如果你想通过.dll导出来公开函数,模板类语法是可选的,但这只适用于Windows平台-所以test_template.h可以像这样:
//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();
使用前面示例中的.cpp文件。
然而,这给链接器带来了更多的头痛,所以如果你不导出.dll函数,建议使用前面的例子。