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

Boost Libraries that work well with Boost.Bimap

Boost , Chapter 1. Boost.Bimap , Bimap and Boost

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

Имя

Описание

автор

Цель

Усиление.

Сериализация для настойчивости и маршализации

Роберт Рэми

Поддержка сериализации контейнеров и итераторов

Назначение

Заполнение контейнеров постоянными или сгенерированными данными никогда не было проще

.

Торстен Оттосен

Помогите заполнить карту или просмотреть ее

Усиление

Объект хэш-функции TR1, который может быть расширен до определенных пользователем типов хеширования

Дэниел Джеймс

Функция хеширования по умолчанию

Boost.Lambda

Определите небольшие неназванные функциональные объекты на фактическом сайте вызова и более

от Jaakko Järvi, Гэри Пауэлл

Функторы для модификации, диапазона, нижнего и верхнего пределов

Рост.Рейндж

Новая инфраструктура для общих алгоритмов, основанная на новых концепциях итератора

Торстен Оттосен

Диапазонные алгоритмы

Усиление.Наставник

BOOST_FOREACH макрос для легкого повторения над элементами последовательности

Эрик Ниблер

Итерация

Рост.Типеоф

Тип эмуляции оператора

Аркадий Вертлейб, Педер Холт

Использование BOOST_AUTO в ожидании C++0x

Boost.Xpressive

Регулярные выражения, которые могут быть написаны как строки или как шаблоны выражения

Эрик Ниблер

Помогите заполнить бимап из струны

Boost.PropertyMap

Концепции, определяющие интерфейсы, которые отображают ключевые объекты на ценные объекты

Джереми Сик

Интеграция с BGL

Бимап можно архивировать и извлекать с помощью Boost. Сериализация библиотеки. Поддерживаются как обычные, так и XML-архивы. Использование является простым и не отличается от любого другого серийного типа. Например:

Перейти к исходному коду

typedef bimap< std::string, int > bm_type;
// Create a bimap and serialize it to a file
{
    bm_type bm;
    bm.insert( bm_type::value_type("one",1) );
    bm.insert( bm_type::value_type("two",2) );
    std::ofstream ofs("data");
    boost::archive::text_oarchive oa(ofs);
    oa << const_cast<const bm_type&>(bm); 1
    2const bm_type::left_iterator left_iter = bm.left.find("two");
    oa << left_iter;
    const bm_type::right_iterator right_iter = bm.right.find(1);
    oa << right_iter;
}
// Load the bimap back
{
    bm_type bm;
    std::ifstream ifs("data", std::ios::binary);
    boost::archive::text_iarchive ia(ifs);
    ia >> bm;
    assert( bm.size() == 2 );
    bm_type::left_iterator left_iter;
    ia >> left_iter;
    assert( left_iter->first == "two" );
    bm_type::right_iterator right_iter;
    ia >> right_iter;
    assert( right_iter->first == 1 );
}

1

Мы должны провести кастинг, потому что буст. Архивы сериализации сохраняют только объекты. Прочитай Буст. Сериализационные документы для обоснования этого решения

2

Мы можем сериализовать итераторы только в том случае, если карта была сериализована первой. Обратите внимание на то, что литье const здесь не требуется, потому что мы создаем наши итераторы как const.

Возможности сериализации автоматически предоставляются путем простого соединения с соответствующим усилителем. Модуль библиотеки сериализации: нет необходимости явно включать любой заголовок из Boost. Сериализация, кроме объявлений типа архива, используемого в процессе. Однако, если не используется, поддержка сериализации может быть отключена путем глобального определения макроса. BOOST_BIMAP_DISABLE_SERIALIZATION. Отключение сериализации для повышения. MultiIndex может дать небольшое улучшение во времени сборки и может быть необходим в тех неисправных компиляторах, которые не могут правильно обрабатывать заголовки Boost.Serialization.

[Warning]Warning

Повышаю. Бимап и Буст. MultiIndex имеет много кода сериализации. Макро<BOOST_BIMAP_DISABLE_SERIALIZATION>отключает сериализацию вобеихбиблиотеках. То же самое происходит, когда<BOOST_MULTI_INDEX_DISABLE_SERIALIZATION>определено.

Получение архивной карты восстанавливает не только элементы, но и порядок их расположения в виде контейнера. Однако есть исключение из этого правила: для неупорядоченных наборов не гарантируется порядок итерации элементов в восстановленном контейнере; в общем, неразумно полагаться на упорядочение элементов хешированного представления, поскольку оно может произвольно изменяться при вставке или перетасовке — именно поэтому хешированные индексы и неупорядоченные ассоциативные контейнеры TR1 не определяют оператора равенства.

Итераторы бимапа также могут быть сериализованы. Сериализация итератора должна производиться только после сериализации соответствующего контейнера.

Цель этой библиотеки состоит в том, чтобы облегчить заполнение контейнеров данными оператором перегрузки и оператором. Эти два оператора позволяют создавать списки значений, которые затем копируются в контейнер.

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

Повышаю. Назначение можно использовать с бимап-контейнерами. Взгляды на бимап совместимы с их стандартными аналогами, поэтому мы можем использовать другие Boost. Назначьте с ними коммунальные услуги.

Перейти к исходному коду

 typedef bimap< multiset_of< int >, list_of< std::string > > bm_type;
 // We can use assign::list_of to initialize the container.
 bm_type bm = assign::list_of< bm_type::relation > 1
     ( 1, "one"   )
     ( 2, "two"   )
     ( 3, "three" );
 // The left map view is a multiset, again we use insert
 assign::insert( bm.left )
     ( 4, "four" )
     ( 5, "five" )
     ( 6, "six"  );
 // The right map view is a list so we use push_back here
 // Note the order of the elements in the list!
 assign::push_back( bm.right )
     ( "seven" , 7 )
     ( "eight" , 8 );
 assign::push_front( bm.right )
     ( "nine"  ,  9 )
     ( "ten"   , 10 )
     ( "eleven", 11 );
// Since it is left_based the main view is a multiset, so we use insert
 assign::insert( bm )
     ( 12, "twelve"   )
     ( 13, "thirteen" );

1

Следует помнить, что<bm_type::relation>следует использовать вместо<bm_type::value_type>. Вопреки<value_type>,<relation>тип сохраняет элементы как non const, требование<assign::list_of>.

Хэш-функция является ядром возможностей быстрого поиска неупорядоченных наборов: хэшер — это просто унарная функция, возвращающая значение std::size_t для любого заданного ключа. В общем, невозможно, чтобы каждая карта ключей имела разное хеш-значение, ибо пространство ключей может быть больше, чем число допустимых хеш-кодов: то, что делает хороший хеш-код хорошим, заключается в том, что вероятность столкновения (два разных ключа с одинаковым хеш-значением) максимально близка к нулю.

Это статистическое свойство в зависимости от типичного распределения ключей в заданном приложении, поэтому невозможно иметь хеш-функцию общего назначения с отличными результатами в каждом возможном сценарии; значение по умолчанию для этого параметра использует Boost. Хэш, который часто дает достаточно хорошие результаты.

Повышаю. Hash может быть расширендля пользовательских типов данных, что позволяет использовать параметр по умолчанию неупорядоченных типов наборов с любыми типами пользователей.

Библиотека Boost Lambda (BLL в продолжении) представляет собой библиотеку шаблонов C++, которая реализует форму абстракций лямбда для C++. Термин происходит от функционального программирования и исчисления лямбда, где абстракция лямбда определяет неназванную функцию. Выражения лямбда очень полезны для построения объектов функций, требуемых некоторыми функциями в виде бимапа.

Повышаю. Bimap определяет новые заполнители в<<boost/bimap/support/lambda.hpp>>, чтобы обеспечить более надежное решение. Заполнители называются _key и _data и оба эквивалентны boost::lambda:::1. Есть две причины для включения этих заполнителей: код выглядит лучше с ними, и они избегают проблемы столкновения между лямбда:: 1 и бустер:: 1 от Boost.Bind.

Go to source code

typedef bimap< std::string, int > bm_type;
bm_type bm;
bm.insert( bm_type::value_type("one",1) );
bm.insert( bm_type::value_type("two",2) );
bm.right.range( 5 < _key, _key < 10 );
bm.left.modify_key( bm.left.find("one"), _key = "1" );
bm.left.modify_data( bm.left.begin(), _data *= 10 );

Повышаю. Range представляет собой набор концепций и утилит, которые особенно полезны для определения и реализации общих алгоритмов. До сих пор общие алгоритмы были определены в терминах двух или более итераторов. Два итератора вместе образуют диапазон значений, на которые может работать алгоритм. Это приводит к очень общему интерфейсу, а также к несколько неуклюжему использованию алгоритмов с избыточной спецификацией имен контейнеров. Поэтому мы хотели бы поднять уровень абстракции для алгоритмов, чтобы они как можно больше конкретизировали свой интерфейс в терминах Диапазонов.

Как Буст. Виды Bimap совместимы со стандартными контейнерными аналогами, они совместимы с концепцией диапазона. В качестве дополнительной функции упорядоченные представления бимап предлагают функцию под названием<range>, которая позволяет получить диапазон значений.

Если у нас есть некоторые общие функции, которые принимают диапазоны:

template< class ForwardReadableRange, class UnaryFunctor >
UnaryFunctor for_each(const ForwardReadableRange & r, UnaryFunctor func)
{
    typedef typename
    boost::range_const_iterator<ForwardReadableRange>::type const_iterator;
    for(const_iterator i= boost::begin(r), iend= boost::end(r); i!=iend; ++i )
    {
        func(*i);
    }
    return func;
}
template< class ForwardReadableRange, class Predicate >
typename boost::range_difference<ForwardReadableRange>::type
    count_if(const ForwardReadableRange & r, Predicate pred)
{
    typedef typename
    boost::range_const_iterator<ForwardReadableRange>::type const_iterator;
    typename boost::range_difference<ForwardReadableRange>::type c = 0;
    for( const_iterator i = boost::begin(r), iend = boost::end(r); i != iend; ++i )
    {
        if( pred(*i) ) ++c;
    }
    return c;
}

Мы можем использовать их с Boost. Бимап с помощью функции<range>.

struct pair_printer
{
    pair_printer(std::ostream & o) : os(o) {}
    template< class Pair >
    void operator()(const Pair & p)
    {
        os << "(" << p.first << "," << p.second << ")";
    }
    private:
    std::ostream & os;
};
struct second_extractor
{
    template< class Pair >
    const typename Pair::second_type & operator()(const Pair & p)
    {
        return p.second;
    }
};
int main()
{
    typedef bimap< double, multiset_of<int> > bm_type;
    bm_type bm;
    bm.insert( bm_type::value_type(2.5 , 1) );
    bm.insert( bm_type::value_type(3.1 , 2) );
    //...
    bm.insert( bm_type::value_type(6.4 , 4) );
    bm.insert( bm_type::value_type(1.7 , 2) );
    // Print all the elements of the left map view
    for_each( bm.left, pair_printer(std::cout) );
    // Print a range of elements of the right map view
    for_each( bm.right.range( 2 <= _key, _key < 6 ), pair_printer(std::cout) );
    // Count the number of elements where the data is equal to 2 from a
    // range of elements of the left map view
    count_if( bm.left.range( 2.3 < _key, _key < 5.4 ),
              bind<int>( second_extractor(), _1 ) == 2 );
    return 0;
}

Перейти к исходному коду

В C++ написание цикла, который повторяется над последовательностью, утомительно. Мы можем либо использовать итераторы, для которых требуется значительное количество котельной пластины, либо мы можем использовать алгоритм std::for_each() и переместить наше тело петли в предикат, который требует не меньше котельной пластины и заставляет нас перемещать нашу логику далеко от того, где она будет использоваться. Напротив, некоторые другие языки, такие как Perl, предоставляют специальную конструкцию «foreach», которая автоматизирует этот процесс. BOOST_FOREACH - это просто конструкция для C++. Он повторяется над последовательностями для нас, освобождая нас от необходимости иметь дело непосредственно с итераторами или писать предикаты.

Вы можете использовать макрос Boost_FOREACH. Виды Бимапа. Сгенерированный код будет таким же эффективным, как и std::for_Every iteration. Вот несколько примеров:

typedef bimap< std::string, list_of<int> > bm_type;
bm_type bm;
bm.insert( bm_type::value_type("1", 1) );
bm.insert( bm_type::value_type("2", 2) );
bm.insert( bm_type::value_type("3", 4) );
bm.insert( bm_type::value_type("4", 2) );
BOOST_FOREACH( bm_type::left_reference p, bm.left )
{
    ++p.second; 1
}
BOOST_FOREACH( bm_type::right_const_reference p, bm.right )
{
    std::cout << p.first << "-->" << p.second << std::endl;
}

1

Мы можем модифицировать нужный элемент, потому что в правой части используется изменяемый тип сбора.

Вы также можете использовать его непосредственно с диапазонами:

BOOST_FOREACH( bm_type::left_reference p,
             ( bm.left.range( std::string("1") <= _key, _key < std::string("3") ) ))
{
    ++p.second;
}
BOOST_FOREACH( bm_type::left_const_reference p,
             ( bm.left.range( std::string("1") <= _key, _key < std::string("3") ) ))
{
    std::cout << p.first << "-->" << p.second << std::endl;
}

Go to source code

Как только C++0x выйдет, мы сможем писать код, например:

auto iter = bm.by<name>().find("john");

Вместо более многословных

bm_type::map_by<name>::iterator iter = bm.by<name>().find("john");

Повышаю. Typeof определяет макрос BOOST_AUTO, который можно использовать в качестве библиотечного решения для ключевого слова авто, пока мы ждем следующего стандарта.

Если у нас есть

typedef bimap< tagged<std::string,name>, tagged<int,number> > bm_type;
bm_type bm;
bm.insert( bm_type::value_type("one"  ,1) );
bm.insert( bm_type::value_type("two"  ,2) );

Следующий сниппет кода

for( bm_type::map_by<name>::iterator iter = bm.by<name>().begin();
     iter!=bm.by<name>().end(); ++iter)
{
    std::cout << iter->first << " --> " << iter->second << std::endl;
}
bm_type::map_by<number>::iterator iter = bm.by<number>().find(2);
std::cout << "2: " << iter->get<name>();

Можно переписать как

for( BOOST_AUTO(iter, bm.by<name>().begin()); iter!=bm.by<name>().end(); ++iter)
{
    std::cout << iter->first << " --> " << iter->second << std::endl;
}
BOOST_AUTO( iter, bm.by<number>().find(2) );
std::cout << "2: " << iter->get<name>();

Перейти к исходному коду

Используя Boost. Впечатляюще мы можем разобрать файл и вставить отношения в карту на том же этапе. Поразительна мощь четырех строк кода. Вот пример (он просто прекрасен).

typedef bimap< std::string, int > bm_type;
bm_type bm;
std::string rel_str("one <--> 1     two <--> 2      three <--> 3");
sregex rel = ( (s1= +_w) >> " <--> " >> (s2= +_d) )
[
    xp::ref(bm)->*insert( xp::construct<bm_type::value_type>(s1, as<int>(s2)) )
];
sregex relations = rel >> *(+_s >> rel);
regex_match(rel_str, relations);
assert( bm.size() == 3 );

Go to source code

Библиотека Boost Property Map состоит в основном из спецификаций интерфейса в виде концепций (аналогично концепциям итератора в STL). Эти спецификации интерфейса предназначены для использования разработчиками общих библиотек при передаче пользователям требований по параметрам шаблонов. В частности, концепции Boost Property Map определяют интерфейс общего назначения для отображения ключевых объектов на соответствующие объекты значений, тем самым скрывая детали того, как отображение реализуется из алгоритмов.

Потребность в интерфейсе карты свойств возникла из библиотеки Boost Graph Library (BGL), которая содержит множество примеров алгоритмов, использующих концепции карты свойств для указания своего интерфейса. Например, обратите внимание на параметр шаблона ColorMap в файле breadth_first_search. Кроме того, BGL содержит множество примеров конкретных типов, реализующих интерфейс карты свойств. Класс adjacency_list реализует карты свойств для доступа к объектам (свойствам), которые прикреплены к вершинам и краям графа.

Противники двух взглядов Бута. Бимап-карта,<set>и<unordered_set>, являются картами свойств чтения-записи. Чтобы использовать их, вам нужно включить один из следующих заголовков:

#include <boost/bimap/property_map/set_support.hpp>
#include <boost/bimap/property_map/unordered_set_support.hpp>

Ниже приведен пример, приведенный в Boost. Документация PropertyMap.

Go to source code

template <typename AddressMap>
void foo(AddressMap & address_map)
{
    typedef typename boost::property_traits<AddressMap>::value_type value_type;
    typedef typename boost::property_traits<AddressMap>::key_type key_type;
    value_type address;
    key_type fred = "Fred";
    std::cout << boost::get(address_map, fred);
}
int main()
{
    typedef bimap<std::string, multiset_of<std::string> > Name2Address;
    typedef Name2Address::value_type location;
    Name2Address name2address;
    name2address.insert( location("Fred", "710 West 13th Street") );
    name2address.insert( location( "Joe", "710 West 13th Street") );
    foo( name2address.left );
    return 0;
}


PrevUpHomeNext

Статья Boost Libraries that work well with Boost.Bimap раздела Chapter 1. Boost.Bimap Bimap and Boost может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Bimap and Boost ::


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 20:44:08/0.034926891326904/1