본문 바로가기

Programming/C++ Template

Type Selection

어떤 조건에 따라 컴파일 타임에 두 개의 타입 중 하나를 선택 가능하게 해주는 도구다.

C++ 표준에서는 std::conditional 으로 제공된다. (C++11 이상)

 

template <bool, typename, typename B> struct IF             { using type = B; };
template <typename A, typename B>     struct IF<true, A, B> { using type = A; };

template <bool Condition, typename A, typename B>
using IF = typename IF<Condition, A, B>::type;

 

위와 같이 템플릿 부분 특수화를 사용하여 구현된다. 동작 기준은 템플릿 인자 Condition이 결정한다.

템플릿 인자 Condition의 값이 true이면 A 타입이 선택되고, false이면 B 타입이 선택된다.

 

 

 

template <bool, typename, typename B> struct IF             { using type = B; };
template <typename A, typename B>     struct IF<true, A, B> { using type = A; };

template <bool Condition, typename A, typename B>
using IF = typename IF<Condition, A, B>::type;

int main() {
    IF< true, int, float> val1;
    IF<false, int, float> val2;
    
    cout << typeid(val1).name() << endl;
    cout << typeid(val2).name() << endl;

    return 0;
}

 

위의 코드는 사용 예시로 실제 구현해보면 val1은 int형, val2는 float형을 출력한다.

 

사용시 주의할 점은 템플릿 인수 Condition는 컴파일 타임에 계산될 수 있어야 한다는 점이다.

 

 

Type Selection의 응용으로는 다음과 같이 static array 구현을 예로 들 수 있다.

 

template <typename T, unsigned int N>
class Array {
    using sizeType = IF<(N <= 0xFF),
                        unsigned char,            // if (N <= 255) -> uchar
                        IF<(N <= 0xFFFF),
                           unsigned short,        // else if (N <= 65535) -> ushort
                           unsigned int           // else -> uint
                        >
                     >;

    public:
        ...

    private:
        T mData[N]{ };
        
        sizeType mSize{ };
};

int main() {
    Array<double, 25> arr1;
    Array<float, 654> arr2;
    Array<int, 88888> arr3;

    return 0;
}

 

위 예시에서 Array 클래스 템플릿에 템플릿 인자로 데이터형 T, 크기 N으로 지정해주었다.

N의 크기에 따라서 멤버 변수 mSize의 형식을 최적화하여 사용되므로 사용되는 메모리를 조금이나마 더 줄일 수 있다.

 

동작은 만약 N <= 255 인 경우 unsigned char를, 256 <= N <= 65535 인 경우 unsigned short를,

그 외의 경우 (N > 65535) 에는 unsigned int형으로 mSize의 형식을 결정한다.

 

위 코드에서 중요하게 볼 점은 IF를 여러번 사용할 수 있다는 점이다.

실제로 위 예제를 구현하여 mSize의 형식을 살펴보면 의도한대로 잘 동작한다는 것을 알 수 있다.

 


<type_traits> 파일 내부의 std::conditional 구현 코드


Reference

'Programming > C++ Template' 카테고리의 다른 글

CRTP (Curiously Recurring Template Pattern)  (0) 2024.05.11
Thin Template 기법  (0) 2024.04.28