Если вы когда-либо сталкивались с мета-программированием на основе шаблонов в 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
проверяет, является ли тип диапазоном, поддерживающим оператор []
.