템플릿이란?
- 함수나 클래스를 개별적으로 다시 작성하지 않아도, 여러 자료형으로 사용할 수 있도록 하게 만들어 놓은 틀.
- 함수 템플릿(Function Template)와 클래스 템플릿(Class Template) 로 나누어짐.
일반화 프로그래밍
- 데이터 대신 프로그램의 알고리즘에 중점을 두는 기법
- 현대 프로그래밍 언어가 가지는 중요한 특징
함수 템플릿
T 자리에 서로 다른 타입을 넣을 수 있음. 이를 이용해 좀 더 코드를 일반화 시킬 수 있음.
cpp
template <typename T>
T sum (T a, T b) {
return a + b;
}
// + 연산이 적용된 타입이면 무조건 accept.
// 타입에 신경쓰지 않는다.
함수 템플릿의 인스턴스화
- 함수 템플릿이 처음으로 호출될 때, c++ 컴파일러는 해당 타입의 인스턴스를 생성.
- 이렇게 생성된 인스턴스는 해당 타입에 대해 특수화된 템플릿 함수
명시적 특수화
- 특정한 함수 템플릿에 대해 특별한 동작을 정의할 수 있게 해주는 것
- 컴파일러는 호출된 함수에 대해 대응하는 정의를 발견하면, 해당 정의를 사용.’
예시는 다음과 같다.
cpp
// 기본적인 함수 템플릿
template <typename T> void Swap(T& a, T& b);
// double 타입인 경우 다른 동작을 한다
template <> void Swap<double>(double&, double&) { ... };
클래스 템플릿
클래스의 일반화된 선언.
타입에 따라 다르게 동작하는 클래스 집합을 만들 수 있음.
cpp
template <typename T>
class Data {
private:
T data_;
public:
Data(T dt);
data(T dt);
T get_data();
};
중첩 클래스 템플릿
- 클래스 또는 클래스 템플릿 내에 또 다른 템플릿을 중첩해 정의하는 것
- 이를 멤버 템플릿이라고 한다.
- 멤버 템플릿 중 클래스 템플릿을 중첩 클래스 템플릿 이라고 함.
- 이러한 중첩 클래스 템플릿은 바깥쪽 클래스의 범위 내에서 클래스 템플릿으로 선언.
- ㄴㄴ정의는 바깥쪽 클래스의 범위 내에서뿐만 아니라 범위 밖에서도 가능
cpp
template <typename T>
class X
{
template <typename U>
class Y {...}
...
}
int main(void)
{
...
}
template <typename T>
template <typename U>
X<T>::Y<U>::멤버함수이름()
{
...
}
클래스 템플릿의 특징
- 하나 이상의 템플릿 인수를 가지는 클래스 템플릿 선언 가능
- 디폴트 템플릿 인수를 명시 가능
- 클래스 템플릿을 기초 클래스로 하여 상속 가능
명시적 특수화
클래스 템플릿은 함수 템플릿과 마찬가지로 특정 타입이나 값의 템플릿 인수에 대하여 특수화할 수 있음.
- 이렇게 특수화를 명시하면, 해당 타입에 대한 특별한 동작을 정의 가능
- 컴파일러는 전달된 인수에 정확히 대응하는 특수화된 정의를 발견하면, 더는 다른 템플릿을 찾지 않고 해당 정의를 사용.
부분 특수화(partial specialization)
만약 템플릿 인수가 두 개 이상이고, 그중 일부에 대해서만 특수화를 해야 할 때는 부분 특수화(partial specialization)를 사용할 수 있다.
- 먼저 template 키워드 다음에 나오는 꺾쇠괄호(<>)에 특수화하지 않는 타입의 템플릿 인수를 명시.
- 그리고서 다음에 나오는 꺾쇠괄호(<>)에 특수화하는 타입을 명시하면 됨.