한 가지 예를 들어 보겠습니다. 어떤 이유로 템플릿 클래스를 원한다고 가정 해 봅시다.
//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 함수를 내 보내지 않으면 이전 예제를 사용하는 것이 좋습니다.