1. 템플릿(Template)

템플릿(Template)이란, 말 그대로 "형틀"이라는 의미를 지니고 있습니다. 무엇을 찍어내는 틀, 비유하자면 붕어빵 틀에 비유할 수 있습니다. 템플릿은 모양, 틀을 본을 떠 놓은것이고, 집어 넣는 재료에 따라 결과가 조금씩 달라집니다. 붕어빵 역시도, 재료만 가지고 똑같은 모양으로 찍어낼 수 있으며, 넣는 재료에 따라 내용물은 조금씩 달라집니다. 이 템플릿은, 기능은 이미 결정되어 있으나 자료형이 정해지지 않는다는 특징을 지니고 있습니다.


이제 함수 템플릿, 클래스 템플릿에 대해 알아보려고 하는데, 함수 템플릿(Function Template)은 말 그대로, 함수를 찍어내는 틀을 말합니다. 클래스 템플릿(Class Template)은 클래스를 찍어내는 템플릿이죠. 우선, 함수 템플릿 부터 보도록 합시다.


2. 함수 템플릿(Function Template)

아래에 있는 함수 템플릿 예제를 바로 보도록 합시다.

#include <iostream>

using namespace std;

template<typename T>
void Swap(T& num1, T& num2)
{
	T temp = num1;
	num1 = num2;
	num2 = temp;
}

int main()
{
	int num1=10, num2=40;
	cout << "before, num1: " << num1 << ", num2: " << num2 << endl;
	Swap(num1, num2);
	cout << "after, num1: " << num1 << ", num2: " << num2 << endl;

	double num3=15.6, num4=14.44;
	cout << "before, num1: " << num3 << ", num2: " << num4 << endl;
	Swap(num3, num4);
	cout << "after, num1: " << num3 << ", num2: " << num4 << endl;
	return 0;
}

결과:

before, num1: 10, num2: 40

after, num1: 40, num2: 10

before, num1: 15.6, num2: 14.44

after, num1: 14.44, num2: 15.6

계속하려면 아무 키나 누르십시오 . . .


코드의 5~11행을 보시면 템플릿 정의가 보입니다. 5행을 먼저 보시면, T라는 이름을 이용해서, 아래에 위치한 함수를 템플릿으로 정의하겠다는 말입니다. 이 템플릿 변수 T는, 11행까지 유효합니다. 6행은 두 변수의 값을 서로 바꿔주는 Swap 함수가 정의되었는데, 전달받은 변수의 실제 값을 바꿔야 하기 때문에, 레퍼런스(Reference, 참조자)를 이용한 참조에 의한 호출(Call by reference)을 하였습니다. 


이어서, main 함수로 들어가 15행을 보시면, 정수형 변수 num1과 num2이 선언과 동시에 10과 40이란 값으로 각각 초기화 되었습니다. 17행의 Swap 함수를 호출하고, 18행에서 num1과 num2의 값을 출력했더니, 두 변수의 값이 서로 바뀌었습니다. 그리고, 이번에는 실수형 변수 num3과 num4이 선언과 동시에 15.6, 14.44란 값으로 각각 초기화 되었고, 22행에서 Swap 함수로 num3과 num4를 넘깁니다. 그런 뒤에 23행에서 num3, num4의 값이 출력됩니다.


결과를 보시면, int형이든, double형이든 자료형에 상관없이 Swap 함수의 본 기능을 제대로 수행하고 있음을 확인하실 수 있습니다. 위의 예제에서 쓰인 방법은, 컴파일러가 전달되는 인자의 자료형을 보고 T의 타입을 유추하는 것이며, 아래와 같이 명시적으로 해석하도록 타입을 지정해주어도 됩니다.

int num1=10, num2=40;
cout << "before, num1: " << num1 << ", num2: " << num2 << endl;
Swap<int>(num1, num2);
cout << "after, num1: " << num1 << ", num2: " << num2 << endl;

double num3=15.6, num4=14.44;
cout << "before, num1: " << num3 << ", num2: " << num4 << endl;
Swap<double>(num3, num4);
cout << "after, num1: " << num3 << ", num2: " << num4 << endl;

참고로, 템플릿을 정의할때 꼭 T라는 이름이 아니여도 괜찮습니다. T는 그저 일반적으로 쓰이는 이름입니다. 덧붙여서, typename을 class로 써도 상관이 없습니다. 즉, "typename T"나 "class T"는 같은 의미를 지닙니다.


3. 클래스 템플릿(Class Template)

이번엔 함수 템플릿이 아닌, 클래스 템플릿에 대해 알아보도록 하겠습니다. 템플릿을 함수에 적용하는 것과 같이, 클래스에도 적용이 가능합니다. 한번 클래스 템플릿을 정의해보도록 하겠습니다.

#include <iostream>

using namespace std;

template <typename T>
class Data 
{
private:
	T data;
public:
	Data(T data) : data(data) { }
	void ShowInfo() {
		cout << data << endl;
	}
};

int main()
{
	Data<int> data1(50);
	data1.ShowInfo();

	Data<char> data2('A');
	data2.ShowInfo();

	Data<double> data3(24.377);
	data3.ShowInfo();
}

결과:

50

A

24.377

계속하려면 아무 키나 누르십시오 . . .


코드를 보시면, 5~15행에서 클래스 템플릿이 정의되었습니다. 아까 보았던, 함수 템플릿과 정의 방법이 같습니다. main 함수로 내려와, 19, 22, 25행을 보시면 각각 Data<int>, Data<char>, Data<double>의 객체를 만들고 있습니다. 그리고 ShowInfo 함수로 출력한 결과, 정상적으로 출력됨을 확인할 수 있습니다.


주의하실 점은, 템플릿 함수에선 자료형 정보(<int>, <double>, <char> ..)를 생략할 수 있었으나, 템플릿 클래스에선 생략하면 안됩니다.


  함수 템플릿과 템플릿 함수, 클래스 템플릿과 템플릿 클래스의 차이점

함수 템플릿은 함수를 만드는데 사용되는 템플릿이라는 의미를 지니며, 템플릿 함수는 템플릿을 기반으로 만들어진 함수입니다. 함수 템플릿은 템플릿을 강조하는 반면, 템플릿 함수는 함수를 강조합니다.

똑같이, 클래스 템플릿은 클래스를 만드는데 사용되는 템플릿이며, 템플릿 클래스는 템플릿을 기반으로 만들어진 클래스입니다. 클래스 템플릿은 템플릿을 강조하는 반면, 템플릿 클래스는 클래스를 강조합니다.


여기까지, 템플릿에 대해 간단히 알아보았습니다. 추가적으로 알고 싶은 부분은, 덧글로 달아주시면 내용에 추가해 드리겠습니다. 수고하셨고, 다음 강좌로 예외 처리(Exception Handling)에 대해 알아보도록 하겠습니다.