Menu

템플릿 메타 프로그래밍(Template meta programming)

C++을 먼저 해본 경험이 있어 템플릿 메타 프로그래밍 을 해봤다면, D 언어에도 비슷한 요소가 있기에 마음이 놓일 것입니다.

템플릿 메타 프로그래밍은 타입을 템플릿을 통해 전달해, 실행에 필요한 요소를 미리 결정하여 좀 더 일반화된 동작을 수행할 수 있는 코드를 작성하게 해줍니다.

static ifis (static if & is)

if 는 프로그램 실행 중에 어느 코드를 실행할지 결정할 때 쓰이지만, static if 는 어느 코드를 컴파일해야 할지 결정하는데 쓰입니다.

static if 에서 컴파일될 코드는 오직 컴파일 시점에만 결정되며, 프로그램 실행 중에 결정되는 건 아닙니다.

    static if(is(T == int))
        writeln("T 는 int 타입입니다");
    static if (is(typeof(x) :  int))
        writeln("변수 x는 자동적으로 int로 변환되는 타입의 값입니다.");

is 표현식 을 이용해 컴파일 시점에 타입 제네릭(type generic) 조건을 확인합니다.

    static if(is(T == int)) { // T는 템플릿 파라미터로, 생략된 코드에 정의되어 있습니다
        int x = 10;
    }

일반적으로 { } 코드 블럭은 새 스코프(scope)를 만들지만, static if 는 조건문이 참인 경우 단순히 static if 에 딸려오는 중괄호만을 제거합니다.

만약 static if 를 사용하면서도 새 스코프(scope)를 만들고자하면 { { 로 열고 } } 로 닫아주셔야합니다.

static if 는 함수나 타입 선언부 등 그 어디서든 어디에서든 이용이 가능합니다.

믹스인 템플릿(mixin template)

자주 반복되는 상용구 코드(boiler plate) 를 다듬을 때 mixin template 을 사용하는 걸 권합니다.

    mixin template Foo(T) {
        T foo;
    }
    ...
    mixin Foo!int; // { 와 }가 없어지고, int foo 변수가 선언되어 이용 가능해집니다.

mixin template 으로 if 나 반복문이 포함되는 복잡한 표현도 삽입하실 수 있습니다. C를 사용했던 분이라면, 이제 전처리기(pre-processor)와 이별하고 D 언어를 만나기 딱 좋은 타이밍입니다.

템플릿 제약사항 지정(Template constraints)

템플릿을 작성할 때, 타입이 어떤 속성들을 갖춰야하는지에 대해 여러가지 제약사항을 걸 수 있습니다.

    void foo(T)(T value)
      if (is(T : int)) { // foo!T 는 T가 int 타입으로
                         // 변환될 수 있을 때만 유효합니다
    }

제약사항을 작성할 때 참 또는 거짓으로 결과가 나오는 여러 조건식을 조합할 수 있으며, 컴파일 시점에 결정될 수 있는 트레이트(trait)도 조건식에서 이용할 수 있습니다.

일례로, std.range.primitives.isRandomAccessRange 를 들 수 있습니다. 임의 접근(random access)를 지원하는 범위 탐색 타입인지 확인하는 트레이트인데, 이 임의 접근은 소스 코드 상에서 [] 연산자로 표현됩니다.

더 살펴보기

기본 참고문서(Basics references)

심도 있는 참고문서(Advanced references)

rdmd playground.d