• 템플릿은 범용 프로그래밍의 기반이며, 특정 타입에 의존하지 않고 코드를 작성합니다.
• 각 컨테이너에는 '벡터'와 같이 하나의 정의가 있지만 프로그래머는 벡터 <int>나 벡터 <float>와 같은 다양한 종류의 벡터를 정의할 수 있습니다.
• 프로그래머는 템플릿을 사용하여 함수 및 클래스를 정의할 수 있습니다.
• 함수 템플릿 자체는 타입이나 함수 또는 다른 개체가 아닙니다.
• 템플릿 정의만 포함된 소스 파일에서는 코드가 생성되지 않습니다.
• 어떤 코드가 나타나려면 템플릿이 인스턴스화되어야 합니다. 컴파일러가 실제 함수를 생성할 수 있도록 템플릿 인수를 지정해야 합니다.return_type function_name(parameter list) { // body of function }
#include <iostream>
using namespace std;
//절댓값 출력 함수
template <typename T>
T user_abs(T a) {
T ret;
ret = a < 0 ? -a : a;
cout << "processing abs : " << ret << endl;
return ret;
}
int main() {
int x1 = 10;
float x2 = -10.1f;
double x3 = -2.3;
user_abs(x1);
user_abs(x2);
user_abs(x3);
return 0;
}
#include <iostream>
using namespace std;
//절댓값 출력 함수
template <typename T>
T user_abs(T a) {
T ret;
ret = a < 0 ? -a : a;
cout << "processing abs : " << ret << endl;
return ret;
}
int main() {
int x1 = 10;
float x2 = -10.1f;
double x3 = -2.3;
user_abs(x1);
user_abs(x2);
user_abs(x3);
return 0;
}
위와 같이 여러 타입을 받는 함수를 오버로딩 과정을 일일이 하지 않고 템플릿을 사용하여 만들 수 있다.
결과:
processing abs : 10
processing abs : 10.1
processing abs : 2.3
템플릿의 정의를 구체적으로 해줄 경우에 error을 방지할 수 있다.
#include <iostream>
using namespace std;
template<typename T, typename Y>T avg(T a, Y b) {
T ret = (a + b) / 2;
cout << "avg = " << ret << endl;
return ret;
}
int main() {
int x1 = 3;
int x2 = 0;
float x3 = 4.12f;
avg(x1, x2);
avg(x2, x3);
avg(x3, x2);
}
#include <iostream>
using namespace std;
template<typename T, typename Y>void generic_swap(T &a, Y &b) {
T temp;
temp = a;
a = b;
b = temp;
}
int main() {
int a = 57, b = 2;
cout << "a=" << a << " b=" << b << endl;
generic_swap(a, b);
cout << "after swap: a=" << a << " b=" << b << endl;
double c = 5.7;
float d = 2.3f;
cout << "c=" << c << " d=" << d << endl;
generic_swap(c, d);
cout << "after swap: c=" << c << " d=" << d << endl;
}
• 템플릿 함수와 마찬가지로 템플릿클래스를 정의할 수 있습니다.
• 템플릿 클래스는 대체로 단일 데이터 유형의 특정 뉘앙스보다는 알고리즘적 사고에 더 초점을 맞춥니다.
• 키워드 'class'와 'typename'을 사용할 수 있습니다.template <class T> class class_name { }; class_name<type> obj_name;
#define MAX_SIZE 50
#include <iostream>
using namespace std;
template <typename TYPE>
class stack {
TYPE data[MAX_SIZE];
int nCount;
public:
stack() { nCount = 0; }
void add(TYPE in) {
data[nCount++] = in;
if (nCount == MAX_SIZE) {
cout << "overflow : " << nCount << endl;
}
}
TYPE pop() {
if (nCount <= 0) {
cout << "empty" << endl;
return data[0];
}
else {
return data[--nCount];
}
}
};
int main() {
stack<int> stack1;
stack<float> stack2;
int i;
float j;
for (i = 0; i < 10; i++)
stack1.add(i);
for (j = 0; j < 10; j += .4)
stack2.add(j);
for (i = 0; i < 10; i++)
cout << stack1.pop() << " ";
cout << endl;
for (i = 0; i < 10; i++)
cout << stack2.pop() << " ";
}
결과:
9 8 7 6 5 4 3 2 1 0
10 9.6 9.2 8.8 8.4 8 7.6 7.2 6.8 6.4
#include <iostream>
using namespace std;
template<typename TYPE>
class list {
TYPE data;
list* pNext;
public:
list(int a) {
data = a;
pNext = NULL;
}
void add(list* pNode) {
pNode->pNext = this;
pNext = NULL;
}
list* getNext() {
return pNext;
}
int getData() {
return data;
}
};
int main() {
list<int> List1(0);
list<int>* pNode, * pLast;
pLast = &List1;
for (int i = 1; i <= 10; i++) {
pNode = new list<int>(i);
pNode->add(pLast);
pLast = pNode;
}
pNode = &List1;
while (pNode) {
cout << pNode->getData() << endl;
pNode = pNode->getNext();
}
}
• 클래스 외부에서 멤버함수를 정의할 경우 각 멤버함수 전에 template 키워드를 반복해서 써야 합니다.
• 클래스의 멤버십을 지정할 때는 템플릿 클래스임을 명시적으로 기술해야 합니다.template <typename T> class class_name { fuc1(T a); }; … template <typename T> T class_name<type> ::fuc1(T a)