Навязчивыйтакже предлагают ассоциативные контейнеры, которые могут быть очень полезны при создании более сложных ассоциативных контейнеров, таких как контейнеры, поддерживающие один или несколько индексов с различной сортировочной семантикой. Повышаю. Интрузивные ассоциативные контейнеры, как и большинство реализаций ассоциативных контейнеров STL, основаны на красно-черных деревьях.
Накладная память этих контейнеров обычно составляет 3 указателя и немного (с проблемами выравнивания это означает 3 указателя и целое число). Этот размер может быть уменьшен до 3 указателей, если указатели имеют четное выравнивание (что обычно верно в большинстве систем).
Размер пустого, непостоянного времени<set>,<multiset>или<rbtree>также имеет размер 3 указателей и целое число (3 указателя при оптимизации для размера. Эти контейнеры имеют логарифмическую сложность во многих операциях, таких как поиск, вставки, стирания и т. Д.<set>и<multiset>являются назойливыми эквивалентами стандартных<std::set>и<std::multiset>контейнеров.
<rbtree>представляет собой набор контейнеров<set>и<multiset>, которые предлагают функции для вставки уникальных и множественных ключей.
<set>,<multiset>и<rbtree>имеют одинаковые крючки. Это преимущество, поскольку один и тот же тип пользователя может быть вставлен сначала в<multiset>, а затем в<set>без изменения определения класса пользователя.
<tag<classTag>>(только для базовых крючков): Этот аргумент служит тегом, поэтому вы можете получить более одного базового крюка. Дефолт:<tag<default_tag>>.
<void_pointer<classVoidPointer>>: Тип указателя, который должен использоваться внутри крючка и распространяться на контейнер. Дефолт:<void_pointer<void*>>.
<optimize_size<boolEnable>>: Крючок будет оптимизирован под размер, а не скорость. Крючок будет вставлять цветной бит красно-черного узла дерева в родительский указатель, если выравнивание указателя равномерно. В некоторых платформах оптимизация размера может немного снизить производительность скорости, поскольку для доступа к родительским указателям и цветовым атрибутам потребуются операции маскировки, в других платформах эта опция повышает производительность благодаря улучшенной локализации памяти. По умолчанию:<optimize_size<false>>.
<base_hook<classHook>>/<member_hook<classT,classHook,HookT::*PtrToMember>>/<value_traits<classValueTraits>>: Чтобы указать тип крючка или характеристики значения, используемые для настройки контейнера. (Чтобы узнать о ценностных чертах, перейдите в разделКонтейнеры с пользовательскими товарными знаками.)
<constant_time_size<boolEnabled>>: Для активации постоянной работы<size()>. Дефолт:<constant_time_size<true>>
<size_type<boolEnabled>>: Указать тип, который будет использоваться для хранения размера контейнера. Дефолт:<size_type<std::size_t>>
Также они могут получить дополнительную опцию:
<compare<classCompare>>: Функция сравнения для объектов, которые вставляются в контейнеры. Сравнительный функтор должен вызывать строгий слабый порядок. Дефолт:<compare<std::less<key_type>>>
<key_of_value<classKeyOfValueFunctionObject>>: Объект функции, который будет определять<key_type>типа значения, которое должно храниться. Этот тип позволит использовать картографический интерфейс.Карта и многокарточный интерфейс с множеством и множествомдля деталей. По умолчанию<key_type>равно<value_type>(набороподобный интерфейс).
Теперь рассмотрим небольшой пример с использованием обоих крючков и обоих контейнеров:
#include<boost/intrusive/set.hpp>#include<vector>#include<functional>#include<cassert>usingnamespaceboost::intrusive;//This is a base hook optimized for sizeclassMyClass:publicset_base_hook<optimize_size<true>>{intint_;public://This is a member hookset_member_hook<>member_hook_;MyClass(inti):int_(i){}friendbooloperator<(constMyClass&a,constMyClass&b){returna.int_<b.int_;}friendbooloperator>(constMyClass&a,constMyClass&b){returna.int_>b.int_;}friendbooloperator==(constMyClass&a,constMyClass&b){returna.int_==b.int_;}};//Define a set using the base hook that will store values in reverse ordertypedefset<MyClass,compare<std::greater<MyClass>>>BaseSet;//Define an multiset using the member hooktypedefmember_hook<MyClass,set_member_hook<>,&MyClass::member_hook_>MemberOption;typedefmultiset<MyClass,MemberOption>MemberMultiset;intmain(){typedefstd::vector<MyClass>::iteratorVectIt;//Create several MyClass objects, each one with a different valuestd::vector<MyClass>values;for(inti=0;i<100;++i)values.push_back(MyClass(i));BaseSetbaseset;MemberMultisetmembermultiset;//Check that size optimization is activated in the base hookassert(sizeof(set_base_hook<optimize_size<true>>)==3*sizeof(void*));//Check that size optimization is deactivated in the member hookassert(sizeof(set_member_hook<>)>3*sizeof(void*));//Now insert them in the reverse order in the base hook setfor(VectItit(values.begin()),itend(values.end());it!=itend;++it){baseset.insert(*it);membermultiset.insert(*it);}//Now test sets{BaseSet::reverse_iteratorrbit(baseset.rbegin());MemberMultiset::iteratormit(membermultiset.begin());VectItit(values.begin()),itend(values.end());//Test the objects inserted in the base hook setfor(;it!=itend;++it,++rbit)if(&*rbit!=&*it)return1;//Test the objects inserted in the member hook setfor(it=values.begin();it!=itend;++it,++mit)if(&*mit!=&*it)return1;}return0;}
Статья Intrusive associative containers: set, multiset, rbtree раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 17. Boost.Intrusive может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.