ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [template] 템플릿 특수화
    개발/C·C++ 2021. 5. 1. 13:12

    템플릿은 기본적으로 일반화 프로그래밍(generic programming)을 위해 사용하지만 경우에 따라서는 다른 동작을 해야 한다거나 타입에 따라 효율성을 위해 구현을 달리 해야 하는 상황이 일어날 수 있습니다. STL 중에는 vector가 bool 타입에 대해서만 특수화가 되어 있죠.

    vector<int>
    vector<bool>

    템플릿 특수화는 함수에도 사용할 수 있고 클래스에도 사용할 수 있습니다. 먼저 함수를 살펴보겠습니다. 특수화에는 완전 특수화와 부분 특수화가 있는데, 완전 특수화는 타입을 구체적으로 명시하는 것을 말합니다. 특수화를 할 때는 일반적으로 만들어놓은 템플릿의 형식을 벗어나면 안 됩니다. 다르게 하면 그냥 다른 함수가 되는 것입니다.

    #include <iostream>
    using std::cout;
    using std::endl;
    
    class Class
    {};
    
    // 기본이 되는 함수 템플릿
    // 파라미터를 레퍼런스로 받음
    template<typename T>
    void swap(T& x, T& y)
    {
        cout << "swap reference" << endl;
        T temp = x;
        x = y;
        y = temp;
    }
    
    // 특수화
    template<>
    void swap(Class& x, Class& y)
    {
        cout << "swap Class" << endl;
    }
    
    /* 포인터로 받을 템플릿을 정의하고 싶다면
    *  T* 형태로 파라미터를 선언해야 하므로
    *  특수화가 아니라 오버로딩이 된다
    */
    template<typename T>
    void swap(T* x, T* y)
    {
        cout << "swap pointer" << endl;
    }
    
    int main()
    {
        Class c0, c1;
        swap(c0, c1); // 특수화된 템플릿과 매칭
        int x = 40, y = 10;
        swap(x, y);   // 기본 함수 템플릿과 매칭
    }

    함수를 호출할 때 구체적인 템플릿과 매칭됩니다. c0, c1 객체는 함수 템플릿에 파라미터가 Class 타입이 있기 때문에 특수화된 템플릿과 연결되며, 정수형 x, y 변수는 Class 타입과는 거리가 멀기 때문에 기본 함수 템플릿과 연결됩니다. 다음은 클래스입니다. 객체를 만들고 멤버 변수를 통해 매칭된 클래스를 확인하기 위해 멤버 변수는 public 안에 정의했습니다. 그 밑으로 특수화된 클래스가 있습니다. 당연한 이야기인데, 템플릿 특수화를 하려면 기본 템플릿이 있어야 합니다. 특수화에 필요한 재료인 거죠. 예제에서 기본 클래스 템플릿을 지워서 확인해볼 수 있습니다.

    #include <iostream>
    using std::cout;
    using std::endl;
    
    // 기본 클래스 템플릿
    template<typename T, typename S>
    class Class
    {
    public:
        T t;
        S s;
    }
    
    // 완전 특수화
    template<>
    class Class<int, float>{};
    
    // 부분 특수화
    template<typename T>
    class Class<T, T>
    {
    public:
        T num;
    };
    
    template<typename T>
    class Class<T, int>
    {
    public:
        T a;
    };
    
    template<>
    class Class<float, int>
    {
    public:
        float b;
    };
    
    int main()
    {
        Class<int, float> t0; // 기본 템플릿이 아니라 특수화 템플릿으로 매칭
        Class<float, int> t1; // 기본 템플릿이 아니라 특수화 템플릿으로 매칭
        // Class<int, int> t2;   // 오류 발생. <T, int>와 <T, T>에서 무엇을 호출할지 모호
    }

     

    댓글

Designed by Tistory.