从列表中删除boost :: shared_ptr的正确方法是什么?

Cat*_*kul 4 c++ boost stl smart-pointers

我有一个std::list,boost::shared_ptr<T>我想从中删除一个项目,但我只有一个T*类型的指针,它匹配列表中的一个项目.

但是我无法使用myList.remove( tPtr )我猜测因为shared_ptr没有==为其模板参数类型实现.

我的直接想法是尝试myList.remove( shared_ptr<T>(tPtr) )哪种语法正确,但它会因双重删除而崩溃,因为临时shared_ptr具有单独的use_count.

std::list< boost::shared_ptr<T> > myList;

T* tThisPtr = new T(); // This is wrong; only done for example code.
                       // stand-in for actual code in T using 
                       // T's actual "this" pointer from within T
{
   boost::shared_ptr<T> toAdd( tThisPtr ); // typically would be new T()
   myList.push_back( toAdd );
}

{
   //T has pointer to myList so that upon a certain action, 
   // it will remove itself romt the list

   //myList.remove( tThisPtr);                      //doesn't compile
   myList.remove( boost::shared_ptr<T>(tThisPtr) ); // compiles, but causes
                                                    // double delete
}  
Run Code Online (Sandbox Code Playgroud)

我看到剩下的唯一选项是使用std :: find和自定义比较,或者循环遍历列表暴力并自己找到它,但似乎应该有更好的方法.

我是否遗漏了一些明显的东西,或者这是否过于非标准用于去除干净/正常的方式?

GMa*_*ckG 5

你是对的,我们不能直接比较指针.但确实存在remove_if,我们可以指定自己的谓词.解决方案:

template <typename T>
struct ptr_contains_predicate
{
    ptr_contains_predicate(T* pPtr) :
    mPtr(pPtr)
    {}

    template <typename P>
    bool operator()(const p& pPtr) const
    {
        return pPtr.get() == mPtr;
    }

    T* mPtr;
};

template <typename T>
ptr_contains_predicate<T> ptr_contains(T* pPtr)
{
    return ptr_contains_predicate<T>(pPtr);
}
Run Code Online (Sandbox Code Playgroud)

只需将上面的谓词保存在某个标题中,您就可以在任何地方使用它.

myList.remove_if(ptr_contains(tThisPtr));
Run Code Online (Sandbox Code Playgroud)

最好的解决方案是永远不要失去对它的控制shared_ptr,所以我们可以使用remove,但无论如何上面都是无害的.

  • 在C++ 0X中不需要函子:myList.remove_if([ptr](shared_ptr <Type> p){return p.get()== ptr;}); (4认同)