2009-09-07 84 views
3

如果我有一個STL容器,說一個指針列表,我可以像下面的例子那樣去除它們。對於weak_ptrs容器,這不起作用,因爲它們無法進行比較,因爲它們需要先被鎖定。我能做什麼?如何在std :: tr1 :: weak_ptr的容器上使用std :: remove?

void MyClass::RemoveItem(std::tr1::weak_ptr<Item> const & pItem) 
{ 
    mylist.remove(pItem); 
} 
+2

如果弱指針不能被鎖定,會發生什麼,因爲它指向的內容已經消失了? – Omnifarious 2009-09-07 20:28:54

+0

使用sbk的答案,p.lock()會返回一個shared_ptr給p,它不會匹配Item.lock(),所以它仍然可以工作。 p.lock()永遠不會拋出。 – 2010-05-21 14:02:13

回答

5

一件事,你可以只定義的==操作符的任何weak_ptr的。我相信這是沒有實現的原因,它可能會在稍後的時候咬你。

template <typename T> 
bool operator == (const std::tr1::weak_ptr<T>& a, const std::tr1::weak_ptr<T>& b) 
{ 
    return a.lock() == b.lock(); 
} 

...你可以像往常一樣調用remove()。我猜這有點極端。

如果你堅持的remove_if()方法,你可以擺脫的綁定的魔法*使用函數對象:

struct EqPredicate 
{ 
    const boost::weak_ptr<Item>& theItem; 

    EqPredicate(const boost::weak_ptr<Item>& item) : theItem(item) 
    { 
    } 

    bool operator() (const boost::weak_ptr<Item>& p) const 
    { 
     return p.lock() == theItem.lock(); 
    } 
}; 

,然後用它是這樣的:

mylist.remove_if(EqPredicate(pItem)); 

它看起來像更多的代碼,但你可以壓縮EqPredicate類,它大多是空的。此外,它可以作爲模板使用它包含除Item之外的類型的列表。

哦,並通過包括您的比較函數在內的所有參考傳遞給您weak_ptrs。

*綁定不是免費的性能。如果您希望進行大量的Remove()調用並關心性能,則可能需要避免它。

0

只因爲我搜索像永遠找到答案。

創建一個函數來比較weak_ptrs,然後綁定一個參數。

bool weak_ptr_comparsion(Item::wPtr a, Item::wPtr b) 
    { 
     return a.lock() == b.lock(); 
    } 

    void MyClass::RemoveItem(Item::wPtr const & pItem) 
    { 
     mylist.remove_if(std::tr1::bind(weak_ptr_comparsion, pItem, 
         std::tr1::placeholders::_1)); 
    } 

不要忘了,包括<tr1/functional>

+1

好像你應該使用一個函數對象,並通過引用來獲取參數。 – rlbond 2009-09-07 18:43:23

0

我認爲sbk的方法存在的問題是weak_ptr運算符==有可能進行比賽。即使你從operator ==返回,也不能保證shared_ptr對a或b存在,這很容易誤解結果代碼。

有了它,似乎你能做的最好的是:

if(a == b) { 
    boost::shared_ptr<Item> a_locked(a.lock()); 
    boost::shared_ptr<Item> b_locked(b.lock()); 
    // It is an error to assume a_locked == b_locked here 
    // It is an error to assume a.lock() == b.lock() here 
    // It is an error to assume a.get() or b.get() here 
} 

這是不是有用。現在,如果你迭代了一個容器,你仍然可以在這個時候刪除迭代器,但是還有很多情況下你最終只會做出錯誤的比較。