일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- AI
- regression
- Classification
- 딥러닝
- 해커톤
- LG Aimers 4th
- LG Aimers
- PCA
- Machine Learning
- 분류
- OpenAI
- 머신러닝
- LLM
- deep learning
- GPT-4
- 회귀
- LG
- supervised learning
- 티스토리챌린지
- 지도학습
- ChatGPT
- 오블완
- gpt
Archives
- Today
- Total
SYDev
C++ Chapter 13-1 : 템플릿(Template)에 대한 이해와 함수 템플릿 본문
함수 템플릿
- 함수 템플릿(function template)은 함수를 만드는 도구이며, 하나의 함수로 다양한 자료형의 함수를 호출할 수 있다.
template <typename T> // template <class T>도 가능
T Add(T num1, T num2)
{
return num1+num2;
}
위 함수의 정의가 함수 템플릿의 예시이다.
- 함수의 기능 : 덧셈
- 대상 자료형 : 결정되지 않음
이처럼 같은 기능을 하는 함수로 여러 자료형을 받고 반환할 수 있게 해주는 것이 함수 템플릿이다.
아래 예제를 살펴보자.
#include <iostream>
using namespace std;
template <typename T>
T Add(T num1, T num2)
{
return num1+num2;
}
int main(void)
{
cout<< Add<int>(15, 20)<<endl; //T를 int로 해서 만들어진 Add 함수 호출, int형 자료에 대한 함수는 이때만 만들어짐
cout<< Add<double>(2.9, 3.7)<<endl; //T를 double로 해서 만들어진 Add 함수 호출, double형 자료에 대한 함수는 이때만 만들어짐
cout<< Add<int>(3.2, 3.2)<<endl; //앞서 만들어놓은 int형 함수 호출
cout<< Add<double>(3.14, 2.75)<<endl; //앞서 만들어놓은 double형 함수 호출
return 0;
}
35
6.6
6 -> int형 함수에 double형 자료를 넣어 값의 손실 발생
5.89
위와 같이 함수 템플릿 기반의 함수는 Add<자료형>(매개변수)로 호출할 수 있다.
이때, 함수는 다음의 형태로 호출되는데, 이를 템플릿 함수(template function)라고 한다.
int Add<int>(int num1, int num2)
{
return num1+num2;
}
double Add<double>(double num1, double num2)
{
return num1+num2;
}
물론, 위 함수 호출문에서 <자료형>부분을 빼고 일반 함수를 호출하듯이 Add(매개변수)의 형태로 호출할 수도 있다. 이 경우에는 컴파일러가 알아서 전달받은 인자의 자료형을 참조하여 호출될 함수의 자료형을 결정한다.
이에 따라 위 예제의 호출문 중 하나인 Add<int>(3.2, 3.2)를 Add(3.2, 3.2)로 바꾸면 실행의 결과로 6.4가 출력된다.
+ 함수를 호출할 때마다 함수를 생성하는 것이 아닌 자료형에 따라 최초 호출시에만 함수 생성, 컴파일 시간이 길어질 뿐 실행 시간은 똑같음.
함수 템플릿과 템플릿 함수
- 함수 템플릿 -> 함수를 만드는데 사용되는 템플릿
- 템플릿 함수 -> 템플릿을 기반으로 만들어진 함수
이렇게 만들어진 템플릿 함수는 일반 함수와 구분되는데, 예제를 통해 살펴보자.
#include <iostream>
using namespace std;
template <typename T>
T Add(T num1, T num2)
{
cout<<"T Add(T num1, T num2)"<<endl;
return num1+num2;
}
int Add(int num1, int num2)
{
cout<<"Add(int num1, int num2)"<<endl;
return num1+num2;
}
double Add(double num1, double num2)
{
cout<<"Add(double num1, double num2)"<<endl;
return num1+num2;
}
int main(void)
{
cout << Add(5, 7) << endl;
cout << Add(3.7, 7.5) << endl;
cout << Add<int>(5, 7) << endl;
cout << Add<double>(3.7, 7.5) << endl;
return 0;
}
Add(int num1, int num2)
12
Add(double num1, double num2)
11.2
T Add(T num1, T num2)
12
T Add(T num1, T num2)
11.2
둘 이상의 형(Type)에 대해 템플릿 선언하기
- 함수 템플릿의 정의에도 다양한 자료형 선언이 가능하다.
- 둘 이상의 type에 대해 템플릿을 선언할 수 있다.
예제를 통해 자세히 살펴보자.
#include <iostream>
using namespace std;
template <class T1, class T2> //둘 이상의 template type 명시 가능
void ShowData(double num) //함수 템플릿의 매개변수, 반환 자료형도 기본 자료형으로 선언 가능
{
cout<<(T1)num<<", "<<(T2)num<<endl; //cout<<T1(num)<<", "<<T2(num)<<endl;과 같은 문장
}
int main(void)
{
ShowData<char, int>(65); //아스키 코드 65번 'A'가 출력
ShowData<char, int>(63); //아스키 코드 63번 '?'가 출력
ShowData<char, double>(126.9); //아스키 코드 126번 '~'가 출력
ShowData<short, double>(69.2);
ShowData<short, double>(70.4);
return 0;
}
A, 65
?, 63
~, 126.9
69, 69.2
70, 70.4
함수 템플릿의 특수화(Specialization)
#include <iostream>
#include <cstring>
using namespace std;
template <typename T>
T Max(T a, T b)
{
return a > b ? a : b ;
/*
삼항 연산자 -> (조건식) ? 반환값1 : 반환값2
조건식의 결과값이 참(1)이면 반환값1 반환, 거짓(0)이면 반환값2 반환
*/
}
int main(void)
{
cout << Max(11, 15) << endl;
cout << Max('T', 'Q') << endl;
cout << Max(3.5, 7.5) << endl;
cout << Max("Simple", "Best") << endl;
return 0;
}
15
T
7.5
Simple
- 위 예제의 함수 템플릿 Max는 전달된 두 데이터 중 큰 값을 반환하도록 정의되어있다.
- 그러나, 15행같은 문자열이 대상으로 주어졌을 때는, 단순히 주소 값의 비교 결과만 나올 뿐이다. 이를 문자열 길이비교와 사전편찬의 순서, 두 가지의 형태로 비교해보자.
#include <iostream>
#include <cstring>
using namespace std;
template <typename T>
T Max(T a, T b)
{
return a > b ? a : b ;
}
template <> //함수 템플릿 특수화
char* Max(char* a, char* b)
{
cout<<"char* Max<char*>(char* a, char* b)"<<endl;
return strlen(a) > strlen(b) ? a : b ;
}
template <> //함수 템플릿 특수화
const char* Max(const char* a, const char* b)
{
cout<<"const char* Max<const char*>(const char* a, const char* b)"<<endl;
return strcmp(a, b) > 0 ? a : b ;
/*
strcmp(a, b)
(1) a < b 인 경우에는 음수 반환
(2) a > b 인 경우에는 양수 반환
(3) a == b 인 경우에는 0을 반환
*/
}
int main(void)
{
cout << Max(11, 15) << endl;
cout << Max('T', 'Q') << endl;
cout << Max(3.5, 7.5) << endl;
cout << Max("Simple", "Best") << endl;
char str1[] = "Simple";
char str2[] = "Best";
cout << Max(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
- 함수 템플릿의 특수화가 진행된 함수의 경우에는 해당 자료형의 템플릿 함수를 별도로 만들지 않고 원래 있던 함수를 호출한다.
참고자료
- 윤성우, <윤성우의 열혈 C++ 프로그래밍>, 오렌지미디어, 2010.05.12
'Programming Lang > C++' 카테고리의 다른 글
C++ Chapter 14-1 : Chapter 13 내용의 확장 (0) | 2023.07.31 |
---|---|
C++ Chapter 13-2 : 클래스 템플릿(Class Template) (0) | 2023.07.28 |
C++ Chapter 12-2 : 문자열 처리 클래스의 정의 (0) | 2023.07.26 |
C++ Chapter 12-1 : C++의 표준과 표준 string 클래스 (0) | 2023.07.26 |
C++ Chapter 11-2 : 배열의 인덱스 연산자 오버로딩 (0) | 2023.07.26 |