C, C++/C++ 언어 / / 2024. 10. 23.

[C++] 클래스 템플릿의 특수화( class template specialization )

클래스 템플릿의 특수화

이전 '함수 템플릿의 특수화'에서 얘기했듯이, 템플릿의 특수화는 보편적인 기능을 구현한 템플릿의 정의와는 다른 기능을 수행하기 위한 방법입니다.

 

[C++] 함수 템플릿의 특수화( function template specialization )

포괄적인 기능의 특수화함수 템플릿은 모든 타입의 매개변수에 대하여 같은 기능을 수행하는 함수를 작성하는 도구입니다. [C++] 함수 템플릿 ( function template )에 대한 설명 1함수 템플릿 용도와

codingembers.tistory.com

 

다음 클래스 템플릿은 형식 템플릿 매개변수에 따른 타입의 데이터를 저장하고 출력하는 클래스들을 만들기 위한 템플릿입니다.

#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 };

 

이 내용에 대한 글을 여기에서 볼 수 있습니다.

 

[C++] 클래스 템플릿( class template )에 대한 설명

클래스 템플릿클래스 템플릿은 클래스를 찍어내는 도구입니다.여기서 말하는 클래스는 넓은 의미의 집합체를 의미하고, C++에서 이러한 집합체에는 class, struct 그리고 union이 있습니다. 이 클래

codingembers.tistory.com

 

그렇지만, 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 )

 

 

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유