함수 템플릿
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 64번째.
두 integers의 maximum을 find하는 function을 작성한 다음, doubles와 strings에도 동일한 로직이 필요하다는 사실을 깨닫는 상황을 상상해 보세요. 템플릿이 없다면 각 타입에 대해 거의 동일한 function을 작성해야 합니다. Function 템플릿은 로직을 한 번만 작성하면 컴파일러가 타입별 버전을 자동으로 생성하도록 하여 이 문제를 해결합니다.
함수 템플릿은 template 키워드 뒤에 꺾쇠괄호로 묶인 템플릿 매개변수를 사용합니다:
template <typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}
int main() {
std::cout << maximum(5, 3) << std::endl; // int 버전 사용
std::cout << maximum(3.14, 2.71) << std::endl; // double 버전 사용
std::cout << maximum('a', 'z') << std::endl; // char 버전 사용
}컴파일러는 각 호출을 검사하고 해당 특정 타입에 대한 구체적인 function을 생성합니다. 이 과정을 템플릿 인스턴스화라고 합니다. 필요할 때는 타입을 명시적으로 지정할 수도 있습니다:
std::cout << maximum<double>(5, 3.14) << std::endl; // double 버전을 강제합니다템플릿에는 여러 타입 매개변수가 있을 수 있으므로 더욱 유연한 설계가 가능합니다.
template <typename T, typename U>
void printPair(T first, U second) {
std::cout << first << ", " << second << std::endl;
}
printPair(42, "hello"); // T=int, U=const char*
printPair(3.14, 100); // T=double, U=int함수 템플릿은 컴파일 시간 다형성을 제공합니다. 즉, 타입은 런타임이 아니라 코드가 컴파일될 때 결정됩니다. 따라서 가상 함수와 비교해 런타임 오버헤드가 전혀 없으므로, 템플릿은 성능이 중요한 제네릭 코드에 이상적입니다.
챌린지
쉬움호환되는 모든 유형에서 작동하는 재사용 가능한 연산을 만들기 위해 함수 템플릿을 사용하는 유틸리티 도구 모음을 만들어 보겠습니다. 제네릭 함수를 헤더 파일에 구성하고, main 프로그램에서 그 유연성을 보여 줍니다.
두 개의 파일을 만듭니다.
MathUtils.h: 일반적인 연산을 수행하는 함수 템플릿 모음을 Define합니다.minimum: 동일한 유형의 두 값을 받아 더 작은 값을 Returns하는 템플릿 함수입니다.clamp: 세 개의 parameters, 즉 값, low bound, high bound를 받는 템플릿 함수입니다. bounds 내에 constrained된 값을 Returns합니다(value가 low보다 작으면 low를, value가 high보다 크면 high를, 그렇지 않으면 value 자체를 Returns합니다).swapValues: 동일한 유형의 두 references를 받아 해당 값들을 exchanges하는 템플릿 함수입니다.main.cpp: 여섯 개의 inputs를 읽습니다(각각 별도의 줄에 입력).- 첫 번째 integer
- 두 번째 integer
- clamp할 double 값
- Low bound (double)
- High bound (double)
- 문자 하나
다음과 같이 템플릿을 시연합니다.
- 두 integers의 minimum을 찾아 다음을 출력합니다:
Min of <a> and <b>: <result> 'm'과 입력 character의 minimum을 찾아 다음을 출력합니다:Min of m and <char>: <result>- double 값을 clamp하고 다음을 출력합니다:
Clamp <value> to [<low>, <high>]: <result> - 첫 번째 integer를 range [0, 100]으로 clamp하고 다음을 출력합니다:
Clamp <value> to [0, 100]: <result> - 두 integers를 swapping하고 다음을 출력합니다:
After swapValues: <a>, <b>
예를 들어 inputs가 25, 10, 3.7, 1.0, 5.0, z인 경우:
Min of 25 and 10: 10
Min of m and z: m
Clamp 3.7 to [1, 5]: 3.7
Clamp 25 to [0, 100]: 25
After swapValues: 10, 25각 함수 템플릿이 integers, doubles, characters와 원활하게 작동하는 방식을 확인하세요. 컴파일러는 사용하는 각 유형에 적합한 버전을 생성합니다. swapValues 함수는 references를 통해 원래 variables를 수정해야 하며, 이를 통해 템플릿이 일반 함수와 마찬가지로 reference parameters와 함께 작동한다는 것을 보여 줍니다.
직접 해보기
#include <iostream>
#include "MathUtils.h"
using namespace std;
int main() {
// 입력 읽기
int a, b;
double value, low, high;
char ch;
cin >> a;
cin >> b;
cin >> value;
cin >> low;
cin >> high;
cin >> ch;
// TODO: 두 정수의 최솟값을 찾기 위해 minimum 템플릿 사용
// 출력: "Min of <a> and <b>: <result>"
// TODO: 'm'과 입력 문자의 최솟값을 찾기 위해 minimum 템플릿 사용
// 출력: "Min of m and <char>: <result>"
// TODO: double 값에 clamp 템플릿 사용
// 출력: "Clamp <value> to [<low>, <high>]: <result>"
// TODO: 범위 [0, 100]인 첫 번째 정수에 clamp 템플릿 사용
// 출력: "Clamp <value> to [0, 100]: <result>"
// TODO: 두 정수에 swapValues 템플릿 사용
// Print: "After swapValues: <a>, <b>"
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러