C++ Template 기본 개념
-
템플릿 (Template)
– 무언가를 찍어내는 틀
– 함수 템플릿, 클래스 템플릿, …
– 함수를 찍어내는 틀, 클래스를 찍어내는 틀, … -
함수 템플릿 (Function Template)
예를들어 두 수를 바꾸는 Swap 함수를 구현할 때
#include <iostream>
using namespace std;
void Swap(int &n1,int &n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
void main() {
int n1 = 10, n2 = 40;
cout << "before n1 : " << n1 << ", n2 : " << n2 << endl;
Swap(n1, n2);
cout << "after n1 : " << n1 << ", n2 : " << n2 << endl;
}
를 사용 할 경우 int 형에 한하여 문제 없이 Swap을 사용할 수 있다.
그러나 다른 자료형에 대하여 Swap이 필요할 경우 템플릿을 사용하지 않으면
#include <iostream>
using namespace std;
//template<typename T>
void Swap(int &n1,int &n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
void Swap(double &n3, double &n4) {
double temp = n3;
n3 = n4;
n4 = temp;
}
void main() {
int n1 = 10, n2 = 40;
cout << "before n1 : " << n1 << ", n2 : " << n2 << endl;
Swap(n1, n2);
cout << "after n1 : " << n1 << ", n2 : " << n2 << endl;
double n3 = 1.11, n4 = 9.99;
cout << "before n3 : " << n3 << ", n4 : " << n4 << endl;
Swap(n3, n4);
cout << "after n3 : " << n3 << ", n4 : " << n4 << endl;
}
와 같이 함수를 오버로딩 하여 중복되게 사용해야 한다. 이는 자료형이 많아질 수 록 코드가 복잡해지며 가독성이 떨어지기 때문에 위와 같은 문제 해결을 위하여
템플릿을 사용한다.
ex.
#include <iostream>
using namespace std;
template<typename T>
void Swap(T &n1,T &n2) {
T temp = n1;
n1 = n2;
n2 = temp;
}
void main() {
int n1 = 10, n2 = 40;
cout << "before n1 : " << n1 << ", n2 : " << n2 << endl;
Swap(n1, n2);
cout << "after n1 : " << n1 << ", n2 : " << n2 << endl;
double n3 = 1.11, n4 = 9.99;
cout << "before n3 : " << n3 << ", n4 : " << n4 << endl;
Swap(n3, n4);
cout << "after n3 : " << n3 << ", n4 : " << n4 << endl;
}
먼저 template 로 템플릿을 정의하고 참조자를 활용하여 참조에 의한 호출을 수행한다. 위 방법은 컴파일러가 전달되는 인자의 자료형을 보고 T의 타입을 유추하는 것이며 Swap(n1, n2) 또는 Swap(n3, n4) 로 사용할 수 있다.
참고로 템플릿의 정의에서 T는 일반적으로 쓰이는 이름이며 typename을 class로 써도 상관없다.
- 클래스 템플릿 (Class Template)
함수 템플릿과 동일하게 다양한 자료형을 가질 수 있는 클래스 마다 별도로 클래스 생성을 하는 것이 아니라 클래스 템플릿을 사용하여 다양한 자료형에 대한 클래스를 생성하는 “틀”을 사용한다.
#include <iostream>
using namespace std;
template<typename T>
class Data {
private:
T data;
public:
Data(T _data) : data(_data) { }
void print() {
cout << "data : " << data << endl;
}
};
void main() {
Data<int> d1(5);
// Data<int> d1 = { 3 }; 와 동일
d1.print();
Data<char> d2('A');
d2.print();
Data<double> d3(3.14);
d3.print();
}
단, 함수 템플릿의 경우 <자료형>을 생략할 수 있지만
클래스 템플릿에서는 반드시 <자료형>을 선언해야 한다.