13. 템플릿(Template) 1
출처: 윤성우 열혈강의 C++ 예제코드
13.1. 템플릿(Template)에 대한 이해와 함수 템플릿
- 함수 템플릿 사용하기
#include <iostream>
using namespace std;
template <typename T>
T Add(T num1, T num2)
{
return num1+num2;
}
int main(void)
{
cout<< Add<int>(15, 20) <<endl;
cout<< Add<double>(2.9, 3.7) <<endl;
cout<< Add<int>(3.2, 3.2) <<endl;
cout<< Add<double>(3.14, 2.75) <<endl;
return 0;
}
35
6.6
6
5.89
- 일반함수와 템플릿함수의 구분
#include <iostream>
using namespace std;
template <typename T>
T Add(T num1, T num2)
{
cout<<"T Add(T num1, T num2)"<<endl;
return num1+num2;
}
int Add(int num1, int num2)
{
cout<<"Add(int num1, int num2)"<<endl;
return num1+num2;
}
double Add(double num1, double num2)
{
cout<<"Add(double num1, double num2)"<<endl;
return num1+num2;
}
int main(void)
{
cout<< Add(5, 7) <<endl;
cout<< Add(3.7, 7.5) <<endl;
cout<< Add<int>(5, 7) <<endl;
cout<< Add<double>(3.7, 7.5) <<endl;
return 0;
}
Add(int num1, int num2)
12
Add(double num1, double num2)
11.2
12
11.2
- 둘 이상의 형(Type)에 대한 템플릿 선언하기
#include <iostream>
using namespace std;
template <class T1, class T2>
void ShowData(double num)
{
cout<<(T1)num<<", "<<(T2)num<<endl;
}
int main(void)
{
ShowData<char, int>(65);
ShowData<char, int>(67);
ShowData<char, double>(68.9);
ShowData<short, double>(69.2);
ShowData<short, double>(70.4);
return 0;
}
A, 65
C, 67
D, 68.9
69, 69.2
70, 70.4
- 함수 템플릿의 특수화
#include <iostream>
#include <cstring>
using namespace std;
template <typename T>
T Max(T a, T b)
{
return a > b ? a : b ;
}
template <>
char* Max(char* a, char* b)
{
cout<<"char* Max<char*>(char* a, char* b)"<<endl;
return strlen(a) > strlen(b) ? a : b ;
}
template <>
const char* Max(const char* a, const char* b)
{
cout<<"const char* Max<const char*>(const char* a, const char* b)"<<endl;
return strcmp(a, b) > 0 ? a : b ;
}
int main(void)
{ cout<< Max(11, 15) <<endl;
cout<< Max('T', 'Q') <<endl;
cout<< Max(3.5, 7.5) <<endl;
cout<< Max("Simple", "Best") <<endl;
char str1[]="Simple";
char str2[]="Best";
cout<< Max(str1, str2) <<endl;
return 0;
}
15
T
7.5
const char* Max<const char*>(const char* a, const char* b)
Simple
char* Max<char*>(char* a, char* b)
Simple
13.2. 클래스 템플릿(Class Temlpate)
- 클래스 템플릿 사용하기
#include <iostream>
using namespace std;
template <typename 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;
}
};
int main(void)
{
Point<int> pos1(3, 4);
pos1.ShowPosition();
Point<double> pos2(2.4, 3.6);
pos2.ShowPosition();
Point<char> pos3('P', 'F'); // 좌표정보를 문자로 표시하는 상황의 표현
pos3.ShowPosition();
return 0;
}
- 클래스 템플릿 선언와 정의 분리
#include <iostream>
using namespace std;
template <typename T>
class Point
{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0);
void ShowPosition() const;
};
template <typename T>
Point<T>::Point(T x, T y) : xpos(x), ypos(y)
{ }
template <typename T>
void Point<T>::ShowPosition() const
{
cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
}
int main(void)
{
Point<int> pos1(3, 4);
pos1.ShowPosition();
Point<double> pos2(2.4, 3.6);
pos2.ShowPosition();
Point<char> pos3('P', 'F'); // 좌표정보를 문자로 표시하는 상황의 표현
pos3.ShowPosition();
return 0;
}
- 배열 클래스의 템플릿화 및 파일분리
ArrayTemplate.h
#ifndef __ARRAY_TEMPLATE_H_
#define __ARRAY_TEMPLATE_H_
#include <iostream>
#include <cstdlib>
using namespace std;
template <typename T>
class BoundCheckArray
{
private:
T * arr;
int arrlen;
BoundCheckArray(const BoundCheckArray& arr) { }
BoundCheckArray& operator=(const BoundCheckArray& arr) { }
public:
BoundCheckArray(int len);
T& operator[] (int idx);
T operator[] (int idx) const;
int GetArrLen() const;
~BoundCheckArray();
};
template <typename T>
BoundCheckArray<T>::BoundCheckArray(int len) :arrlen(len)
{
arr=new T[len];
}
template <typename T>
T& BoundCheckArray<T>::operator[] (int idx)
{
if(idx<0 || idx>=arrlen)
{
cout<<"Array index out of bound exception"<<endl;
exit(1);
}
return arr[idx];
}
template <typename T>
T BoundCheckArray<T>::operator[] (int idx) const
{
if(idx<0 || idx>=arrlen)
{
cout<<"Array index out of bound exception"<<endl;
exit(1);
}
return arr[idx];
}
template <typename T>
int BoundCheckArray<T>::GetArrLen() const
{
return arrlen;
}
template <typename T>
BoundCheckArray<T>::~BoundCheckArray()
{
delete []arr;
}
#endif
Point.h
#ifndef __POINT_H_
#define __POINT_H_
#include <iostream>
using namespace std;
class Point
{
private:
int xpos, ypos;
public:
Point(int x=0, int y=0);
friend ostream& operator<<(ostream& os, const Point& pos);
};
#endif
Point.cpp
#include <iostream>
#include "Point.h"
using namespace std;
Point::Point(int x, int y) : xpos(x), ypos(y) { }
ostream& operator<<(ostream& os, const Point& pos)
{
os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
return os;
}
BoundArrayMain.cpp
#include <iostream>
#include "ArrayTemplate.h"
#include "Point.h"
using namespace std;
int main(void)
{
/*** int형 정수 저장 ***/
BoundCheckArray<int> iarr(5);
for(int i=0; i<5; i++)
iarr[i]=(i+1)*11;
for(int i=0; i<5; i++)
cout<<iarr[i]<<endl;
/*** Point 객체 저장 ***/
BoundCheckArray<Point> oarr(3);
oarr[0]=Point(3, 4);
oarr[1]=Point(5, 6);
oarr[2]=Point(7, 8);
for(int i=0; i<oarr.GetArrLen(); i++)
cout<<oarr[i];
/*** Point 객체의 주소 값 저장 ***/
typedef Point * POINT_PTR;
BoundCheckArray<POINT_PTR> parr(3);
parr[0]=new Point(3, 4);
parr[1]=new Point(5, 6);
parr[2]=new Point(7, 8);
for(int i=0; i<parr.GetArrLen(); i++)
cout<<*(parr[i]);
delete parr[0];
delete parr[1];
delete parr[2];
return 0;
}
11
22
33
44
55
[3, 4]
[5, 6]
[7, 8]
[3, 4]
[5, 6]
[7, 8]