![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Determine the Type of the Iterator of a ContainerBoost , Spirit 2.5.2 , Extract Attribute Values to Generate Output from a Container (Karma)
|
![]() | Note |
---|---|
Этот файл заголовка не должен быть включен непосредственно любой пользовательской программой, поскольку он обычно включен другими файлами заголовка Spirit, основанными на его содержании. |
Имя |
---|
|
template <typename Container, typename Enable> struct container_iterator { typedef <unspecified> type; };
Параметр |
Описание |
По умолчанию |
---|---|---|
Container | Тип, |
|
| Шаблон-помощник используется для выборочного включения или отключения определенных специализаций | |
Notation
C
Тип контейнера, для которого требуется оценка типа итератора.
Выражение |
Семантика |
---|---|
| Результат метафункции, которая оценивает тип, который будет использоваться в качестве итератора для доступа ко всем элементам контейнера, |
Вернутый тип концептуально должен быть эквивалентен стандартному переднему итератору. Но он не должен раскрывать стандартизированный интерфейс. Если эта точка настройки реализована для определенного типа контейнера, все соответствующие точки настройки также должны быть реализованы (см. Related Attribute Customization Points ниже). Это инкапсулирует конкретный интерфейс итератора, необходимый для данного типа. Минимальные требования для типа, который должен быть выставлен в качестве итератора в этом контексте:
traits::compare_iterators
),лоты::next_iterator
),traits::deref_iterator
).Спирит предопределяет специализации этой точки настройки для нескольких типов. В следующей таблице перечислены эти типы вместе с типами, возвращенными встроенным тип-дефицитом type
:
Параметры шаблона |
Семантика |
---|---|
| Возвращение |
| Возвращение |
| Возвращение |
Точка настройки контейнер_итератор
должна быть реализована для конкретного типа всякий раз, когда этот тип будет использоваться в качестве атрибута вместо контейнера STL. Он применим только для генераторов (Spirit.Karma). Как правило, он должен быть реализован всякий раз, когда определенный тип должен быть передан в качестве атрибута генератора, обычно обнажающего контейнер STL, C
и если тип не выставляет интерфейс контейнера STL (т.е. is_container<C>::type
обычно возвращает mpl::false_>>.
Если эта точка настройки будет реализована, могут потребоваться также следующие другие пункты настройки.
Имя |
Когда реализовать |
---|---|
Должны быть реализованы всякий раз, когда тип должен использоваться в качестве контейнерного атрибута в Karma. | |
Карма: List ( | |
Карма: List ( | |
Карма: List ( | |
Карма: List ( | |
Карма: List ( | |
Карма: List ( |
Вот файлы заголовка, необходимые для составления примерного кода ниже компиляции:
#include <boost/spirit/include/karma.hpp> #include <iostream> #include <vector>
Пример (для полного исходного кода см. здесь: customize_embedded_container.cpp) использует структуру данных
namespace client { struct embedded_container { // expose the iterator of the embedded vector as our iterator typedef std::vector<int>::const_iterator iterator; // expose the type of the held data elements as our type typedef std::vector<int>::value_type type; // this is the vector holding the actual elements we need to generate // output from std::vector<int> data; }; }
как прямой контейнерный атрибут List (%
) генератор. Для того, чтобы сделать эту структуру данных совместимой, нам нужно специализируется на нескольких пунктах настройки атрибутов: traits::is_container
, traits::container_iterator
>,>traits> Как вы можете видеть, специализации просто разоблачают встроенную
, std::vector<int>
как контейнер для использования. Нам не нужно специализироваться на настройках, связанных с итераторами (traits::
deref_iteratortraits::next_iterator
, и traits::compareerators
), так как мы разоблачаем стандартный его и по умолчанию внедрение этих настраиваемых устройств обрабатывает стандартный установщик.
// All specializations of attribute customization points have to be placed into // the namespace boost::spirit::traits. // // Note that all templates below are specialized using the 'const' type. // This is necessary as all attributes in Karma are 'const'. namespace boost { namespace spirit { namespace traits { // The specialization of the template 'is_container<>' will tell the // library to treat the type 'client::embedded_container' as a // container holding the items to generate output from. template <> struct is_container<client::embedded_container const> : mpl::true_ {}; // The specialization of the template 'container_iterator<>' will be // invoked by the library to evaluate the iterator type to be used // for iterating the data elements in the container. We simply return // the type of the iterator exposed by the embedded 'std::vector<int>'. template <> struct container_iterator<client::embedded_container const> { typedef client::embedded_container::iterator type; }; // The specialization of the templates 'begin_container<>' and // 'end_container<>' below will be used by the library to get the iterators // pointing to the begin and the end of the data to generate output from. // These specializations simply return the 'begin' and 'end' iterators as // exposed by the embedded 'std::vector<int>'. // // The passed argument refers to the attribute instance passed to the list // generator. template <> struct begin_container<client::embedded_container const> { static client::embedded_container::iterator call(client::embedded_container const& d) { return d.data.begin(); } }; template <> struct end_container<client::embedded_container const> { static client::embedded_container::iterator call(client::embedded_container const& d) { return d.data.end(); } }; }}}
Последний фрагмент кода показывает пример с использованием экземпляра структуры данных client::embedded_container
для получения выхода из List (%
) генератор:
client::embedded_container d1; // create some test data d1.data.push_back(1); d1.data.push_back(2); d1.data.push_back(3); // use the instance of an 'client::embedded_container' instead of a // STL vector std::cout << karma::format(karma::int_ % ", ", d1) << std::endl; // prints: '1, 2, 3'
Как вы можете видеть, специализация точек настройки, как определено выше, обеспечивает плавную интеграцию пользовательской структуры данных без необходимости изменения формата вывода или самого генератора.
Для других примеров использования точки настройки container_iterator
см. здесь: use_as_container и counter_example.
Статья Determine the Type of the Iterator of a Container раздела Spirit 2.5.2 Extract Attribute Values to Generate Output from a Container (Karma) может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Extract Attribute Values to Generate Output from a Container (Karma) ::
реклама |