[모던C++입문] 3.1 함수 템플릿
- 📕 Book/모던C++입문
- 2021. 7. 9.
제네릭 프로그래밍
함수 템플릿
- 함수 템플릿(Function Template)은 잠재적으로 무한한 함수 오버로드를 생성하는 청사진
int max(int a, int b) { return a > b ? a : b; }
int max(double a, double b) { return a > b ? a : b; }
//위 두개의 함수를 템플릿을 사용하면 아래와 같이 한번만 구현하면 된다
template<typename T>
T max(T a, T b) { return a > b ? a : b; }
//다음 함수는 각 리터럴에 의해 각 타입이 인스턴스화 된다
cout << max(3, 5) << endl; //int max(int, int);
cout << max(3l, 5l) << endl; //long max(long, long);
cout << max(3.0, 5.0) << endl; //double max(double, double);
인스턴스화
- 템플릿은 인수로부터 타입의 매개변수를 추론할 때 인스턴스화 된다.
- 명시적으로 템플릿 매개 변수를 치환하는 타입을 선언하는 방법도 있다.
cout << max<float>(8.1, 9.3) << endl;
매개변수 타입 추론
값 매개변수
//템플릿의 매개변수도 const와 레퍼런스로 한정할 수 있다.
template<typename T>
T max(const T& a, const T& b);
//값을 복사하는 함수 템플릿
template<typename TPara>
void f1(TPara p) {}
int main()
{
int i = 0;
int& j = i;
const int& k = i;
f1(i);
f1(j);
f1(k);
//위 3개의 함수호출은 p타입이 전부 int로 치환된다
}
Lvalue 레퍼런스 매개변수
//상수 레퍼런스를 매개변수로 사용하면 모든 인수를 받을수 있다
template<typename TPara>
void f1(const TPara& p) {}
//그러나 다음과 같은 매개변수가 레퍼런스이면
//모든 리터럴과 임시변수를 거부한다
template<typename TPara>
void f1(const TPara& p) {}
f1(3); //오류 : 'void f1<int>(TPara &)': 인수 1을(를) 'int'에서 'TPara &'(으)로 변환할 수 없습니다.
퍼펙트 포워딩
template<class T>
void f4(T& n) {
std::cout << "l-value" << std::endl;
}
template<class T>
void f4(const T& n) {
std::cout << "r-value" << std::endl;
}
template<class T>
void f5(T&& n) {
f4(std::forward<T>(n));
}
int main() {
int n = 1;
f5(3); //Rvalue
f5(n); //Lvalue
}
템플릿의 오류 처리
std::complex<float> z(3,2), c(4, 8);
std::cout << "The Maximum of c and z is " << ::max(c,z) << std::endl;
//operator> 연산자가 정의되지 않으면 컴파일 오류가 발생한다
타입 혼합하기
int inline max(int a, int b) { return a > b ? a : b; }
unsigned u1 = 2;
int i = 3;
cout << "max is " << max(u1, i) << endl; //에러
cout << "max is " << max(int(u1), i) << endl; //가능
cout << "max is " << max<int>(u1, i) << endl; //가능
유니폼 초기화
- 템플릿에서도 유니폼 초기화가 동작한다
자동 return 타입 (C++14)
template<typename T, typename U>
inline auto max(T a, U b)
{
return a > b ? a : b;
}
반응형