클래스 템플릿의 특수화
이전 '함수 템플릿의 특수화'에서 얘기했듯이, 템플릿의 특수화는 보편적인 기능을 구현한 템플릿의 정의와는 다른 기능을 수행하기 위한 방법입니다.
다음 클래스 템플릿은 형식 템플릿 매개변수에 따른 타입의 데이터를 저장하고 출력하는 클래스들을 만들기 위한 템플릿입니다.
#include <iostream>
using namespace std;
template < typename T > // 클래스 템플릿
class DataPrinter{
T m_Data;
public:
DataPrinter(T data) : m_Data{data}{};
void print(){
cout << m_Data << endl;
}
};
이 템플릿에서 만들어진 클래스의 멤버 함수 print는 bool 타입의 데이터도 int 타입의 데이터와 같은 방식으로 출력해야 합니다.
int main(){
DataPrinter intData{ 1 };
DataPrinter boolData{ true };
intData.print();
boolData.print();
}
▼출력
1
1
여기서, 위의 main 함수의 DataPrinter intData{ 1 } 의 선언이 좀 이상하다고 느낄 수 있을지 모르겠습니다.
이 문장이 오류를 발생하지 않은 것은, 이 코드를 컴파일한 컴파일러의 버전이 C++ 17 이상이고, 이 컴파일러가 클래스 인수로부터 클래스 템플릿 매개변수를 추론( class template augument deduction, CTAD )했기 때문입니다.
실제, 컴파일러가 추론한 코드는 다음과 같을 것입니다.
DataPrinter<int> intData{ 1 }; // 컴파일러가 추론한 템플릿 매개변수들
DataPrinter<bool> boolData{ true };
이 내용에 대한 글을 여기에서 볼 수 있습니다.
그렇지만, bool 형식의 클래스 템플릿을 특수화하면, 이 템플릿에 속하는 멤버 함수의 기능도 특별하게 구현할 수 있게 됩니다.
// DataPrinter 클래스 템플릿의 특수화
template<>
class DataPrinter<bool>{
bool m_Data;
public:
DataPrinter( bool data) : m_Data{data}{};
void print(); // 멤버 함수 선언
};
// 템플릿 클래스 외부에서 멤버 함수 정의
void DataPrinter<bool>::print(){
cout << boolalpha << m_Data << endl;
}
▼출력
1
true
하지만, print 멤버 함수의 기능 하나를 특별하게 동작하도록 만들기 위해, 클래스 전체를 작성해야 된다는 것은 코드의 낭비처럼 느껴집니다.
다행인 것은, C++은 이러한 문제를 막기 위해서 다음과 같은 방법을 만들었습니다.
template<> // 템플릿으로부터 특수화되었음을 알려줌
void DataPrinter<bool>::print(){
cout << boolalpha << m_Data << endl;
}
위와 같이 선언하면, 컴파일러는 DataPrinter 클래스 템플릿으로부터 DataPrinter<bool> 클래스를 암시적으로 특수화합니다.
그리고, 이 클래스의 멤버 함수 print의 정의를 위의 명시적인 멤버 함수로 대체하는 것입니다.
전체적인 코드를 다시 정리하자면 다음과 같습니다.
template < typename T > // 클래스 템플릿
class DataPrinter{
T m_Data;
public:
DataPrinter(T data) : m_Data{data}{};
void print(){
cout << m_Data << endl;
}
};
template<> // 멤버 함수만 특수화도 가능
void DataPrinter<bool>::print(){
cout << boolalpha << m_Data << endl;
}
int main(){
DataPrinter intData{ 1 };
DataPrinter boolData{ true };
intData.print();
boolData.print();
}
▼출력
1
true
이 글과 관련있는 글들
템플릿의 부분 특수화( partial specialization )
'C, C++ > C++ 언어' 카테고리의 다른 글
[C++] 한정 이름( qualified name ) 사용을 편리하게 하는 using 선언문과 using 지시문 (1) | 2024.10.31 |
---|---|
[C++] 템플릿의 부분 특수화( partial specialization ) (0) | 2024.10.26 |
[C++] 함수 템플릿의 특수화( function template specialization ) (0) | 2024.10.18 |
[C++] 비-형식 템플릿 매개변수( non-type template parameter) (0) | 2024.10.18 |
[C++] 클래스 템플릿( class template )에 대한 설명 (0) | 2024.10.15 |