메타프로그래밍 소개

 

간단하게 설명하면 '코드를 사용해서 코드를 생성하는 기술' 이다.

C++ 템플릿 메타프로그래밍(TMP)은 튜링 완전하다.

재귀를 많이 사용하고 불변 변수를 사용한다.

 

 

매크로를 사용한 코드 전처리

#define MAX(a,b) (((a) > (b)) ? (a) : (b))

C언어에서 사용되던 그 매크로 맞다. 매크로는 전처리기에 의해 컴파일 타임에 실행된다.

위의 코드처럼 매개변수가 있는 C 매크로는 메타함수라고 부르며 메타프로그래밍의 한 예다.

 

 

표준 라이브러리의 템플릿 메타프로그래밍 자세히 보기

컴파일러는 템플릿으로 인스턴스를 생성할 때 코드를 생성한다.

 

 

 

 

템플릿 메타프로그래밍

 

템플릿 메타프로그래밍에서 타입 다루기

매크로는 매개변수가 호환되는 타입인지 확인할 수 없는 반면, 템플릿은 C++ 타입 시스템에 통합되어 있기 때문에 타입 확인이 가능하다.

템플릿 메타프로그래밍을 사용하는 더 좋은 방법은 필요한 타입의 매개변수에 대해서만 동작하도록 코드를 작성하는 것이다.

템플릿 메타프로그래밍은 가변 변수가 없다. 즉, 초기화된 변수의 값을 바꿀 수 없다는 의미이다.

대신 변수에서 필요한 것은 접근할 수 있는 이름이고 typedef(또는 using)로 재정의한 이름을 주로 사용한다.

 

 

템플릿 메타프로그래밍에서 값 처리

template<int A, int B>
struct Multiplexer {
    static const int result = A * B;
    /* enum { result = A * B } */
    /* 이런 방법도 있다 */
};

int i = Multiplexer<2, 3>::result; // 6

 

 

 

템플릿 메타프로그래밍에서 조건 처리

template<typename A, typename B>
struct CheckingType {
    static const int result = 0;
};

template<typename X> // 템플릿 특수화
struct CheckingType<X, X> {
    static const int result = 1;
};


if (CheckingType<UnknownType, int>::result) {
    /* UnknownType이 int면 result가 1이므로 여기 실행 */
}
else {
    /* UnknownType이 int가 아니면 result가 0이므로 여기 실행 */
}

 

 

템플릿 메타프로그래밍에서 재귀 처리

template<int I>
struct factorial {
    static const int value = I * factorial<I - 1>::value;
};

template<>
struct factorial<0> { // 템플릿 특수화
    static const int value = 1;
};

int fact10 = factorial<10>::value;

 

재귀함수에서의 종료 조건은 템플릿 특수화를 통해서 구현할 수 있다.

또한 템플릿 매개변수는 반드시 상수여야만 한다.

당연한 이야기겠지만 컴파일 타임에 코드가 생성되기 때문에 변수가 대입될 수 없다.

+ Recent posts