Minwoo Dev.
[C++] 템플릿(Template), 템플릿 특수화(Specialization) 본문
프로그램을 작성하다 보면 자료형에 따라 여러 개의 함수를 만들어야 하는 상황이 발생한다.
예를 들어서 덧셈 연산을 하는 프로그램이 있다고 하자.
#include<iostream>
using namespace std;
int Add(int n1, int n2){
cout << "Add(int n1, int n2)" << endl;
return n1 + n2;
}
double Add(double e1, double e2){
cout << "double Add(double e1, double e2)" << endl;
return e1 + e2;
}
int main(void){
double a = 2.14;
double b = 5.3;
cout << Add(a, b) << endl;
return 0;
}
실행 결과
위 코드에서는 double 타입의 두 변수를 사용하여 Add 함수를 호출하였다.
함수는 매개변수에 따라서 오버로딩이 가능하기에, 우리가 int형 변수 두 개의 덧셈을 계산하려면 위처럼 int 형의 Add 함수를 하나 더 작성해야한다.
이렇게 사용하려는 변수의 타입마다 함수를 하나씩 작성한다면 굉장히 번거로울 것이다.
이럴 때 우리는 템플릿(Template)을 사용하여 코드를 간단히 나타낼 수 있다.
템플릿(Template)
템플릿 이라는 단어는 액자, 틀 이라는 뜻을 가지고 있다.
- 타입을 결정하지 않고 틀만 작성하여 나중에 컴파일러가 알아서 해당하는 타입의 함수를 만들어 사용하는 방식이다.
기본적인 형식은 아래와 같다.
template<typename T>
T 함수이름 (T 매개변수1, T 매개변수2, ...){
함수 내용
}
꼭 위의 형식이 아니더라도, 템플릿 변수 T에 의해 변수 타입이 정해지도록 하고싶은 부분에 T를 적어주면 된다.
사용할 때는 아래와 같은 형식으로 사용한다.
함수이름<타입>(매개변수, ...);
위의 Add 함수를 사용하여 에제 코드를 보이겠다.
#include<iostream>
using namespace std;
template<typename T>
T Add(T n1, T n2){
return n1 + n2;
}
int main(void){
double a = 2.14;
double b = 5.3;
cout << Add<double>(a, b) << endl;
return 0;
}
실행 결과
Add<double>()을 사용하여 사용할 템플릿 변수가 double 타입이라는 것을 명시하였다.
+) 함수 호출에서 타입 명시의 생략
<> 안에 들어가는 타입을 생략할 수도 있다.
#include<iostream>
using namespace std;
template<typename T>
T Add(T n1, T n2){
return n1 + n2;
}
int main(void){
double a = 2.14;
double b = 5.3;
cout << Add(a, b) << endl; // <double> 생략!
return 0;
}
실행 결과
템플릿 변수의 특수화
위와 같이 템플릿을 사용하여 함수를 만들 때, 어떤 타입은 일반적인 덧셈과 다르게 해야하는 상황이 있을 것이다.
예를 들어서 char* 형이 있다.
#include<iostream>
using namespace std;
template<typename T>
T Add(T n1, T n2){
return n1 + n2;
}
int main(void){
char *a = "I love ";
char *b = "You.";
cout << Add(a, b) << endl;
return 0;
}
위 코드에서 보듯이, 문자열 두 개를 덧셈한다면 어떻게 되겠는가 ?
Java와 같은 언어들에서는 문자열의 덧셈이 이어지겠지만, C++에서는 문자열 두 개의 덧셈은 문자열이 하나로 합쳐지지 않는다.
실행 결과
따라서 우리는 템플릿 변수에서 char* 에 해당하는 부분만 편집해줘야 할 것이다.
이렇게 특정 자료형의 함수만 수정해주는 것을 템플릿 특수화라고 한다.
코드에서 char* 에 해당하는 함수만 따로 구현해준다면 템플릿 특수화를 진행한 것이다.
#include <iostream>
#include <cstring>
using namespace std;
template<typename T>
T Add(T n1, T n2){
return n1 + n2;
}
template<> // 템플릿 특수화 부분
char* Add(char* n1, char* n2){
char* result = new char[strlen(n1) + strlen(n2) + 1];
strcpy(result, n1);
strcat(result, n2);
return result;
}
int main(void){
char a[] = "I love ";
char b[] = "You.";
char* result = Add(a, b);
cout << result << endl;
delete[] result;
return 0;
}
실행 결과
템플릿 특수화는 위처럼 template<>를 작성하고, 그 아래에 정해진 타입의 함수 내용을 수정하여 작성하면 된다.
위와 같은 경우에, char* 타입이라고 컴파일러가 인식하게 되면 특수화된 템플릿으로 만들어진 함수를 호출하게 될 것이다.
'C++' 카테고리의 다른 글
[C++] 예외처리 try, catch, throw (0) | 2024.07.24 |
---|---|
[C++] 템플릿의 부분 특수화 (0) | 2024.07.24 |
[C++] 윤성우의 열혈 C++ 13-2 클래스 템플릿의 정의 문제풀이 (2) | 2024.07.23 |
[C++] 윤성우의 열혈 C++ 13-1 함수 템플릿의 정의 문제풀이 (0) | 2024.07.23 |
[C++] 포인터 연산자 오버로딩, operator*, operator-> (2) | 2024.07.23 |