1. 템플릿(Template)에 대한 이해와 함수 템플릿
템플릿에는 '모형자'라는 뜻이 담겨 있다.
함수를 대상으로 템플릿 이해하기
'함수 템플릿'은 함수를 만들어 낸다.
함수의 기능은 결정되어 있지만, 자료형은 결정되어 있지 않아서 결정해야 한다.
예를 통해 살펴보자
int Add(int num1, int num2) { return num1+num2; |
T Add(T num1, T num2) { return num1+num2; |
- 함수의 기능 덧셈 - 대상 자료형 int형 데이터 |
- 함수의 기능 덧셈 - 대상 자료형 결정되어 있지 않음 |
위를 살펴보면 int형 선언을 T로 대신 했음을 알 수 있는데, 이는 자료형을 결정짓지 않은,
그래서 나중에 T를 대신해서 실제 자료형을 결정하겠다는 뜻이다.
그런데 이것이 전부는 아니다.
우리는 컴파일러에게 다음과 같은 메시지를 전달해야 한다.
"T는 자료형을 결정짓지 않겠다는 의미로 사용한 것입니다. 즉, 함수를 만들어 내는 템플릿을 정의하기 위해서 사용된 것이지요."
그리고 이러한 메시지를 담아서 위의 '함수 템플릿'은 다음과 같이 완성해야 한다.
template <typename T> T Add(T num1, T num2) { return num1+num2; } |
위의 템플릿 정의에 다음 문장이 존재한다.
template<typename T> |
이는 T라는 이름을 이용해서 아래의 함수를 템플릿으로 정의한다는 의미이다.
typename을 대신해서 class를 사용할 수도 있다.
template<class T> |
함수 템플릿과 템플릿 함수
앞서 보인 다읨의 정의를 가리켜 '함수 템플릿(function template)'이라 한다.
template <typename T> T Add(T num1, T num2) { return num1+num2; } |
반면, 위의 템플릿을 기반으로 컴파일러가 만들어 내는 다음 유형의 함수들을 가리켜
'템플릿 함수(template function)'이라 한다.
int Add<int>(int num1, int num2) { return num1+num2; double Add<double>(double num1, double num2) { return num1+num2; |
위의 템플릿 함수의 표시에서 <int>와 <double>은 일반함수가 아닌,
컴파일러가 만들어낸 템플릿 기반의 함수임을 표시한 것이다.
정리하자면,
'함수 템플릿'은 다음의 의미를 지닌다.
"함수를 만드는데 사용되는 템플릿!
즉, 호출이 가능한 함수가 아닌, 템플릿임을 강조한 것이다.
그리고 '템플릿 함수'는 다음의 의미를 지닌다.
템플릿을 기반으로 만들어진 함수!
템플릿 함수는 컴파일러에 의해서 생성된 함수이기 때문에 '생성된 함수(Gernerated Function)'으로도 불린다.
그리고 잠시 후에 설명하는 '템플릿 클래스' 역시 '생성된 클래스'로도 불린다.
함수 템플릿의 특수화(Specialization)
예를 통해 살펴보자
#include <iostream> template <typename T> int main(void) return 0; |
|
위 예제의 함수 템플릿 Max는 인자로 전달된 두 데이터 중 큰 값을 반환하도록 정의되어 있다.
그런데 문자열을 대상으로 호출할 경우, 그 결과에 대해서는 아무런 의미도 부여할 수 없게 된다.
(단순히 주소 값의 비교결과가 반환되므로)
만약에 문자열의 길이비교가 목적이라면, 다음의 형태로 템플릿 함수가 구성되어야 의미가 있으며,
const char* Max(const char* a, const char* b) { return strlen(a) > strlen(b) ? a : b; |
사전편찬 순서의 비교가 목적이라면, 다음의 형태로 템플릿 함수가 구성되어야 의미를 갖는다.
const char* Max(const char* a, const char* b) { return strcmp(a, b) > 0 ? a : b; |
상황에 따라서 템플릿 함수의 구성방법에 예외를 둘 필요가 있는데 , 이 때 사용되는 것이
'함수 템플릿의 특수화(specialization of function template)'이다.
다음 예제는 위에서 이야기한 함수 템플릿의 특수화를 진행시킨 예제이다.
#include <iostream> template<typename T> template<> template<> int main(void) char str1[]="Simple"; |
위 예제의 다음 정의는
template<> |
컴파일러에게 다음의 메시지를 전달하는 것이다.
"char* 형 함수는 내가 이렇게 제시를 하니, char* 형 템플릿 함수가 필요한 경우에는 별도로 만들지 말고 이것을 써라."
마찬가지로 다음 정의는
template<> |
"const char*형 함수는 내가 이렇게 제시를 하니, const char* 형 템플릿 함수가 필요한 경우에는 별도로 만들지 말고 이것을 써라."
그리고 이 두 '함수 템플릿의 특수화' 정의 형태는,
특수화 하는 자료형의 정보 <char*>와 <const char*>를 생략한 형태이며,
이를 생략하지 않고 정의를 하면 다음의 형태가 된다.
template<> char* Max<char*>(char* a, char* b){.....} template<> const char* Max<const char*>(const char* a, const char* b) {.....} |
특수화하는 자료형 정보를 생략하건 생략하지 않건 그 의미하는 바에 차이는 없으나,
가급적이면 자료형 정보를 명시하는 것이 뜻을 명확히 하는 방법이 된다.
2. 클래스 템플릿(Class Template)
클래스도 템플릿으로 정의가 가능하다.
그리고 이렇게 정의된 템플릿을 가리켜 '클래스 템플릿(class template)이라 하며,
이를 기반으로 컴파일러가 만들어 내는 클래스를 가리켜 '템플릿 클래스(template class)라 한다.
예를 통해 살펴보자
#include <iostream> template <class T> int main(void) Point<double> pos2(2.4, 3.6); Point<char> pos3('P', 'F'); return 0; |
클래스 템플릿의 경우는 자료형의 정보 생략이 불가능하다.
클래스 템플릿 기반의 객체생성에는 반드시 자료형 정보를 명시하도록 되어 있다.
- 윤성우 저, 열혈강의 C++ 프로그래밍 中 -
'Programming Study > C++' 카테고리의 다른 글
예외처리(Exception Handling) (0) | 2014.10.15 |
---|---|
템플릿_2 (0) | 2014.10.14 |
String 클래스의 디자인 (0) | 2014.10.06 |
연산자 오버로딩_2 (0) | 2014.10.03 |
연산자 오버로딩_1 (0) | 2014.10.03 |