타입은 다른데 같은 작업을 하는 클래스나 함수를 구현을 할때 템플릿을 사용합니다. 아래와 같이 말이죠.


template<typename T>
class CFoo
{
public:
	T Add(T lhs, T rhs)
	{
		return lhs + rhs;
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	CFoo<int> integer;
	std::cout << integer.Add(3, 5) << std::endl;

	CFoo<float> floating;
	std::cout << floating.Add(2.5f, 8.2f) << std::endl;

	return 0;
}



여기까지는 계획대로 잘 되는거 같습니다. 그렇다면 Add 함수에 아래와 같이 문자열을 넣어서 두 문자열이 합쳐지게 만드려면 어떨까요?


CFoo<char*> szStr;
std::cout << szStr.Add("Hello, ", "World!!") << std::endl;


결과는 error C2110: '+' : 두 포인터를 더할 수 없습니다. 라는 메시지와 함께 에러가 나버립니다. 두 문자열이 합쳐지게 하려면 char* 타입용 CFooCharPointer 클래스를 따로 구현해야 할까요? 아니면 클래스 전체를 구현하기는 귀찮으니 char* 인자를 받는 AddCharPointer 함수만 추가로 구현해줄까요? 


비슷한 일을 하는 클래스를 또 만드는 것도, 다른 타입의 템플릿 클래스에서는 굳이 사용안할 멤버 함수를 추가하는 것도, 둘다 그리 좋은 모습은 아닙니다. 이런 상황의 해결책으로 템플릿 특수화 기능을 사용하면 됩니다. 특정 타입에서만 다르게 동작하는 함수를 만들수 있는 것이죠. 위의 상황에서 int나 float 같은 일반적인 타입에서는 기존에 정의한 Add 함수대로 동작하고, char* 같은 예외 타입이 들어오면 특수화 시킨 함수를 호출 시키게 하면 되는 것입니다.


template<typename T>
class CFoo
{
public:
	T Add(T lhs, T rhs)
	{
		return lhs + rhs;
	}
};

// char* 타입용 특수화 함수
template<> char* CFoo<char*>::Add(char* lhs, char* rhs)
{
	char *sz = new char[128];
	memset(sz, 0, sizeof(sz));
	strcat(sz, lhs);
	strcat(sz, rhs);
	return sz;
}

int _tmain(int argc, _TCHAR* argv[])
{
	CFoo<int> integer;
	std::cout << integer.Add(3, 5) << std::endl;

	CFoo<float> floating;
	std::cout << floating.Add(2.5f, 8.2f) << std::endl;

	CFoo<char*> szStr;
	char *resultString = szStr.Add("Hello, ", "World!!");
	std::cout << resultString << std::endl;
	delete[] resultString;

	return 0;
}

CFoo에 위와 같이 char* 타입에 대해 함수를 재정의 해줍니다. 이렇게 할 경우 char* 타입으로 템플릿을 생성했을 경우 Add 함수를 호출 하면, 특수화된 Add 함수가 호출되고, 결과는 아래와 같이 원하는대로 출력되는 것을 확인할 수 있습니다.



참고 : https://msdn.microsoft.com/ko-kr/library/c401y1kb.aspx

PS : CFoo<std::string> 을 사용하면 char* 특수화를 안해도되지만, 예를 위해 위와 같이 샘플 코드를 작성해보았습니다.

+ Recent posts