web-dev-qa-db-ja.com

オブジェクトのベクトルに対するC ++ remove_if

私は一度に複数のオブジェクトを削除しようとするオブジェクトのベクトル(順序が重要)(それらをmyobjクラスと呼びます)を持っています。

class vectorList
{

    vector<*myobj> myList; 
};

class myobj
{

    char* myName;
    int index;
    bool m_bMarkedDelete;
}

これを行う最善の方法は、特定のmyobjオブジェクトを削除対象としてマークし、ベクターでmyList.remove_if()を呼び出すことだと考えていました。ただし、このために述語などを使用する方法は正確にはわかりません。 myobjを削除し、メンバー変数が設定されているかどうかを確認する述語を作成したいということができるオブジェクトにメンバー変数を作成する必要がありますか?

VectorListクラスの一部として述語を実装するにはどうすればよいですか?

30
Jordan

Myobjを削除し、メンバー変数が設定されているかどうかを確認する述語を作成したいということができるオブジェクトにメンバー変数を作成する必要がありますか?

もうやったことない?それはm_bMarkedDeleteは次のように述語を記述します。

bool IsMarkedToDelete(const myobj & o)
{
    return o.m_bMarkedDelete;
}

次に:

myList.erase(
    std::remove_if(myList.begin(), myList.end(), IsMarkedToDelete),
    myList.end());

または、ラムダを使用して:

myList.erase(
    std::remove_if(myList.begin(), myList.end(),
        [](const myobj & o) { return o.m_bMarkedDelete; }),
    myList.end());

あなたのクラスが実際にそのメンバーを持っていない場合、あなたは私たちにそうすべきかどうか尋ねているなら、私はノーと言うでしょう。削除のマークを付けるためにどのような基準を使用しましたか?述部で同じ基準を使用します。例えば:

bool IndexGreaterThanTen(const myobj & o)
{
    return o.index > 10;
}

-すべてのメンバーはプライベートなので、私が書いた関数はもちろん無効です。そのため、それらにアクセスするには何らかの方法が必要です。

43

述語は基本的に条件付き比較です。関数またはオブジェクトにすることができます。新しいC++ラムダを使用した例を次に示します。このコードはベクトルを通過し、3に等しい値を削除します。

int arg[6] = {1, 2, 3, 3, 3, 5};
std::vector<int> vec(arg, arg+6);
vec.erase(
   std::remove_if(
      vec.begin(), vec.end(),
      [](int i){ return i == 3;}),
   vec.end());

編集:ポインターの場合、ベクターまたはインターフェースをnullptrに設定し、ほぼ同じコードでバッチで削除できるとしましょう。 VS2008では、ラムダがないため、代わりに比較述語関数または構造体を作成します。

bool ShouldDelete(IAbstractBase* i)
{
    return i == nullptr;
    // you can put whatever you want here like:
    // return i->m_bMarkedDelete;
}

std::vector<IAbstractBase*> vec;
vec.erase(
   std::remove_if(
      vec.begin(), vec.end(),
      ShouldDelete),
   vec.end());
10
AJG85