Недавно столкнулся с интересной задачей: описанием класса, который инкапсулирует неизвестный заранее набор объектов. Типы этих объектов задаются через 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, конвертируя в нужный тип. Без дополнительных проверок это небезопасно, но если вы знаете, что делаете – очень полезно.

Written by Gecko

Разработчик компьютерной графики

Оставить комментарий

Ваш адрес email не будет опубликован.