[Basic C++] #55-6_함수 템플릿
C++의 템플릿 중 "함수 템플릿"에 대해 알아보겠습니다.
"전문가를 위한 C"의 11 항목, "템플릿을 이용한 제네릭 코드 작성"에 해당하는 내용입니다.
함수 템플릿
일반 함수를 템플릿 화하는 방법을 알아보겠습니다!
1. 템플릿 함수 예제
static const size_t NOT_FOUND = (size_t)(-1);
template<typename T>
size_t Find(T& val, T* arr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (arr[i] == val)
return i;
}
return NOT_FOUND;
}
위 "Find()" 함수는 특정 값, 배열, 그리고 배열의 크기를 인자로 받아 특정 값과 일치하는 항목을 찾아 인덱스를 반환합니다!
이때, "Find()" 함수를 템플릿으로 작성함으로써, "int" 타입 혹은 "double" 타입의 배열을 받아도 문제없이 함수를 호출할 수 있겠죠!
2. 템플릿 함수 호출 방법
#include<iostream>
using namespace std;
static const size_t NOT_FOUND = (size_t)(-1);
template<typename T>
size_t Find(T& val, T* arr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (arr[i] == val)
return i;
}
return NOT_FOUND;
}
int main()
{
int arr[4] = { 1, 2, 3, 4 };
size_t arrSize = sizeof(arr) / sizeof(int);
size_t res;
// 1. 타입 연역 활용, "<>" 생략한 호출
int val = 3;
res = Find(val, arr, arrSize);
if (res != NOT_FOUND)
cout << res << endl;
// 2. 명시적인 타입 지정으로 호출
int val2 = 4;
res = Find<int>(val2, arr, arrSize);
if (res != NOT_FOUND)
cout << res << endl;
}
템플릿 함수의 호출 방법은 두 가지입니다.
1. auto res = Find(val, arr, arrSize) -> 타입 연역
2. auto res = Find<int>(val, arr, arrSize) -> 타입을 명시적으로 지정
하나는 "타입 연역(Type Deduction)"을 활용하여 "<>"을 생략하고 호출하는 방법,
그리고 다른 하나는 타입을 명시적으로 지정하여 호출하는 방법입니다.
* 추가적으로, 템플릿 함수 또한 템플릿 클래스와 같이 "non-type" 파라미터를 받을 수 있습니다!
템플릿 함수의 특수화
특정 데이터 타입에대한 템플릿 함수의 특수화를 살펴보겠습니다.
1. 템플릿 함수의 특수화
// 원본 템플릿 함수
template<typename T>
size_t Find(T& val, T* arr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (arr[i] == val)
return i;
}
return NOT_FOUND;
}
// string에 대한 특수화
template<>
size_t Find<string>(string& val, string* arr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (arr[i] == val)
return i;
}
return NOT_FOUND;
}
template<>
size_t Find<string>( string str, vector<string> arr, size_t arrSize )
위 코드 예제를 살펴보면, "typename T"를 생략하고, 특수화를 진행할 대상 "타입"을 명시적으로 "<>"안에 작성해주고 있습니다.
2. 특수화 템플릿 호출
int main()
{
vector<string> arr{"one", "two", "three"};
size_t arrSize = arr.size();
string val = "one";
auto res = Find(val, arr, arrSize);
if (res != NOT_FOUND)
cout << res << endl;
}
템플릿 함수의 오버로딩
템플릿 함수 또한 일반 함수와 같이 "오버로딩" 할 수 있습니다.
1. 오버로딩 함수 예제
static constexpr size_t NOT_FOUND = (size_t)(-1);
// 1. 원본 템플릿 함수
template<typename T>
size_t Find(T& val, vector<T> arr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (arr[i] == val)
return i;
}
return NOT_FOUND;
}
// 2. Find<T>() 메서드를 오버로딩한 함수
size_t Find(string& val, vector<string> arr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (arr[i] == val)
return i;
}
return NOT_FOUND;
}
주의할 점은 "타입 연역"으로 템플릿 함수를 호출될 때도 우리가 의도한 템플릿 함수가 호출되려면 "함수 오버로딩"보다 "템플릿 특수화" 버전으로 작성하는 것이 좋습니다.
'언어 > Basic C++' 카테고리의 다른 글
[Basic C++] #56_cctype, 대문자+소문자 확인 (0) | 2022.09.15 |
---|---|
[Basic C++] #55-7_템플릿 변수 (0) | 2022.08.10 |
[Basic C++] #55-5_템플릿 클래스의 파생 클래스, 템플릿 클래스의 상속 (0) | 2022.08.04 |
[Basic C++] #55-4_템플릿 클래스의 특수화, 특정 타입에 대한 템플릿 클래스 (0) | 2022.07.28 |
[Basic C++] #55-3_템플릿 메서드, 이중 템플릿 (0) | 2022.07.27 |