템플릿 메타프로그래밍

Template Metaprogramming. 템플릿을 이용해 메타 프로그래밍을 하는 것을 뜻한다. 쉽게 말하면, 언어에서 제공해주는 기능인 템플릿(틀)을 이용해, 프로그램을 작성하는 부분을 프로그래밍하는 하는 것인데, 템플릿 기능이 있는 가장 대표적인 언어가 C++라 C++에 관련된 토픽으로 분류되는 경우가 많다.

보통 말하는 C++에서의 템플릿 메타 프로그래밍이란, 템플릿을 이용하여 컴파일 타임에 코드를 생성하는 것을 말한다. 보통 함수형 프로그래밍 방식으로 개발하며, 일반화 프로그래밍이 가능하다는 장점이 있다.

예제[편집 | 원본 편집]

int Fibo(int n)// 재귀 함수
{
    if(n <= 1) return 1;
    return Fibo(n-1) + Fibo(n-2);
}

// 템플릿 메타 프로그래밍
template <int N>
struct Fibo
{
    enum{
        value = Fibo<N-1>::value + Fibo<N-2>::value
    }
}

template <>
struct Fibo<0>
{
    enum{
        value = 1
    }
}

template <>
struct Fibo<1>
{
    enum{
        value = 1
    }
}

재귀항수를 이용한 방법은 런타임에 콜스택을 늘려가며 계산해야 하지만, 템플릿 메타 프로그래밍을 이용한 방법은, N값이 컴파일타임에 결정된다면 컴파일타임에 Fibo<N>이 계산된다.

방법[편집 | 원본 편집]

주로 재귀적 성질을 이용한 함수형 프로그래밍을 사용한다. 템플릿의 비 타입 인자에는 컴파일 타임에 값을 알 수 있는 값만 넣을 수 있다. 주의할 점 중 하나는, 상수 포인터는 비타입 인자가 될 수 있지만 const char*는 예외적인 경우가 있다. 비타입 인자가 const char*형일 때, 같은 문자열을 넣어도 주소값이 다를 수 있기 때문에, extern 키워드를 사용하거나 일종의 꼼수를 써야 한다.

위의 예제와 같이, 좀 더 일반적인 템플릿 인자(위에서는 template <int N> ~~)를 가진 형태와 경계 조건일 때의 인자(template<>~~)를 가진 형태로 나누어서 프로그래밍하게 되는데, 위쪽에 일반적인 형태를 선언한다.

원리[편집 | 원본 편집]

템플릿의 확장은 컴파일 타임에 이루어진다. 컴파일러 최적화가 더디던 시절에는, 컴파일을 하는 도중 템플릿을 만나면 현재까지 알고 있는 심볼 등을 확인하면서 알 수 있는 내용을 가지고 익명 함수 등을 만들며 원시 C++ 코드를 작성해나갔다. 이런 과정이 끝나고 템플릿이 모두 전개되었다면 그때부터 원래 코드를 컴파일하기 시작했다. 지금은 이 과정에서 최적화 등을 사용하는 경우가 많은 편.

장점[편집 | 원본 편집]

  • 원래 언어에 있는 기능이다. 메타 프로그래밍이 보통 스크립트 언어 등으로 다른 언어를 붙여서 써야하는 경우가 많은데 반해서, C++ 언어에 원래 정의된 것을 가지고 구현하기 때문에, C++ 규격의 변화에만 대응하면 된다.
  • 런타임의 시간 복잡도를 줄일 수 있다. 컴파일 타임에 모든 것이 이루어지기 때문에 런타임 복잡도가 줄어들어 실행시간 등이 감소할 여지가 많다.
  • 무결성. 소스 코드의 재활용 등으로 복붙 등의 과정을 줄일 수 있어 무결성 및 관리성이 높아진다.

단점[편집 | 원본 편집]

  • 템플릿을 떡칠하면 알아보기 힘들다. 일반적으로 인간의 두뇌는 이러한 확장 과정에 익숙하지 않은 편[1]이다. 특히 디버그하는 과정에서 템플릿을 떡칠하다보면 환장하는 경우가 꼭 한 번씩은 있을 것이다.
  • 컴파일 복잡도가 늘어난다. 이게 문제가 되는 건 소규모 프로그램보다는 주로 대형 프로젝트 쪽. 그잖아도 컴파일에 수 시간 걸리는 프로젝트에 템플릿 메타프로그래밍을 쓴다면?
  • 프로그램이 커진다. 지금이야 용량이 문제가 되는 시대가 아니긴 하지만, 컴파일 시간에 코드를 확장하면서 길이가 늘어나기 때문에 프로그램이 쉽게 커질 수 있다. 다행히 용량에 민감한 임베디드 쪽은 C++을 많이 쓰지 않는다고는 하지만. 또한 길이가 길어지면서 자연스럽게 프로그램 로딩 속도도 길어진다는 점도 나름의 문제점이다.

추가바람

  1. 클래스 등에서 상속이 일어나는 경우를 생각해보면 된다. 물론 인간의 신경 등이 아날로그 위주로 발달하다보니 아날로그 신호 등(이미지라든지 소리)에 대해서는 나름 이해가 빠르지만, 클래스나 템플릿에 대해서는 원래 있던 내용을 머리에 담고서 생각해야 되기 때문에, 2중, 3중이 되면 모든 정보를 다 담지 않으면 파악이 힘들어지면서 두뇌에 부하가 걸리는 것.