별거 없다. 그냥 배열 클래스를 만들었는데 배열 타입이 정해진게 아니고 템플릿으로 변경된 것
template <class T>
class SimpleClass{
public:
T SimpleFunc(T num) { ... }
};
template <>
class SimpleClass<int>{ // 함수 템플릿때랑 똑같다. T 부분을 전부 int로 바꿔준다.
public:
int SimpleFunc(int num){...}
};
template <class T1, class T2>
class SimpleClass{
public:
T1 SimpleFunc(T1 num1, T2 num2) { ... }
};
template <class T1>
class SimpleClass<T1, int>{ // T1은 그대로 템플릿 형식으로 두고, 뒤의 T2만 특수화하여(여기선 int) 쓸 수 있다.
public:
T1 SimpleFunc(T1 num, int num2){...}
};
위와 같이 전부 특수화하는것이 아니라 일부분에만 특수화를 적용 시킬 수 있다.
템플릿을 정의할 때 결정되지 않은 자료형을 의미하는 용도로 사용되는 T 또는 T1, T2와 같은 문자를 가리켜 템플릿 매개변수
라고 한다. 그리고 템플릿 매개변수에 전달되는 자료형 정보를 가리켜 템플릿 인자
라고 한다.
template <class T1, int len>
class SimpleClass{
private:
T arr[len];
public:
T& operator[] (int idx){
return arr[idx];
}
};
int main(void){
SimpleClass<int, 5> i5arr;
SimpleClass<double, 7> d7arr;
}
위와 같이 class T1
이 아닌 int len
처럼 쓸 수 있으며, main
에서 보는바 와 같이 객체 생성이 가능하다.
int len
부분은 사실 굳이 배열의 길이를 결정하기 위해 템플릿 매개변수에 정수를 전달하는 것보단SimpleClass<int, 5>
와 SimpleClass<int, 7>
을 비교하면, 두 class는 다른 형(type)이기 때문에 이와같이 배열 클래스 객체를 만들면 길이가 다른 두 배열 객체간의 대입은 허용되지 않는다!.template <class T1=int, int len=7>// 이런식으로 Default value 지정!
class SimpleClass{
private:
T arr[len];
public:
T& operator[] (int idx){
return arr[idx];
}
};
int main(void){
SimpleClass<> arr;// arr의 T = int, len = 7 로 기본값이 넣어진다. 이떄 <>마크는 내부를 비워둘지언정 항상 있어야한다.
}
template <class T>
void ShowstaticValue(void){
static T num = 0;
num+=1;
cout << num << " ";
}
int main(void){
ShowStaticValue<int>();
ShowStaticValue<long>();
return 0;
}
위와 같이 함수 템플릿 내에 지역변수 num을 static으로 선언한다. 그럼 컴파일러는 함수 템플릿 기반으로 아래와 같은 템플릿 함수를 만든다.
void ShowstaticValue<int>(void){
static T num = 0;
num+=1;
cout << num << " ";
}
void ShowstaticValue<long>(void){
static T num = 0;
num+=1;
cout << num << " ";
}
이때, static 지역변수가 템플릿 함수 별로 각각 존재하게 되어, 해당 타입에 맞는 static 지역변수를 부르게 된다.
static 멤버변수는 변수가 선언된 클래스의 객체간 공유가 가능한 변수이다. 따라서 아래와 같은 클래스 템플릿이 정의되면
template <class T>
class SimpleClass{
private:
static T mem;
public:
void AddMem(T num) {mem+=num;}
void ShowMem(){cout << mem << endl;}
};
template<class T>
T SimpleClass<T>::mem=0;//템플릿 기반의 static 멤버 초기화 문장;
int main(void){
SimpleClass<int> obj1;
SimpleClass<long> obj2;
return 0;
}
컴파일러에 의해서 아래와 같이 템플릿 클래스들이 생성된다.
class SimpleClass<int>{
private:
static int mem;
public:
void AddMem(int num) {mem+=num;}
void ShowMem(){cout << mem << endl;}
};
int SimpleClass<int>::mem=0;//템플릿 기반의 static 멤버 초기화 문장;
class SimpleClass<long>{
private:
static long mem;
public:
void AddMem(long num) {mem+=num;}
void ShowMem(){cout << mem << endl;}
};
long SimpleClass<long>::mem=0;//템플릿 기반의 static 멤버 초기화 문장;
방금 보였던 예제에서 T SimpleClass<T>::mem=0;
템플릿 기반의 static 멤버 초기화 문장은 모든 type
의 mem
이 0
으로만 초기화되게 하였다. 하지만, 만약 long
이나 double
에는 4나 1.6 등을 넣어 초기화 시켜주고 싶다면 어찌해야하는가?
답은 초기화의 특수화에 있다.
template<class T>
T SimpleClass<T>::mem=0;//템플릿 기반의 static 멤버 초기화 문장;
____위를 아래와 같이 특수화 시킬 수 있다.____
template<>
long SimpleClass<long>::mem=5;