4

クラスの std::list があり、削除対象としてマークされたエントリを削除したいと考えています。std::remove_if と erase を使用しています。

class MyClass
{
    bool isDone(MyData& myData)
    {
        return myData.isDone();
    }

    void removeIfDone(std::list<MyData>& myList)
    {
        std::list<MyData>::iterator it =
            remove_if(myList.begin(), myList.end(), 
                  boost::bind(&MyClass::isDone, this, _1));
        myList.erase(it, myList.end());
    }
};

メモリの割り当てと割り当て解除が非常に高価な小さなプロセッサで実行しています。この remove は、私のアプリケーションで new と delete を何千回も呼び出しています。

私は以前boost::ref、重要な変数をバインド パラメータとして渡すときに使用していましたが、この場合、問題を引き起こしているのはおそらくファンクタ自体の作成と破棄、またはそのコピーであると思います。

私は次のようなことをしたいと思います

boost::bind(&MyClass::isDone, boost::ref(this), boost::ref(_1));

作成および破棄されているものに関するドキュメントが見つかりません。私の簡単な質問は、これをより効率的にするにはどうすればよいかということです。

4

2 に答える 2

9

std::remove_ifへの呼び出しをに置き換えてみてくださいstd::list::remove_if。後者は、要素をリストの最後に移動しようとするのではなく、前後の要素からいくつかのポインターのみをコピーする必要があります。これが、複数の割り当ての原因です。追加の利点は、 のメンバー関数であるためstd::list、条件に一致する要素を実際に削除 (つまり消去) することです。

class MyClass
{
    bool isDone(MyData& myData)
    {
        return myData.isDone();
    }

    void removeIfDone(std::list<MyData>& myList)
    {
        myList.remove_if( boost::bind( &MyClass::isDone, this, _1 ) );
    }
};
于 2013-03-07T20:36:33.387 に答える
0

に渡す単純なファンクターを使用して、おそらく問題を解決できますstd::remove_if。この方法では、引数を渡してremove_if自分自身を保存する必要はありませんboost::bind

struct functor
{
public:
    bool operator()(MyData& mydata)
    { 
       return mydata.IsDone();
    }   
};

void removeIfDone(std::list<MyData>& myList)
{
   std::list<MyData>::iterator it =
     remove_if(myList.begin(), myList.end(), 
         functor()); //call operator() on functor
     myList.erase(it, myList.end());
}

ここでコンパイルする例

于 2013-03-07T17:53:37.700 に答える