2

remove_if以下の疑似コードで、次のように文字列のベクトルを使用することを考えていました。

for(some strings in a given set) {
  remove_if(myvec.begin(), myvec.end(), string_matches_current_string);
}

これで、述語を定義して、これを簡単に機能させることができることがわかりました。しかし、これを機能させるために上記の述語の代わりに使用できる標準のテンプレート関数があるかどうか疑問に思っていました。私は周りを見回していて、1つを見つけることができませんでした。例を挙げてアイデアを評価してください。ありがとう!

4

2 に答える 2

3

std::remove_if削除したい値がすでにわかっているのに、なぜ使用するのですか?を使用するstd::removeと、指定された範囲内で指定された値に一致するアイテムが削除されます。

std::vector<std::string>::iterator new_end = my_vec.end();
for(const auto &current_set_string : some_set)
    new_end = std::remove(myvec.begin(), new_end, current_set_string);
my_vec.erase(new_end, my_vec.end()); // effectively remove them from the vector.

これを短くするために範囲ベースのforループを使用したことに注意してください。ただし、C ++ 11を使用できない場合は、通常のループを使用する必要があります。

于 2012-06-21T01:15:49.237 に答える
3

標準関数がないことは確かですが、C++11 ラムダを使用して式全体を簡単に記述できます。

std::remove_if(myvec.begin(), myvec.end(),
              [&compare_me](std::string const& cmp) -> bool
              {
                return compare_me == cmp;
              });

compare_me は、外側のループによって設定された「現在の」文字列です。

remove_if は、最後の有効な要素の 1 つ後ろの反復子を返すことに注意してください。したがって、正しい myvec を取得するには、remove_if によって返される反復子と myvec.end() の間の要素を消去する必要があります。

C++11 以外の実装では、ラムダを関数またはファンクターに変換する必要があります。ファンクターに変換する場合は、ファンクターを直接渡すことができます。関数に変換する場合は、boost::bind などを使用して必要な接着剤を提供する必要があります。

于 2012-06-21T01:05:09.530 に答える