일반화는 여러 상황에 적용할 수 있는 프로그램 하나를 만들 때 사용할 수 있는 방법입니다. C++는 이런 과정을 템플릿 프로그래밍 혹은 제네릭 프로그래밍이라고 부릅니다.
함수 템플릿
1. 함수 템플릿 사용
함수 템플릿 문법
템플릿 자료형 위치에 플레이스홀더(placeholder)을 사용합니다. T, U, …, Z 등의 플레이스홀더가 실제 자료형으로 대체됩니다.
template<typename T, typename U, ..., typename Z>
T 함수_이름(U first, ... Z last)
{
...
}
템플릿 헤더는 template 키워드와 <> 괄호로 구성됩니다. <> 괄호에는 함수 내부에서 사용할 자료형 목록의 심볼을 지정합니다.
만약 값으로 전달이 아니라 참조로 전달로 코드를 작성하고 싶다면, T를 T&로 변경하기만 하면 됩니다.
/**************************************************************
* 두 값 중에 작은 값을 찾는 *
* 템플릿 함수를 사용하는 프로그램 *
**************************************************************/
#include <iostream>
using namespace std;
// 템플릿 함수 정의
template <typename T>
T smaller(T first, T second)
{
if(first < second)
{
return first;
}
return second;
}
int main()
{
cout << "a와 B 중에 작은 것 = " << smaller('a', 'B') << endl;
cout << "12와 15 중에 작은 것 = " << smaller(12, 15) << endl;
cout << "44.2와 33.1 중에 작은 것 = " << smaller(44.2, 33.1) << endl;
return 0;
}
템플릿 인스턴스화
개별적인 자료형에 대한 함수 정의 생성이 컴파일 시점까지 이루어지지 않으며, 컴파일되는 때에 컴파일러가 함수 호출에 필요한 만큼의 함수들을 만들어냅니다. 이러한 과정을 템플릿 인스턴스화(template instantiation)라고 부릅니다.
2. 함수 템플릿의 변형
자료형이 아닌 템플릿 매개변수
함수 템플릿으로 자료형이 아닌 값을 정의할 수도 있습니다. 이는 매개변수를 전달하는 것과 비슷한 역할을 합니다. 또한 자료형은 고정됩니다.
/**************************************************************
* 모든 자료형과 크기의 배열을 출력하는 *
* 템플릿 함수를 사용하는 프로그램 *
**************************************************************/
#include <iostream>
using namespace std;
// 템플릿 함수 정의
template <typename T, int N>
void print(T(&array) [N])
{
for(int i = 0; i < N ; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
int main()
{
// 배열 생성
int arr1[4] = {7, 3, 5, 1};
double arr2[3] = {7.5, 6.1, 4.6};
// 템플릿 함수 호출
print(arr1);
print(arr2);
return 0;
}
명시적 자료형 결정
cout << smaller(23, 67.2); // T에 대한 자료형이 다르므로 오류
만약 이러한 코드를 동작하게 만들고 싶다면, 괄호 <> 내부에 자료형을 직접적으로 지정하면 됩니다. 이렇게 코드를 작성하면 T가 double로 지정되므로, 23을 23.0으로 변환해서 처리합니다.
cout << smaller<double>(23, 67.2); // 23이 23.0으로 변환되어서 실행
미리 정의된 연산
< 연산자가 오버로드되어 있는 모든 자료형을 사용할 수 있습니다.
예를 들어 라이브러리 string 클래스는 < 연산자를 오버로드하고 있으므로 컴파일할 수 있습니다.
cout << smaller("Hello", "Bi"); // "Bi" 출력
C 문자열과 Rectangle 자료형에는 이러한 연산자 오버로드가 되어있지 않으므로, 이러한 자료형을 smaller 함수에 활용하면 컴파일 오류가 발생합니다. 이러한 문제를 해결하기 위해 특수화를 사용합니다.
특수화
템플릿 자료형이 아니라 특정 자료형으로 다른 함수를 정의해서 활용하는 것입니다.
/**************************************************************
* 템플릿 함수의 특수화를 사용하는 프로그램 *
**************************************************************/
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
// 템플릿 함수 정의
template <typename T>
T smaller(const T& first, const T& second)
{
if(first < second)
{
return first;
}
return second;
}
// 템플릿 함수 특수화
template<>
const char* smaller(const char* const& first, const char* const& second)
{
if(strcmp(first, second ) < 0)
{
return first;
}
return second;
}
int main()
{
// 문자열로 템플릿 함수 호출
string str1 = "Hello";
string str2 = "Hi";
cout << "Smaller(Hello , Hi) = " << smaller(str1, str2) << endl;
// C 문자열로 템플릿 함수 호출
const char* s1 = "Bye";
const char* s2 = "Bye Bye";
cout << "Smaller(Bye, Bye Bye) = " << smaller(s1, s2) << endl;
return 0;
}
이미 정의되어 있는 템플릿 함수의 특수화라는 것을 나타내려면, 함수 앞에 template<>를 사용해야 합니다. 또한, 특수화하려면 모든 T를 같은 자료형으로 변경해야 합니다. C 스타일 문자열은 const char이므로 모든 T 위치에 해당하는 자료형을 const char로 입력해야 합니다.
템플릿의 오버로딩
/**************************************************************
* smaller 템플릿 함수를 오버로딩 하는 프로그램 *
**************************************************************/
#include <iostream>
using namespace std;
// 템플릿 함수 정의
template <typename T>
T smallest(const T& first, const T& second)
{
if(first < second)
{
return first;
}
return second;
}
// 템플릿 함수 정의
template <typename T>
T smallest(const T& first, const T& second, const T& third)
{
return smallest(smallest(first, second), third);
}
int main()
{
// 매개변수가 3개인 형태 호출
cout << "smallest(17, 12, 27) = ";
cout << smallest(17, 12, 27) << endl;
// 매개변수가 3개인 형태 호출
cout << "smallest(8.5, 4.1, 19.75) = ";
cout << smallest(8.5, 4.1, 19.75) << endl;
return 0;
}
출처 : 포르잔 C++ 바이블
'내일배움캠프 > TIL' 카테고리의 다른 글
[내일배움캠프 Day13] C++ 2주차 과제 진행 (1) | 2025.01.03 |
---|---|
[내일배움캠프 Day12] 반복자와 포인터 (2) | 2025.01.02 |
[내일배움캠프 Day10] 메모리 관리 (0) | 2024.12.31 |
[내일배움캠프 Day9] 포인터 (0) | 2024.12.27 |
[내일배움캠프 Day8] C++ 과제 진행 (2) | 2024.12.26 |