템플릿 개요
매개 변수화된 유형이라고도 하는 템플릿은 유형 매개 변수에 따라 함수와 클래스를 생성하는 메커니즘입니다. 템플릿을 사용함으로써 각 형식마다 별도의 클래스를 만드는 대신 많은 형식의 데이터에서 작동하는 단일 클래스 또는 함수를 디자인할 수 있습니다.
설명
예를 들어, 템플릿을 사용하지 않고 두 매개 변수의 최소값을 반환하는 형식 안전 함수를 만들려면 다음과 같이 오버로드된 함수 집합을 씁니다.
// what_are_templates1.cpp
// compile with: /c
// min for ints
int min( int a, int b ) {
return ( a < b ) ? a : b;
}
// min for longs
long min( long a, long b ) {
return ( a < b ) ? a : b;
}
// min for chars
char min( char a, char b ) {
return ( a < b ) ? a : b;
}
템플릿을 사용하여 이 중복을 단일 함수 템플릿으로 줄일 수 있습니다.
// what_are_templates2.cpp
// compile with: /c
template <class T> T min( T a, T b ) {
return ( a < b ) ? a : b;
}
템플릿은 형식 안전성 저하 없이 소스 코드 크기를 줄이고 코드 유연성을 상당히 높일 수 있습니다.
템플릿에는 함수 템플릿 및 클래스 템플릿과 같은 두 가지 기본 형식이 있습니다. 이전 예제에서 min은 함수 템플릿입니다. 클래스 템플릿은 다음과 같은 매개 변수를 포함하는 클래스입니다.
// what_are_templates3.cpp
template <class T> class A {
T m_t;
public:
A(T t): m_t(t) {}
void f(T t);
};
int main() {
A<int> a(10);
}
일부 중요한 차이점으로 다른 함수 및 클래스와 마찬가지로 템플릿이 선언되고 정의됩니다. 템플릿 선언은 함수 또는 클래스를 완벽하게 정의하지 않고 클래스 또는 함수에 대한 구문 구조만 정의합니다. 실제 클래스 또는 함수가 인스턴스화라는 프로세스를 통해 템플릿에서 만들어집니다. 개별 클래스 또는 생성된 함수를 인스턴스화됨이라고 합니다. 예를 들어 다음과 같은 클래스 템플릿을
template <class T> struct A { . . . };
A<int>, A<char>, A<int*>, A<MyClass*> 등에 대한 클래스를 인스턴스화하는 데 사용할 수 있습니다.
클래스나 함수의 인스턴스화를 명시적 또는 암시적으로 수행할 수 있습니다. 명시적 인스턴스화는 템플릿에서 생성되는 버전을 코드로 호출하는 방식입니다. 템플릿을 처음 사용하는 지점에서 필요에 따라 암시적 인스턴스화를 통해 템플릿을 인스턴스화할 수 있습니다.
템플릿은 값 매개 변수에 따라 매개 변수화될 수 있으며 이 경우 템플릿 매개 변수는 함수에 대한 매개 변수로 선언됩니다. 부동 소수점 형식 및 클래스 형식은 값 매개 변수로 사용할 수 없습니다.
// what_are_templates4.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
template <int i> class A {
int array[i];
public:
A() { memset(array, 0, i*sizeof(int)); }
};
int main() {
A<10> a;
}
템플릿에 대한 일반적인 문제는 동일한 코드가 모든 형식에 적용되는 만능 솔루션이 될 수 있다는 것입니다. 특정 형식에 대한 템플릿의 동작을 사용자 지정해야 하는 경우 특수화를 사용할 수 있습니다. 명시적 특수화를 사용하여 템플릿은 제네릭 형식이 아닌 특정 실제 형식으로 특수화할 수 있습니다. 클래스 템플릿은 부분적으로 특수화하여 여러 형식 매개 변수가 있는 템플릿을 갖고 있고 일부 매개 변수에 관한 동작만 사용자 지정하려는 경우 유용합니다. 부분 특수화는 여전히 일반적이며 실제 인스턴스화된 클래스를 생성하기 위해 실제 템플릿 인수가 필요합니다.