📕 Book/모던C++입문

[모던C++입문] 3.1 함수 템플릿

테디슨 2021. 7. 9. 22:53

제네릭 프로그래밍

함수 템플릿

  • 함수 템플릿(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;
}
반응형