[문과 코린이의 IT 기록장] C++ - 템플릿과 static (함수 템플릿과 static 지역 변수, 클래스 템플릿과 static 맴버변수, template<typename T>, template<> 사용 상황, 템플릿 static 맴버변수 초기화의 특수화)
[문과 코린이의 IT 기록장] C++ - 템플릿과 static (함수 템플릿과 static 지역 변수, 클래스 템플릿과 static 맴버변수, template<typename T>, template<> 사용 상황, 템플릿 static 맴버변수 초기화의 특수화)
[ 클래스 템플릿에 대한 이전 포스팅 ]
1. 함수 템플릿과 static 지역 변수
* static에 대해 좀 더 참고하고 싶다면?
ex 1 ) 함수 템플릿 - static 활용
template <typename T>
void ShowStaticValue() {
static T num = 0; // 지역변수 num이 static으로 선언됨
num += 1;
cout << num << " ";
}
ex 2 ) 템플릿 함수들과 static
void ShowStaticValue<int>() {
static int num = 0; // static 지역변수는 템플릿 함수 별로 각각 존재하게 된다.
num += 1;
cout << num << " ";
}
void ShowStaticValue<long>() {
static int num = 0; // static 지역변수는 템플릿 함수 별로 각각 존재하게 된다.
num += 1;
cout << num << " ";
}
Case 1 )
#include<iostream>
using namespace std;
// 함수 템플릿
template <typename T>
void ShowStaticValue() {
static T num = 0;
num += 1;
cout << num << " ";
}
int main() {
ShowStaticValue<int>();
ShowStaticValue<int>();
ShowStaticValue<int>();
cout << endl;
ShowStaticValue<long>();
ShowStaticValue<long>();
ShowStaticValue<long>();
cout << endl;
ShowStaticValue<double>();
ShowStaticValue<double>();
ShowStaticValue<double>();
return 0;
}
결과값을 보면, 실행되는 컴파일러에 의해서 만들어진 템플릿 함수별로 static 지역변수가 유지되는 것을 알 수 있다.
2. 클래스 템플릿과 static 맴버변수
ex 1 ) 클래스 템플릿 - static
template <typename T>
class SimpleStaticMem {
private:
static T mem;
public:
void AddMem(int num) { mem += num; }
void Showmem() { cout << mem << endl; }
};
template <typename T>
T SimpleStaticMem<T>::mem = 0; // 템플릿 기반의 static 맴버 초기화 문장
ex 2 ) 컴파일러에 의한 템플릿 클래스들과 static
// <int>
class SimpleStaticMem<int> {
private:
static int mem;
public:
void AddMem(int num) { mem += num; }
void ShowMem() { cout << mem << endl; }
};
int SimpleStaticMem<int>::mem = 0;
// <double>
class SimpleStaticMem < double > {
private:
static double mem;
public:
void AddMem(double num) { mem += num; }
void ShowMem() { cout << mem << endl; }
};
double SimpleStaticMem<double>::mem = 0;
# 템플릿 클래스 별로 static 맴버변수를 유지하게 된다.
Case 2 )
#include<iostream>
using namespace std;
template <typename T>
class SimpleStaticMem {
private:
static T mem;
public:
void AddMem(int num) { mem += num; }
void Showmem() { cout << mem << endl; }
};
template <typename T>
T SimpleStaticMem<T>::mem = 0; // 템플릿 기반의 static 맴버 초기화 문장
int main() {
// obj1,obj2는 같은 템플릿 클래스를 활용하므로, static 맴버변수 공유
SimpleStaticMem<int>obj1;
SimpleStaticMem<int>obj2;
obj1.AddMem(2);
obj2.AddMem(3);
obj1.Showmem();
// obj3, obj4는 같은 템플릿 클래스를 활용하므로, static 맴버변수 공유
SimpleStaticMem<long>obj3;
SimpleStaticMem<long>obj4;
obj3.AddMem(100);
obj4.Showmem();
return 0;
}
3. template<typename T>, template<> 사용 상황
템플릿 관련 정의에는 template<typename T> 또는 template<>와 같은 선언을 둬서, 템플릿의 일부 또는 전부를 정의하고 있다는 사실을 컴파일러에게 알려야 한다.
- template<typename T> 선언 : 정의 부분에 T에 관한 내용이 들어가면 사용
template <typename T>
class SoSimple{
public:
T SimpleFunc(T num) {...}
}
- template<> 선언 : 정의 부분에 T가 들어가지 않으면 사용
// 위의 클래스 템플릿을 특수화 한 경우
template<>
class SoSimple<int>{
public:
int SimpleFunc(int num) { ... }
}
4. 템플릿 static 맴버변수 초기화의 특수화
앞의 예시에서 클래스 내부에서 static 맴버를 초기화 하는 방법은 이러했다.
// 클래스 static맴버변수 초기화 방법
template <typename T>
T SimpleStaticMem<T>::mem=0;
이 경우는 SimpleStaticMem<int>, SimpleStaticMem<double> ... 모두 0으로 초기화 시킨다.
그렇다면 만약 SimpleStaticMMem<long>만 0이 아닌, 5로 초기화하고 싶다면 어떻게 해야하는가?
template<>
long SimpleStaticMem<long>::mem=5;
이와 같이 특수화를 진행해 주면 된다.
즉, 특수화는 함수 템플릿, 클래스 템플릿만이 아닌, 그 클래스 내부(정의)부분에 있는 초기화문을 대상으로도 할 수 있다는 것이다.
* 유의사항 - 아직 공부하고 있는 문과생 코린이가, 정리해서 남겨놓은 정리 및 필기노트입니다. - 정확하지 않거나, 틀린 점이 있을 수 있으니, 유의해서 봐주시면 감사하겠습니다. - 혹시 잘못된 점을 발견하셨다면, 댓글로 친절하게 남겨주시면 감사하겠습니다 :) |