Boost C++ 库

...世界上最受推崇和设计最精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

PrevUpHomeNext

擦除和处置 Boost.Intrusive 容器中的值

当使用侵入式容器时,最繁琐的任务之一是对已擦除元素的管理。当使用 STL 容器时,容器本身会解除链接并销毁包含的元素,但是对于侵入式容器,用户必须在从容器中擦除元素后显式销毁该对象。这使得类似 STL 的函数擦除多个对象变得无用:用户无法销毁每个擦除的元素。例如,我们来看一下 remove_if 函数,它来自 list

template<class Pred>
void remove_if(Pred pred);

用户如何销毁将根据谓词擦除的元素(例如,使用 operator delete)?Boost.Intrusive 容器提供了额外的函数,这些函数接受一个函数对象,该对象将在元素从容器中擦除后被调用。例如,list 提供了

template<class Pred, class Disposer>
void remove_and_dispose_if(Pred pred, Disposer disposer)

使用此函数,如果 disposer 函数销毁一个对象,用户可以有效地移除和销毁元素:remove_and_dispose_if 将为每个移除的元素调用 “disposer” 函数对象。list 提供了更多将 disposer 函数对象作为参数的函数,例如 erase_and_disposeclear_and_disposeremove_and_dispose 等。

请注意,disposer 函数不一定只销毁对象。它可以实现任何其他操作,例如将移除的对象插入到另一个容器中。让我们看一个小例子

#include <boost/intrusive/list.hpp>

using namespace boost::intrusive;

//A class that can be inserted in an intrusive list
class my_class : public list_base_hook<>
{
   public:
   my_class(int i)
      :  int_(i)
   {}

   int int_;
   //...
};

//Definition of the intrusive list
typedef list<my_class> my_class_list;

//The predicate function
struct is_even
{
   bool operator()(const my_class &c) const
   {  return 0 == (c.int_ % 2);  }
};

//The disposer object function
struct delete_disposer
{
   void operator()(my_class *delete_this)
   {  delete delete_this;  }
};

int main()
{
   const int MaxElem = 100;

   //Fill all the nodes and insert them in the list
   my_class_list list;

   try{
      //Insert new objects in the container
      for(int i = 0; i < MaxElem; ++i) list.push_back(*new my_class(i));

      //Now use remove_and_dispose_if to erase and delete the objects
      list.remove_and_dispose_if(is_even(), delete_disposer());
   }
   catch(...){
      //If something throws, make sure that all the memory is freed
      list.clear_and_dispose(delete_disposer());
      throw;
   }

   //Dispose remaining elements
   list.erase_and_dispose(list.begin(), list.end(), delete_disposer());
   return 0;
}

所有 Boost.Intrusive 容器都为所有从容器中擦除元素的函数提供了这些 “擦除 + 处置” 附加成员。


PrevUpHomeNext