틀, 주물이라는 뜻으로 틀은 대량생산과 규격화 된 제품을 복사하듯이 사용할 수 있는 것과 달리 프로그래밍 언어에서 템플릿은 불필요하게 반복되는 작접을 혁신적으로 줄여줄 수 있는 문법 중 하나이다.
사용하고자 하는 함수가 단지 타입만 다르다면 다시 함수를 정의하고 사용하는 것은 불필요한 작업이 아닐 수 없다.
따라서 템플릿 문법을 사용하면 이러한 수고는 훨씬 덜 수 있다.
//함수 템플릿
template<typename Tem>
Tem Add(Tem a, Tem b){
teturn a + b;
}
//함수 템플릿 사용
int main(){
float num1 = Add<float>(2.2, 3.0);
//타입이 다른 함수로 사용할 수 있다.
int num2 = Add<int>(2.2, 3.0);
return 0;
}
함수에서 사용했듯이 클래스에서도 템플릿을 사용할 수 있다.
이전에 배열을 클래스로 구현 한 예시로 템플릿을 적용시켜보자
// 템플릿 사용
template <typename T>
class CArr {
private :
// 어떤 데이터의 타입이 들어올지 모르므로 타입으로 정의
T* m_pData;
// 아래 두 멤버변수는 정수타입이여야 한다.
int m_iCount;
int m_MaxCount;
public :
CArr();
~CArr();
public :
void PushBack(const T& _Data);
void Resize(int ResizeData);
// 해당 타입의 배열의 값을 리턴해야 되기 때문에 템플릿으로 정의한다.
T& operator[] (int idx);
};
template <typename T>
// 클래스 옆에 템플릿을 사용한다.
CArr<T>::CArr() :
m_pData(nullptr),
m_iCount(0),
m_MaxCount(2)
{
m_pData = new T[2];
}
template <typename T>
CArr<T>::~CArr()
{
delete[] m_pData;
}
template <typename T>
void CArr<T>::PushBack(const T& _Data)
{
// 데이터 부족 시 공간 크기 증가
if (m_iCount >= m_MaxCount) {
Resize(m_MaxCount * 2);
}
//데이터 넣기
m_pData[m_iCount++] = _Data;
}
template <typename T>
void CArr<T>::Resize(int ResizeData)
{
//만약 증가하고자 하는 값이 지금 사이즈보다 작거나 같으면 필요없음
if (m_MaxCount >= ResizeData) {
assert(m_MaxCount >= ResizeData);
}
// 리사이즈 시킬 갯수 만큼 동적 할당
// 해당 타입도 마찬가지로 어떤 타입의 자료형이 올지 모르기 때문에 템플릿으로 정의하였다.
T* pNew = new T[ResizeData];
//기존 공간 데이터들을 새로 할당된 공간으로 복사
for (int i = 0; i < m_iCount; i++)
{
pNew[i] = m_pData[i];
}
// 기존 공간 삭제
delete[] m_pData;
//배열이 새로 할당된 공간을 가르키게 한다
m_pData = pNew;
// MaxCount 변경점 적용
m_MaxCount = ResizeData;
}
template <typename T>
T& CArr<T>::operator[](int idx)
{
// TODO: 여기에 return 문을 삽입합니다.
return m_pData[idx];
}
int main(){
// 자료형을 선정하여 인스턴스화 한다.
CArr<float> carr;
carr.PushBack(3.12f);
carr.PushBack(2.2f);
carr.PushBack(45.2f);
carr.PushBack(50.3f);
return 0;
}