Навязчивыйпредлагает дополнительные крючки с уникальными функциями:
Когда называется деструктор крючка, крюк проверяет, вставлен ли узел в контейнер. Если это так, крючок удаляет узел из контейнера.
Крючок имеет функцию членаunlink(), которые могут быть использованы для удаления узла из контейнера в любое время без какой-либо ссылки на контейнер, если пользователь хочет это сделать.
Эти крючки имеют точно такой же размер накладных расходов, как и их аналоговые неавтоматизированные крючки, но у них есть ограничение: они могут использоваться только снепостоянными контейнерами времени. Для этого есть причина:
Автоматические крючки не хранят никаких ссылок на контейнер, где они вставлены.
Только контейнеры с непостоянным временемразмером()позволяют удалять объект из контейнера без ссылки на контейнер.
Эта функция автоматического отсоединения полезна в некоторых приложениях, но она должна использоватьсяочень осторожно:
Если несколько нитей используют один и тот же контейнер, деструктор крючка автоматического разъединения будет называться без какой-либо синхронизации нитей, поэтому удаление объекта является небезопасным.
Содержимое контейнера изменяется бесшумно без прямого изменения контейнера. Это может привести к удивительным эффектам.
Эти автоматически разъединяющие крючки также обладают безопасными свойствами:
Конструкторы Хукса поместили крючок в известное состояние по умолчанию.
Каждый раз, когда объект вставляется в интрузивный контейнер, контейнер проверяет, находится ли крюк в известном состоянии по умолчанию. Если нет, то высказывается утверждение.
Каждый раз, когда объект стирается из навязчивого контейнера, контейнер помещает стертый объект в известное состояние по умолчанию.
Давайте посмотрим на пример крючка автоматического отсоединения:
#include<boost/intrusive/list.hpp>#include<cassert>usingnamespaceboost::intrusive;typedeflist_base_hook<link_mode<auto_unlink>>auto_unlink_hook;classMyClass:publicauto_unlink_hook//This hook removes the node in the destructor{intint_;public:MyClass(inti=0):int_(i){}intget_int(){returnint_;}voidunlink(){auto_unlink_hook::unlink();}boolis_linked(){returnauto_unlink_hook::is_linked();}};//Define a list that will store values using the base hook//The list can't have constant-time size!typedeflist<MyClass,constant_time_size<false>>List;intmain(){//Create the listListl;{//Create myclass and check it's linkedMyClassmyclass;assert(myclass.is_linked()==false);//Insert the objectl.push_back(myclass);//Check that we have inserted the objectassert(l.empty()==false);assert(&l.front()==&myclass);assert(myclass.is_linked()==true);//Now myclass' destructor will unlink it//automatically}//Check auto-unlink has been executedassert(l.empty()==true);{//Now test the unlink() function//Create myclass and check it's linkedMyClassmyclass;assert(myclass.is_linked()==false);//Insert the objectl.push_back(myclass);//Check that we have inserted the objectassert(l.empty()==false);assert(&l.front()==&myclass);assert(myclass.is_linked()==true);//Now unlink the nodemyclass.unlink();//Check auto-unlink has been executedassert(l.empty()==true);}return0;}
Как пояснялось,Boost.Intrusiveкрючки автосвязи несовместимы с контейнерами, имеющими постоянный размер(), поэтому, если вы попытаетесь определить такой контейнер со значением крючка автосвязи, вы получите статическое утверждение:
error : use of undefined type 'boost::STATIC_ASSERTION_FAILURE<false>'
Указывая на такой код:
//Constant-time size is incompatible with auto-unlink hooks!BOOST_STATIC_ASSERT(!(constant_time_size&&((int)value_traits::link_mode==(int)auto_unlink)));
Таким образом, нет никакого способа компилировать программу, если вы пытаетесь использовать автоматические крючки в контейнерах постоянного размера.
Статья Auto-unlink hooks раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 17. Boost.Intrusive может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.