다음과 같은 구조체를 정의한다고 가정하자.
struct job
{
char name[40];
double salary{};
int floor{};
}
이러한 구조체 두 개를 만들고 두 구조체의 내용을 교환하려 한다.
원본 템플릿은 다음과 같은 코드를 사용하여 내용을 교환한다.
temp = a;
a = b;
b = temp;
C++에서는 하나의 구조체를 다른 하나의 구조체에 대입할 수 있기 때문에,
Any형이 job 구조체인 경우도 코드는 동작한다.
그러나 salary와 floor 멤버만 교환하고,
name 멤버는 그대로 두고 싶다고 가정하자.
이 경우는, 이제 코드가 달라져야 한다.
그러나 Swap()에 넘겨주는 매개변수는 첫 번째 경우와 같아야한다.
그렇다면 새로운 코드에 템플릿 오버로딩을 사용할 수 없다.
그러나 명시적 특수화(Explicit Specialization)라는
특수화된 함수 정의를, 필요한 코드와 함께 제공할 수 있다.
컴파일러가 함수 호출에 정확히 대응하는 특수화된 정의를 발견하면,
템플릿을 찾기 않고 그 정의를 사용한다.
이러한 특수화 형식은 C++가 발전하면서 계속 변화해 왔다.
3세대 특수화
특수화 방식을 모두 실험한 후, C++98 표준은 이 방식을 다음과 같이 정립하였다.
* 함수 이름이 하나 주어지면, 사용자는 템플릿이 아닌 함수,
템플릿 함수, 명시적 특수화 템플릿 함수를 가질 수 있다.
또한, 이 모든 것들의 오버로딩 버전도 가질 수 있다.
* 명시적 특수화를 위한 원형과 정의 앞에 template <>가 와야한다.
그리고 특수형의 이름을 서술해야 한다.
* 특수화는 템플릿을 무시하고, 템플릿이 아닌 함수는 특수화와 템플릿 둘 다 무시한다.
다음은 job형 구조체를 교환하는 세 가지 형식의 함수 원형이다.
// 템플릿이 아닌 함수 원형
void Swap(job &, job &);
// 템플릿 원형
template <typename T>
void Swap(T &, T &);
// job형을 위한 명시적 특수화
template <> void Swap<job>(job&, job&);
------------------------------------------------------------------------------
template <Class T>
void Swap(T &, T &);
// job 형에 대한 명시적 특수화
template <> void Swap<job>(job&, job&);
int main()
{
double u, v;
...
Swap(u, v); // 템플릿 사용
job a, b;
...
Swap(a,b); // void Swap<job>(job&, job &) 사용
}
이것이 job을 위한 특수화라는 것을 함수 매개변수의 데이터형이 알려주기에,
Swap에 있는 은 생략할 수 있다. 그러므로 원형도 다음처럼 간단히 나타낼 수 있다.
template<> void Swap(job&, job&);
출처 : C++ 기초 플러스 6판 / 성안당