메타프로그래밍 소개
간단하게 설명하면 '코드를 사용해서 코드를 생성하는 기술' 이다.
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;
재귀함수에서의 종료 조건은 템플릿 특수화를 통해서 구현할 수 있다.
또한 템플릿 매개변수는 반드시 상수여야만 한다.
당연한 이야기겠지만 컴파일 타임에 코드가 생성되기 때문에 변수가 대입될 수 없다.
'도서 > 모던 C++로 배우는 함수형 프로그래밍' 카테고리의 다른 글
동시성을 이용한 병렬 실행 (0) | 2022.12.11 |
---|---|
메타프로그래밍으로 코드 최적화 (2) (0) | 2022.12.11 |
지연 평가로 실행 늦추기 (1) (0) | 2022.12.10 |
재귀 함수 호출 (2) (0) | 2022.12.09 |
재귀 함수 호출 (1) (0) | 2022.12.09 |