Фокусы с Compound

Недавно столкнулся с интересной задачей: описанием класса, который инкапсулирует неизвестный заранее набор объектов. Типы этих объектов задаются через variadic template – то есть, шаблон с переменным количеством параметров. Статические массивы для этой задачи, ясное дело, не годятся, но тут идеально подошел Compound из dlib.core.compound. Это своеобразный “гибрид” кортежа и структуры – составной тип данных, который можно создавать в шаблонах. Ему можно передавать кортеж параметров variadic-шаблона, и это позволяет проделывать замечательные вещи.


class Collection(C...)
{
protected Compound!C _components;

this(C comps)
{
_components = comps;
}
}

auto inc = new Collection!(int, char, bool)(10, 'a', false);

Проблема с обычными кортежами (Tuple) в том, что их нельзя возвращать из функции. Но Compound – можно. Таким образом, для ридонли-доступа к _components мы можем объявить следующий метод:


auto components() @property
{
return _components;
}

А еще мы можем заполнять Compound в цикле, читая значения, например, из массива:

this(int[] arr)
{
foreach(i, T; C)
{
_components[i] = cast(T)arr[i];
}
}

auto inc = new Collection!(int, char, bool)([5, 40, 0]);

Пример бессмысленный, но наглядный – мы проходим по всем типам кортежа C и записываем входное значение в наш Compound, конвертируя в нужный тип. Без дополнительных проверок это небезопасно, но если вы знаете, что делаете – очень полезно.