More C++ Idioms (44. Int-To-Type, Int2Type)

2024. 8. 5. 20:20프로그래밍 (확장)/More C++ Idioms

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Int-To-Type

 

More C++ Idioms/Int-To-Type - Wikibooks, open books for an open world

From Wikibooks, open books for an open world Jump to navigation Jump to search To treat an integral constant as a type at compile-time. To achieve static call dispatch based on constant integral values. Integral constant wrappers Function overloading in C+

en.wikibooks.org

 

템플릿 메타프로그래밍에서 자주 사용되는 기술로, C++에서는 정수를 타입으로 변환하여 컴파일 타임에 특정 동작을 수행할 수 있도록 해주는 탬플릿 기법이다.

 

개념적으로 Int To Type은 정수를 타입으로 변환하여, 컴파일 타임에 조건부 로직을 구현, 이를 통해 함수 오버로딩이나 템플릿 특수화를 활용해서, 정수 값에 따라 서로 다른 코드 경로를 선택할 수 있도록 해주는 개념이다.

 

예제 코드는 ChatGPT로 생성:

#include <iostream>

// 템플릿 기법으로 I의 값에 따라 다른 타입을 만들 수 있다.
template <int I>
struct IntToType {
    enum { value = I };
};

void printType(int value, IntToType<1>) {
    std::cout << "Type 1: " << value << std::endl;
}

void printType(int value, IntToType<2>) {
    std::cout << "Type 2: " << value << std::endl;
}

void printType(int value, IntToType<3>) {
    std::cout << "Type 3: " << value << std::endl;
}

int main() {
    int value = 42;

    printType(value, IntToType<1>()); // "Type 1: 42"
    printType(value, IntToType<2>()); // "Type 2: 42"
    printType(value, IntToType<3>()); // "Type 3: 42"

    return 0;
}
Type 1: 42
Type 2: 42
Type 3: 42

위 예제에서 함수 오버로딩에 의해서 타입에 따른 함수가 호출되는 모습을 볼 수 있다.

 

#include <iostream>

template<int I>
struct IntToType {
    enum { value = I };
};

void doSomething(IntToType<1>) {
    std::cout << "Doing something for case 1\n";
}

void doSomething(IntToType<2>) {
    std::cout << "Doing something for case 2\n";
}

int main() {
    doSomething(IntToType<1>()); // Doing something for case 1
    doSomething(IntToType<2>()); // Doing something for case 2

    return 0;
}
Doing something for case 1
Doing something for case 2

컴파일 타임에 결정되는 값을 활용해서 함수를 선택하는 경우로, 응용해서 사용하면 실제 사용하는 함수만 생성되게 하는 형태로 경우에 따라 사용하지 않는 코드를 제외함으로 크기 최적화도 가능할 것 같다.

 

#include <iostream>
#include <array>

template<int I>
struct IntToType {
    enum { value = I };
};

template<typename T, unsigned int N>
class Array : public std::array<T, N> {
    enum AlgoType { NOOP, INSERTION_SORT, QUICK_SORT };
    static const int algo = (N == 0 || N == 1) ? NOOP : (N < 50) ? INSERTION_SORT : QUICK_SORT;

    void sort(IntToType<NOOP>) {
        std::cout << "No sorting needed\n";
    }

    void sort(IntToType<INSERTION_SORT>) {
        std::cout << "Insertion sort\n";
    }

    void sort(IntToType<QUICK_SORT>) {
        std::cout << "Quick sort\n";
    }

public:
    void sort() {
        sort(IntToType<algo>());
    }
};

int main() {
    Array<int, 1> smallArray;
    smallArray.sort(); // No sorting needed

    Array<int, 30> mediumArray;
    mediumArray.sort(); // Insertion sort

    Array<int, 100> largeArray;
    largeArray.sort(); // Quick sort

    return 0;
}
No sorting needed
Insertion sort
Quick sort

특정 케이스(여기서는 배열 크기)에 따른 정렬 알고리즘 선택 예제다. - More C++ Idioms Int-To-Type 참고.

 

활용 예제는 향후 추가 예정.