Menu

Шаблоны и мета-программирование

Если вы когда-либо сталкивались с мета-программированием на основе шаблонов в C++, вам будет приятно узнать, какие инструменты D предлагает, чтобы упростить вашу жизнь. Мета-программирование на основе шаблонов - техника, позволяющая принимать решения на основе свойств типов, и таким образом делающая обобщённые типы ещё более гибкими, т.к. помогает принимать решения во время инстанцирования.

static if и is

Подобно обычному if, static if компилирует блок кода в зависимости от условия, вычисляемого во время компиляции:

static if(is(T == int))
    writeln("T - это int");
static if (is(typeof(x) :  int))
    writeln("Переменная x может быть " ~
            "неявно преобразована в int");

Выражение is - помощник, вычисляющий выражения во время компиляции.

static if(is(T == int)) { // T - параметр
                          // шаблона
    int x = 10;
}

Фигурные скобки удаляются, если условие истинно - новая область видимости не создаётся. { { и } } явно создают новый блок.

static if можно использовать в разных участках кода - в функциях, в глобальной области видимости, или в теле определения типов.

mixin template

Всякий раз, как вы встречаете избыточный код, на помощь придёт mixin template:

mixin template Foo(T) {
    T foo;
}
...
mixin Foo!int; // с этого момента доступна переменная foo типа int.

mixin template может содержать произвольное количество сложных выражений, которые будут вставлены в месте инстанцирования. Помашите ручкой препроцессору, если вы пришли из C!

Ограничения шаблонов

Шаблону можно указать произвольный набор ограничений, помогающих указать необходимые свойства типов:

void foo(T)(T value)
  if (is(T : int)) { // foo!T принимается
                     // только если T
                     // можно преобразовать
                     // в int
}

Ограничения можно комбинировать в логическое выражение, они могут содержать вызовы функций, которые можно вычислить во время компиляции. Например, std.range.primitives.isRandomAccessRange проверяет, является ли тип диапазоном, поддерживающим оператор [].

Подробнее

Основы

Углублённо

rdmd playground.d