일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- c언어
- 플러터
- C언어 포인터
- 깃
- vim
- c#
- c# 추상 클래스
- Flutter
- 도커
- Algorithm
- dart 언어
- HTML
- C# delegate
- C++
- Houdini
- Unity
- jupyter lab
- docker
- 다트 언어
- c# winform
- Data Structure
- gitlab
- 포인터
- 구조체
- git
- 유니티
- jupyter
- c# 윈폼
- github
- Python
- Today
- Total
nomad-programmer
[Programming/C++] 함수 템플릿과 특수화(Specialization) 본문
함수 템플릿과 템플릿 함수
다음의 정의를 가리켜 '함수 템플릿(Function Template)' 이라 한다.
template <typanme T>
T Add(T num1, T num2) {
return num1 + num2;
}
반면 위의 템플릿을 기반으로 컴파일러가 만들어 내는 다음 유형의 함수들을 가리켜 '템플릿 함수(Template Function)' 이라 한다.
int Add<int>(int a, int b) {
return num1 + num2;
}
double Add<double>(double num1, double num2) {
return num1 + num2;
}
템플릿 함수의 표시에서 <int>와 <double>은 일반함수가 아닌, 컴파일러가 만들어낸 템플릿 기반의 함수임을 표시한 것이다.
- 함수 템플릿
- 함수를 만드는데 사용되는 템플릿
- 템플릿 함수
- 템플릿을 기반으로 만들어진 함수
템플릿 함수의 또 다른 표현
'템플릿 함수'는 컴파일러에 의해 생성된 함수이기 때문에 '생성된 함수(Generated Function)'으로도 불린다.
'템플릿 클래스' 역시 '생성된 클래스(Generated Class)'라고도 불린다.
둘 이상의 형(Type)에 대한 템플릿 선언
템플릿의 정의에는 다양한 자료형의 선언이 가능할 뿐만 아니라, 둘 이상의 형(type)에 대해서 템플릿을 선언할 수도 있따.
template <typename T1, typename T2>
void ShowData(double num) {
cout << (T1)num << ", " << (T2)num << endl;
}
int main(void) {
ShowData<char, int>(65);
ShowData<short, double>(68.8);
return 0;
}
위에서 보듯이 쉼표를 이용해 둘 이상의 템플릿 타입을 명시할수 있다. 그리고 함수 템플릿의 매개변수 조차도 기본 자료형으로 선언될 수 있다.
참고로 위의 문자을 아래처럼 대신할 수 있다.
cout << T1(num) << ", " << T2(num) << endl;
C++에서는 데이터에 소괄호를 묶는 형태로 형 변환을 명령할 수 있다. 아래의 형 변환문은 완전히 일치한다.
int num = (int)3.14;
int num = int(3.14);
typename 키워드 대신 class 키워드를 사용할 수 있다.
함수 템플릿의 특수화(Specialization)
#include <iostream>
#pragma warning(disable: 4996)
using std::cout;
using std::cin;
using std::endl;
template <typename T>
T Max(const T a, const T b) {
return a > b ? a : b;
}
int main(const int argc, const char* const argv[]) {
cout << Max<int>(11, 15) << endl;
cout << Max<char>('T', 'Q') << endl;
cout << Max<double>(3.5, 7.5) << endl;
cout << Max<const char*>("Simple", "Best") << endl;
return 0;
}
/* 결과
15
T
7.5
Simple
*/
위 예제의 함수 템플릿 Max는 인자로 전달된 두 데이터 중 큰 값을 반환하도록 정의되어 있다. 그런데 문자열을 대상으로 호출할 경우, 그 결과에 대해서는 아무런 의미도 부여할 수 없게 된다(단순히 주소 값의 비교결과가 반환).
이렇듯 상황에 따라 템플릿 함수의 구성방법에 예외를 둘 필요가 있는데, 이 때 사용되는 것이 '함수 템플릿의 특수화(Specialization of Function Template)' 이다.
#include <iostream>
#pragma warning(disable: 4996)
using std::cout;
using std::cin;
using std::endl;
template <typename T>
T Max(const T a, const T b) {
return a > b ? a : b;
}
// char* 형에 대해서 특수화
template <>
char* Max<char*>(char* a, char* b) {
cout << "char* Max<char*>(char* a, char* b)" << endl;
return strcmp(a, b) > 0 ? a : b;
}
// const char* 형에 대해서 특수화
template <>
const char* Max<const char*>(const char* a, const char* b) {
cout << "const char* Max<const char*>(const char* a, const char* b)" << endl;
return strlen(a) > strlen(b) ? a : b;
}
int main(const int argc, const char* const argv[]) {
cout << Max<int>(11, 15) << endl;
cout << Max<char>('T', 'Q') << endl;
cout << Max<double>(3.5, 7.5) << endl;
cout << Max<const char*>("Simple", "Best") << endl;
char str1[] = "Simple";
char str2[] = "Best";
cout << endl;
cout << Max<char*>(str1, str2) << endl;
return 0;
}
/* 결과
15
T
7.5
const char* Max<const char*>(const char* a, const char* b)
Simple
char* Max<char*>(char* a, char* b)
Simple
*/
위의 예제에서 template<> 명령은 다음과 같다.
"char*형 함수는 프로그래머가 직접 제시를 하니, char*형 템플릿 함수가 필요한 경우 별도로 만들지 말고 프로그래머가 만든 템플릿 함수를 사용하라." 라는 메시지를 컴파일러에게 알리는 명령이다.
그리고 특수화하는 자료형 정보를 생략하건 생략하지 않건 그 의미하는 바에 차이는 없으나, 가급적이면 자료형 정보를 명시하는 것이 뜻을 명확히 하는 방법이 된다.
template <>
char* Max<char*>(char* a, char* b) { ... }
template <>
const char* Max<const char*>(const char* a, const char* b) { ... }
'Programming > C++' 카테고리의 다른 글
[Programming/C++] 클래스 템플릿의 특수화(Class Template Specialization) (0) | 2021.02.07 |
---|---|
[Programming/C++] 클래스 템플릿(Class Template) (0) | 2021.02.07 |
[Programming/C++] 표준 string 클래스의 분석 (0) | 2021.02.06 |
[Programming/C++] 임시객체로의 자동 형 변환과 형 변환 연산자(Conversion Operator) (0) | 2021.02.05 |
[Programming/C++] ( )연산자의 오버로딩과 펑터(Functor) (0) | 2021.02.05 |