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

    제네릭 프로그래밍

    함수 템플릿

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

    댓글

    Designed by JB FACTORY