3

STL コンテナーがある場合、以下の例のように削除できるポインターのリストを言います。最初にロックする必要があるため、weak_ptrs のコンテナーでは比較できないため、これは機能しません。私に何ができる?

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

3 に答える 3

5

1 つには、weak_ptr に対して operator == を定義するだけです。これが実装されていないのには理由があると確信しています。後で噛まれる可能性があります。

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 クラスを圧縮できます。ほとんどが中空です。また、アイテム以外のタイプを含むリストで使用するためのテンプレートにすることもできます。

ああ、あなたの比較関数を含むどこでも参照によってweak_ptrsを渡します。

*bind は性能的に無料ではありません。多くの Remove() 呼び出しが予想され、パフォーマンスを重視する場合は、それを避けるのが良いかもしれません。

于 2009-09-07T19:14:26.570 に答える
0

sbkのアプローチの問題は、weak_ptroperator==にレースの可能性があることだと思います。operator ==から戻っても、aまたはbへのshared_ptrが存在するという保証はありません。これにより、結果のコードを誤解しやすくなります。

それで、あなたができる最善のことは次のようです:

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
}

これはあまり役に立ちません。さて、コンテナを反復処理している場合でも、この時点でイテレータを削除することはできますが、わずかに間違った比較を行ってしまう場合がさらに多くあります。

于 2012-06-28T17:31:30.357 に答える
0

答えを見つけるために永遠に検索したからです。

weak_ptrs を比較する関数を作成し、1 つの引数をバインドします。

    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>

于 2009-09-07T17:39:35.403 に答える