함수 템플릿은 함수를 만들어 낸다. 함수의 기능은 결정되어 있지만, 자료형은 결정되어 있지 않아서 결졍해야 한다.
즉, 함수 템플릿
이라는 것은 함수를 만드는 도구가 된다.
template <typename T> // T라는 이름을 이용해서 아래의 함수를 템플릿으로 정의한다는 의미이다.
template <class C> // typename, class 둥다 흔히 사용되니 아무거나 쓰자, C++ 창시자 왈 class가 편하다.(짧아서..)
T Add(T num1, T num2)
{
return num1 + num2;
}
int main(void){
Add<int>(14,20);
Add<double>(2.9, 2.3);//이렇게 <>안에 원하는 타입을 넣어 원하는 방식으로 작동할 수 있따.
}
Add<int>, Add<double>
을 보고 미리 저 타입의 함수를 만들어 둔다. 그리고 나서 런타임시엔 앞서 만들어 놓은 두 함수를 호출 할 뿐이다. 런타임에 새로 함수를 만들지 않으며, 함수는 자료형만 하나씩만 만들어지게 된다.int main(void){
Add(14,20);
Add(2.9, 2.3);//이렇게 하면 전달되는 인자의 자료형을 참조하여 호출될 함수의 유형을 컴파일러가 결정하기 때문이다.
}
함수 템플릿
이라 한다. 템플릿 함수
라 한다.int Add<int>(int num1, int num2)// 컴파일러가 컴파일시 함수 템플릿을 참조해서 만든 템플릿 '함수'
{
return num1 + num2;
}
템플릿 함수
는 컴파일러에 의해서 생성된 함수이기 때문에 생성된 함수(Generated Function)
로도 불린다.템플릿 함수
와 일반 함수 중가 공존하는 코드에 일반 호출 Add(5,67)
을 할 때, 일반 함수가 불리고, Add<in>(5,67)
과 같이 템플릿 함수
의 호출을 명시해야 템플릿 함수
가 호출된다.함수 템플릿
을 정의한 상황에서 일반함수까지 정의하는 것은 자제하자... 바람직하지 못하다.함수 템플릿을 만들때, 꼭 1개의 type만으로만 만들 수 있는 것은 아니다.
template <class T1, class T2>
void ShowData(double num){
cout << (T1)num << ", " << (T2)num <<endl;
}
위와 같이 2개 이상의 타입도 가능하다.
템플릿 함수의 구성방법에 예외를 둘 필요가 있는데, 이 떄 사용되는 것이 함수 템플릿의 특수화(specialization of gunction template
이다.
template <class T>
T Max(T a, T b){
return a> b? a:b;
}
int main(void){
cout << Max(11, 15);
cout << Max("Simple", "Best");
}
위와 같은 구문이 있을때, Max(11,15)
는 문제없이 의도대로 작동하나, Max("Simple", "Best")
는 실제 길이or사전순을 비교하는 것이 아니라, 단순히 주소 값의 비교경과를 반환되므로 의미가 없어진다.
이를 막기 위해 함수 템플릿의 특수화를 써서 해결해보자
template <class T>
T Max(T a, T b){
return a> b? a:b;
}
template <>
char* Max(char *a, char* b){// char* Max<char*>요런 식으로 적으로 좀더 정보를 명확히 하는 방법이 된다.
cout << "special max" <<endl;
return strlen(a) > strlen(b) ? a: b;
}
template <>
const char* Max(char *a, char* b){
cout << "special max" <<endl;
return strcmp(a,b) > 0 ? a: b;
}
int main(void){
cout << Max(11, 15);
cout << Max("Simple", "Best");
}
template<>
코드 아래 적힌 Max
함수 들은 각각 char*
, const char*
형은 "내가 이렇게 제시를 하니, 그 타입의 템플릿 함수가 필요한 경우에는 별도로 만들지 말고 이것을 써라"라고 컴파일러에게 알려주는 것이다.앞서 함수를 템플릿으로 정의했듯이 클래스도 템플릿으로 정의가 가능하다. 그리고 이렇게 정의된 템플릿을 가리켜
클래스 템플릿
이라 하며, 이를 기반으로 컴파일러가 만들어 내는 클래스를 가리켜템플릿 클래스
라 한다.
template<class T>
class Point{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0): xpos(x), ypos(y)
{}
void ShowPosition() const
{
cout << '[' << xpos << ", " << ypos << ']' << endl;
}
};
함수 템플릿 기반과 다르게 클래스 템플릿 기반의 객체생성에는 반드시! 자료형 정보를 명시하도록 되어있다.
클래스 템플릿도 멤버함수를 클래스 외부에 정의하는 것이 가능하다. 예를 들어,
template <class T>
class SimpleTemplate
{
public:
T SimpleFunc(const T& ref);
};
이 템플릿의 멤버함수 SimpleFunc
은 다음과 같이 외부에 정의해야 한다.
template <class T>
T SimpleTemplate<T>::SimpleFunc(const T& ref){} //여기서 T SimpleTemplate<T>는
//"T에 대해 템플릿화 된 simple Template 클래스 템플릿을 뜻한다."
template <class T>
를 빼면 에러가 난다. T가 무엇인지 모르기 때문