Произвольный порядок списка инициализации шаблона19.04.2014 17:18
Думаю многие кто работает с шаблонами, знакомы со следующей ситуацией. У нас есть некий шаблонный класс с кучей шаблонных параметров
struct deferred;
struct deadline;
struct disable;
template
struct some_container
Пускай это будет некий интерфейс отложенного выполнения задач (активная очередь). И мы хотим расширить её функционал добавив отложенное выполнение и дедлайны. Но не хотим что бы все это было сразу включено, а хотим что бы можно было собирать нужную конфигурацию под свои нужды. Проблема таких шаблонов (у которых много параметров и почти все уже имею значение по умолчанию) в том, что для того что бы переопределить, скажем, последний параметр нам нужно указать все перед ним стоящие.
typedef some_container deadline_container;
template
struct get_plugin
{
typedef typename get_plugin_impl:: type>:: type type;
};
Это позволит нам из списка типов узнать был ли задан нужный нам тип и если нет, то использовать дефолтное значение. Как видите данный код зависит только от одного типа который участвует в параметризации конечной структуры (и сообщает что мы не используем это конкретный тип), поэтому при добавлении новых шаблонных типов, этот код не будет меняться.На следующем шаге, мы определяем все типы которые используются в конечном шаблоне
template
struct get_plugins
{
typedef typename get_plugin:: type deferred;
typedef typename get_plugin:: type deadline;
};
И это то место, которое будет меняться при добавлении новых шаблонных параметров. Но это происходит предельно легко, и никаких 2^n комбинаций перечислять не надо.Дальше мы вводим прослойку между конечным шаблонным типом и пользователем
template
struct container
{
typedef boost: mpl: set plugin_list;
typedef get_plugins plugs;
typedef typename plugs: deferred deferred;
typedef typename plugs: deadline deadline;
typedef some_container type;
};
Именно она позволяет нам абстрагироваться от числа и порядка указания шаблонных параметров. По сути она объединяет в себе все те (2^n + K) специализаций который нам пришлось бы писать для различного числа заданных шаблонных параметров и их порядка.Возвращаясь нашему шаблонному типу, я покажу вам как это работает
Обратите внимание, что порядок специализации сохранен в нужном виде, не зависимо от того в каком порядке были указаны типы при инстанцировании шаблона.Вот и все, надеюсь кому то это поможет сделать код более красивым и аккуратным.Исходникик: git