dlib: практикум

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


Copyright © 2008-2023 Тимур Гафаров и соавторы. Доступно по СС BY-NC-SA 3.0.