본문 바로가기

Information Technology/C++

[C++] 함수 템플릿 특수화

이 글은 개인의 학습을 목적으로 정리한 글입니다. 이점 참고하고 읽어주세요 ;)


우리는 하나의 함수 혹은 클래스를 다양한 자료형으로 사용 사용할 수 있게 템플릿을 사용합니다.

즉, 템플릿에는 일반화의 의미가 내포되어 있다고 할 수 있습니다.

그런데 이번에 다뤄볼 함수 템플릿 특수화는, 일반화를 위해 생성한 함수 템플릿에서 특정 조건에 해당하는 경우를 따로 지정하는 것입니다. 코드를 통해 설명해보겠습니다.

template<typename T>
T getMax(T x, T y)
{
	return (x > y) ? x : y;
}

여기 template을 사용한 getMax 함수가 있습니다. template을 사용했으니 다양한 자료형을 이 getMax함수에서 사용할 수 있습니다.

그런데 getMax 함수를 만든 프로그래머는 이용자가 getMax 함수로 char 자료형을 통해 문자열을 비교할 때에는 경고창을 띄우고 싶다는 생각이 들었습니다. 이때 사용하는 것이 함수 템플릿 특수화입니다.

template<>
char getMax(char x, char y)
{
	cout << "Warning : comparing chars " << endl;
	return (x > y) ? x : y;
}

함수 템플릿 특수화는 다음과 같습니다.

우선 template을 선언하고 템플릿의 매개변수는 사용하지 않습니다. 우리는 char 자료형을 사용하는 경우만 다루기 때문입니다.

그리고 템플릿 선언 아랫줄에는 위에서 정의한 getMax를 자료형만 변경해서 선언해줍니다. 이 예제에서는 char 자료 혀입니다.

그리고 함수의 바디에서는 getMax 함수를 char 자료형으로 사용했을 때 호출되거나 출력될 내용을 입력하면 됩니다.

int main()
{
	cout << getMax('a', 'b') << endl;
    // Warning : comparing chars 
    // b
	
	return 0;
}

그리고 main 함수에서 getMax 함수에 코드 블록과 같이 문자열을 비교하게 되면

위에서 getMax 함수를 char 자료형에 대해 특수화한 대로 경고문구와 a와 b 중 더 큰 값인 b가 출력됩니다.


template <class T>
class Storage
{
private:
	T m_value;

public:
	Storage(T value)
	{ m_value = value; }

	~Storage()
	{}

	void print()
	{ std::cout << m_value << "\n"; }
};

이번에는 따로 Storage.h 헤더 파일을 만들어서 Storage 클래스를 정의했습니다.

템플릿 클래스로 작성했고, 간단하게 값을 입력받아 m_value로 초기화하고 print 함수를 통해 값을 출력합니다.

int main()
{
	Storage<int> nValue(5);
	Storage<double> dValue(6.7);
	
        nValue.print() // 5
	dValue.print() // 6.7
	return 0;
}

그리고 main함수에서 Storage 클래스의 인스턴스를 int 자료형으로도 만들고 double 자료형으로도 만듭니다.

그리고 두 인스턴스 모두 print 함수를 호출하면 이상 없이 저장된 값이 출력됩니다.

그런데 이번엔 이 코드의 프로그래머가 double 자료형을 사용하는 Storage 클래스의 인스턴스는 특정 문구가 출력되게 만들고 싶다는 생각이 들었습니다. 이를 위해서는 어떻게 해야 할까요?

template<>
void Storage<double>::print()
{
	std::cout << "This is special ";
	std::cout << m_value << std::endl;
}

일단 Storage 클래스를 정의한 Storage.h 헤더 파일로 돌아옵니다.

그리고 Storage 클래스를 정의한 코드 밑에 template 선언을 하고 매개변수는 입력하지 않습니다.

그 밑에 함수를 정의하듯이 출력 자료형 type을 우선 적습니다. 이 print 함수에서는 void입니다.

다음에 Storage 클래스의 멤버인 print 함수를 가져오는데, 우리가 특정하려는 자료형을 입력합니다. Storage<double>

매개변수 역시 함수에 알맞게 입력합니다. 예제의 print 함수는 매개변수가 없으니 비워뒀습니다.

마지막으로 함수의 바디 부분에 double 타입의 Storage 클래스 인스턴스가 print 함수를 호출할 때 실행시킬 코드를 입력하면 클래스 내에서의 함수 템플릿 특수화가 완료됩니다.

int main()
{
	Storage<int> nValue(5);
	Storage<double> dValue(6.7);

	nValue.print(); // 5
	dValue.print(); // This is special 6.7
	return 0;
}

그리고 다시 main함수를 실행시키면 int 자료형인 nValue의 print 함수에서는 5가 출력되고,

double 자료형인 dValue의 print 함수에서는 특수화를 시킨 대로 This is special 6.7 이 출력됩니다.

'Information Technology > C++' 카테고리의 다른 글

[C++] 템플릿의 부분적 특수화  (0) 2019.11.21
[C++] 클래스 템플릿 특수화  (0) 2019.11.20
[C++] 자료형이 아닌 템플릿 매개변수  (0) 2019.11.20
[C++] 클래스 템플릿  (0) 2019.11.19
[C++] 함수 템플릿  (0) 2019.11.19