Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Notes

Boost , Chapter 1. Fusion 2.2 , Chapter 1. Fusion 2.2

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Recursive Inlined Functions

Интересной особенностью таких функций, как<at>, при применении кForward Sequence, как<list>, является то, что то, что могло бы быть линейной сложностью выполнения, эффективно становится постоянным O(1) из-за оптимизации компилятором встроенных функций C++, хотя и глубоко рекурсивных (до определенного предела компилятора, конечно). Сложность компиляции времени остается линейной.

Overloaded Functions

Ассоциативные последовательности используют перегрузку функций для реализации тестирования членства и поиска связанных ключей. Это равносильно постоянному времени выполнения и амортизированным постоянным сложностям компиляции времени. Есть перегруженная функция<f(k)>, для каждого ключатип<k>. Компилятор выбирает соответствующую функцию, заданную ключом<k>.

Tag Dispatching

Отправка тегов - это общий метод программирования для выбора специализаций шаблонов. Как правило, в механизме отправки тегов участвуют 3 компонента:

  1. Тип, для которого требуется соответствующая специализация шаблона
  2. Метафункция, которая связывает тип с типом тега
  3. Шаблон, который специализируется на типе тега

Например, метафункция синтеза<result_of::begin>реализована следующим образом:

template <typename Sequence>
struct begin
{
    typedef typename
        result_of::begin_impl<typename traits::tag_of<Sequence>::type>::
        template apply<Sequence>::type
    type;
};

В случае:

  1. <Sequence>является типом, для которого требуется подходящая реализация<result_of::begin_impl>.
  2. <traits::tag_of>— это метафункция, которая связывает<Sequence>с соответствующим тегом.
  3. <result_of::begin_impl>является шаблоном, который специализирован для обеспечения реализации для каждого типа тега.

Extensibility

В отличие отMPL, в слиянии нет расширяемой последовательности. Это не означает, что последовательности Fusion не расширяемы. Фактически, все последовательности Fusion по своей сути расширяемы. Просто способ расширения последовательности в Fusion отличается отSTLиMPLиз-за ленивой природы слиянийАлгоритмы.STLконтейнеры расширяются на месте, хотя членские функции, такие как<push_back>и<insert>.MPLпоследовательности, с другой стороны, расширяются через «внутренние» функции, которые фактически возвращают целые последовательности.MPLчисто функциональна и не может иметь побочных эффектов. Например,MPL's<push_back>фактически не мутирует<mpl::vector>. Этого не может быть. Вместо этого он возвращает расширенный<mpl::vector>.

Как иMPL, Fusion тоже чисто функциональна и не может иметь побочных эффектов. С учетом эффективности времени выполнения последовательности Fusion расширяются за счет общих функций, которые возвращаютПросмотры.Видыпредставляют собой последовательности, которые фактически не содержат данных, а вместо этого передают альтернативное представление по данным из одной или нескольких базовых последовательностей.Видыявляются прокси. Они обеспечивают эффективный, но чисто функциональный способ работы с потенциально дорогостоящими операциями последовательности. Например, учитывая<vector>, Fusion<push_back>возвращает<joint_view>, вместо фактического расширенного<vector>. A<joint_view>содержит ссылку на оригинальную последовательность плюс прилагаемые данные, что делает ее очень дешевой для передачи.

Element Conversion

Функции, которые принимают элементарные значения для формирования последовательностей (например,<make_list>), преобразуют свои аргументы во что-то подходящее для хранения в качестве элемента последовательности. В общем, типы элементов хранятся в виде простых значений. Пример:

make_list(1, 'x')

<list><<int, char>>возвращает.

Однако есть несколько исключений.

Решетки:

Аргументы массива выводятся для ссылки на типы const.:

make_list("Donald", "Daisy")

<list>[]

list<const char (&)[7], const char (&)[6]>

Функциональные указатели:

Функциональные указатели выводятся на простой нессылочный тип (т.е. на простой функциональный указатель). Пример:

void f(int i);
  ...
make_list(&f);

<list>[]

list<void (*)(int)>

Reference Wrappers

Функции генерации Fusion (например,<make_list>) по умолчанию хранит типы элементов в виде простых нессылочных типов. Пример:

void foo(const A& a, B& b) {
    ...
    make_list(a, b)

<list>[]

list<A, B>

Иногда простой нессылочный тип нежелателен. Вы можете использовать<boost::ref>и<boost::cref>для хранения ссылок или ссылок (соответственно). Механизм не компрометирует правильность const, поскольку объект const, завернутый ref, приводит к элементу кортежа с эталонным типом const (см. пятую строку кода ниже). Примеры:

Например:

A a; B b; const A ca = a;
make_list(cref(a), b);          // creates list<const A&, B>
make_list(ref(a), b);           // creates list<A&, B>
make_list(ref(a), cref(b));     // creates list<A&, const B&>
make_list(cref(ca));            // creates list<const A&>
make_list(ref(ca));             // creates list<const A&>

См.Boost.Refдля деталей.

Начиная с C++11 работают также стандартные обертки ссылок<std::ref>и<std::cref>.

adt_attribute_proxy

Для адаптации произвольных типов данных, которые не допускают прямого доступа к своим членам, но позволяют косвенный доступ через выражения (такие как вызовы get- и set-методов), может использоваться семейство fusion<BOOST_FUSION_ADAPT_xxxADTxxx>(например,<BOOST_FUSION_ADAPT_ADT>). Чтобы обойти ограничение, не имеющее фактических значений l, которые представляют элементы последовательности синтеза, а скорее последовательность парных выражений, которые получают доступ к элементам, фактический тип возврата функций доступа к внутренней последовательности синтеза<at>,<at_c>,<at_key>,<deref>и<deref_data>является прокси-типом, экземпляром<adt_attribute_proxy>, который инкапсулирует эти выражения.

<adt_attribute_proxy>определяется в пространстве имен<boost::fusion::extension>и имеет три шаблонных аргумента:

namespace boost { namespace fusion { namespace extension
{
    template<
        typename Type
      , int Index
      , bool Const
    >
    struct adt_attribute_proxy;
}}}

При адаптации типа класса<adt_attribute_proxy>специализируется на каждом элементе адаптированной последовательности, причем<Type>является типом класса, который адаптирован,<Index>основанными на 0 индексами элементов и<Const>как<true>, так и<false>. Возвратный тип функции доступа к внутренней последовательности слияния дляNэлемента адаптированного типа класса<type_name>является<adt_attribute_proxy<type_name,N,Const>>, причем<Const>является<true>для постоянных экземпляров<type_name>и<false>для непостоянных.

Notation

type_name

Тип, подлежащий адаптации, с атрибутами M

inst

Объект типа<type_name>

const_inst

Объект типа<type_nameconst>

(attribute_typeN, attribute_const_typeN, get_exprN, set_exprN)

Атрибутный дескрипторNатрибута<type_name>, переданный макросу адаптации, 0≤N

proxy_typeN

<adt_attribute_proxy<type_name,N,false>>сNбудучи интегральной постоянной, 0≤N

const_proxy_typeN

<adt_attribute_proxy<type_name,N,true>>сNбудучи интегральной постоянной, 0≤N

proxyN

Объект типа<proxy_typeN>

const_proxyN

Объект типа<const_proxy_typeN>

Семантика экспрессии

выражение

Семантика

<proxy_typeN(inst)>

Создает экземпляр<proxy_typeN>с базовым объектом<inst>

<const_proxy_typeN(const_inst)>

Создает экземпляр<const_proxy_typeN>с базовым объектом<const_inst>

<proxy_typeN::type>

Другое название<attribute_typeN>

<const_proxy_typeN::type>

Другое название<const_attribute_typeN>

<proxyN=t>

Призывает<set_exprN>, причем<t>является произвольным объектом.<set_exprN>может получить доступ к переменным, названным<obj>типа<type_name&>, которые представляют соответствующий экземпляр<type_name>, и<val>произвольного конст-квалифицированного параметра типа эталонного шаблона<Val>, который представляет<t>.

<proxyN.get()>

Призывает<get_exprN>и пересылает его обратное значение.<get_exprN>может получить доступ к переменной, названной<obj>типа<type_name&>, которая представляет основной экземпляр<type_name>.<attribute_typeN>может указать тип, который<get_exprN>обозначает.

<const_proxyN.get()>

Призывает<get_exprN>и пересылает обратное значение.<get_exprN>может получить доступ к переменной, названной<obj>типа<type_nameconst&>, которая представляет основной экземпляр<type_name>.<attribute_const_typeN>может указать тип, который<get_exprN>обозначает.

Кроме того,<proxy_typeN>и<const_proxy_typeN>являются копируемыми конструируемыми, присваиваемыми копиями и неявно конвертируемыми в<proxy_typeN::type>или<const_proxy_typeN::type>.

[Tip] Tip

Чтобы избежать ловушек прокси-типа, произвольный тип класса также может быть адаптирован непосредственно с использованием внутреннего механизма расширения синтеза.



Обратите внимание, что тип строки буквально представляет собой набор константных символов, а не<constchar*>. Чтобы получить<make_list>, чтобы создать<list>с элементом типа массива, не являющегося константой, необходимо использовать обертку<ref>(см.<ReferenceWrappers>).


PrevUpHomeNext

Статья Notes раздела Chapter 1. Fusion 2.2 Chapter 1. Fusion 2.2 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 1. Fusion 2.2 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-07-05 10:39:56/0.0096299648284912/0