문과 코린이의, [C. C++] 기록/C++ 이론

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿의 특수화(Class Template Specialization) (클래스 템플릿 특수화, 클래스 템플릿의 부분 특수화)

벼리네 2021. 6. 30. 14:21
반응형

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿의 특수화(Class Template Specialization) (클래스 템플릿 특수화, 클래스 템플릿의 부분 특수화)

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿의 특수화(Class Template Specialization) 

(클래스 템플릿 특수화, 클래스 템플릿의 부분 특수화)


[ 클래스 템플릿에 대한 이전 포스팅 ]

2021.06.29 - [문과 코린이의, [C. C++] 기록/C++ 이론] - [문과 코린이의 IT 기록장] C,C++ - 템플릿(Template)에 대한 이해와 함수 템플릿 (함수를 대상으로 템플릿 이해하기, 함수 템플릿과 템플릿 함수, 둘 이상의 형(Type)에 대해 템플릿 선언하기, 함수 ..

 

[문과 코린이의 IT 기록장] C,C++ - 템플릿(Template)에 대한 이해와 함수 템플릿 (함수를 대상으로 템

[문과 코린이의 IT 기록장] C,C++ - 템플릿(Template)에 대한 이해와 함수 템플릿 (함수를 대상으로 템플릿 이해하기, 함수 템플릿과 템플릿 함수, 둘 이상의 형(Type)에 대해 템플릿 

vansoft1215.tistory.com

2021.06.29 - [문과 코린이의, [C. C++] 기록/C++ 이론] - [문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿의 선언과 정의의 분리, 배열 클래스의 템플릿화)

 

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (클래스 템플릿의 정의, 클래스 템플릿의 선언과 정의의 분리, 배열 클래스의 템플릿화) 1. 클래스 템플릿의 정의 [문과

vansoft1215.tistory.com

2021.06.30 - [문과 코린이의, [C. C++] 기록/C++ 이론] - [문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (Point 클래스 템플릿과 배열 클래스 템플릿, 특정 템플릿 클래스의 객체를 인자로 받는 일반함수의 정의와, friend 선언)

 

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (Point 클래스 템플릿과 배열 클래스 템

[문과 코린이의 IT 기록장] C++ - 클래스 템플릿(Class Template) (Point 클래스 템플릿과 배열 클래스 템플릿, 특정 템플릿 클래스의 객체를 인자로 받는 일반함수의 정의와, friend 선..

vansoft1215.tistory.com

 


1. 클래스 템플릿 특수화

- 함수 템플릿을 특수화하는 이유 : 특정 자료형에 대해, 구분이 되는 다른 행동을 보이기 위해서

- 클래스 템플릿을 특수화하는 이유 : 특정 자료형을 기반으로 생성된 객체에 대해, 구분이 되는 다른 행동양식을 적용하기 위해서

 * 즉 클래스 템플릿을 특수화하면, 템플릿을 구성하는 맴버함수의 일부 또는 전부를 다르게 행동하도록 정의할 수 있음

 

ex 1 ) 클래스 템플릿

template <typename T>
class SoSimple
{
public:
	T SimpleFunc(T num) { ... }
}

 

ex 2 ) int형에 대해 특수화된 템플릿 클래스

template<>
class SoSimple<int>
{
public:
	int SimpleFunc(int num){ ... }
}

이와 같이 int형에 대해 특수화가 된 이후 아래와 같이 객체생성을 할 경우, 객체가 생성된다.

SoSimple<int> obj;

 


Case 1 )

#include <iostream>
using namespace std;

/* 클래스 템플릿 Point 정의 */
template <typename T>
class Point {
private:
	T xpos, ypos;
public:
	Point(T x = 0, T y = 0) :xpos(x), ypos(y) { }
	void ShowPosition() const {
		cout << '[' << xpos << ", " << ypos << ']' << endl;
	}
};

/* 클래스 탬플릿 SimpleDataWrapper 정의 */
// 간단히 하나의 데이터를 저장하고, 데이터 정보를 출력하도록 정의
template <typename T>
class SimpleDataWrapper {
private:
	T mdata;
public:
	SimpleDataWrapper(T data) :mdata(data) { }
	void ShowDataInfo() {
		cout << "Data: " << mdata << endl;
	}
};

// 클래스 템플릿 SimpleDataWrapper를 char*형에 대해 특수화함.
// 목적 : 문자열을 저장하기 위한 것 (동적할당, 문자열의 길이정보 추가)
template<>
class SimpleDataWrapper<char*> {
private:
	char* mdata;
public:
	SimpleDataWrapper(const char* data) {
		mdata = new char[strlen(data) + 1];
		strcpy(mdata, data);
	}
	void ShowDataInfo() {
		cout << "String: " << mdata << endl;
		cout << "Length: " << strlen(mdata) << endl;
	}
	~SimpleDataWrapper(){
		delete[] mdata;
	}
};

// 클래스 템플릿 SimpleDataWrapper를 Point<int>형에 대해 특수화함.
// 목적 : 자료형의 이름만 Point<int>형으로 바뀜. 특수한 차이는 없음.
template<>
class SimpleDataWrapper<Point<int>>
{
private:
	Point<int> mdata;
public:
	SimpleDataWrapper(int x, int y) :mdata(x, y) { }
	void ShowDataInfo() {
		mdata.ShowPosition();
	}
};



int main() {
	SimpleDataWrapper<int> iwrap(170);
	iwrap.ShowDataInfo();
	
	// char*형에 대해서 특수화가 진행되었으므로, 별도의 템플릿 클래스가 생성되지 않고, 32행에 정의된 탬플릿 클레스의 객체가 생성된다.
	SimpleDataWrapper<char*> swrap("Class Template Specialization");
	swrap.ShowDataInfo();

	// Point<int>형에 대해서 특수화가 진행되었으므로, 별도의 템플릿 클래스가 생성되지 않고, 51행에 정의된 탬플릿 클레스의 객체가 생성된다.
	SimpleDataWrapper<Point<int>> poswrap(3, 7);
	poswrap.ShowDataInfo();

	return 0;
}

 


2. 클래스 템플릿의 부분 특수화

Case 2 )

#include<iostream>
using namespace std;

template <typename T1, typename T2>
class MySimple {
public:
	void WhoAreYou() {
		cout << "size of T1 : " << sizeof(T1) << endl;
		cout << "size of T2 : " << sizeof(T2) << endl;
		cout << "<typename T1, typename T2>" << endl;
	}
};

template<>
class MySimple<int, double> {
public:
	void WhoAreYou(){
		cout << "size of int : " << sizeof(int) << endl;
		cout << "size of double : " << sizeof(double) << endl;
		cout << "<int, double>" << endl;
	}
};

/*
template <typename T1>
class MySimple<T1, double> // T2를 double로 부분 특수화
{
public:
	void WhoAreYou(){
		cout << "size of T1 : " << sizeof(T1) << endl;
		cout << "size of double : " << sizeof(double) << endl;
		cout << "<T1,double>" << endl;
	}
};
*/

int main() {
	MySimple<char, double>obj1; // 주석이 해제되면 <T1,double> 특수화 부분이 실행됨
	obj1.WhoAreYou();

	MySimple<int, long> obj2;
	obj2.WhoAreYou();

	MySimple<int, double> obj3; // 부분 특수화에 해당되더라도, 전체 특수화가 우선적으로 실행됨
	obj3.WhoAreYou();

	return 0;
}

주석 해제 X

 

주석 해제 O

 

 


* 유의사항
- 아직 공부하고 있는 문과생 코린이가, 정리해서 남겨놓은 정리 및 필기노트입니다.
- 정확하지 않거나, 틀린 점이 있을 수 있으니, 유의해서 봐주시면 감사하겠습니다.
- 혹시 잘못된 점을 발견하셨다면, 댓글로 친절하게 남겨주시면 감사하겠습니다 :)
반응형