2016-12-16 5 views
1

私は以下のクラスがあります。のstd ::のstd :: remove_if対削除

class Foo 
{ 
public: 
    void Fill(); 
private: 
    std::vector<std::wstring> vec; 
}; 

とし、その後の実装は次のとおりです。私がやりたいのは何

void Foo::Fill() 
{ 
    vec.push_back(L"abc aaa"); 
    vec.push_back(L"def aaa"); 
    vec.push_back(L"fed bbb"); 
    vec.push_back(L"cba bbb"); 
} 

から要素を削除しますこのベクトルは、 "def"を含むものと言います。そうする最も簡単な方法は何でしょうか?

私はremove_ifを使用すると考えていますが、コンパレータは1つのパラメータ - コンテナ要素しか受け入れません。

優雅なソリューションはありますか?私は最後の手段としてループを使用します。

+1

あなたはどのコンパレータについて話していますか? –

+0

'remove_if' expectsは単項述語を期待しています。あなたの検索に基づいて真または偽を返すラムダを渡すことができます。 – Arunmu

+0

なぜ述語に複数の引数が必要なのですか(私はこれをコンパレータが意味すると仮定します)。 – MikeMB

答えて

3

関数ではなくクラスである場合、述語にはコンストラクタがあり、コンストラクタには引数を取ることができます。

あなたは、関数呼び出し演算子の内側にそれを使用し、メンバーとしてそれを保存し、このコンストラクタに検索文字列を渡すことができます。これを行うに

struct Pred 
{ 
    Pred(std::wstring str) : str(std::move(str)) {} 
    bool operator()(const std::wstring& el) const 
    { 
     return el.find(str) != el.npos; 
    } 
private: 
    const std::wstring str; 
}; 

std::remove_if(std::begin(vec), std::end(vec), Pred("def")); 

// N.B. `el.find` is probably wrong. Whatever. 

「ショートカット」のためのラムダを使用することです述語が関数である場合

std::remove_if(
    std::begin(vec), std::end(vec), 
    [](const auto& el) { return el.find("def") != el.npos; } 
); 

// N.B. `el.find` is probably still wrong. Whatever. 

:述語が、その後、検索文字列の通過は、ラムダ・キャプチャーを経由して、またはあなたが文字通りすぐそこ、その後でそれを入力したという事実によっていずれかのあなたのために行われます、あなたはそれがバイナリコンパレータを呼び出すことを望むならば、あなたは同じ結果を達成するためにstd::bindと混乱する。

+0

コンパイラエラーが発生しました。「パラメータに 'auto'が含まれている型を持つことはできません。 "auto"を "std :: wstring"に変更すると、すべてがコンパイルされて正常に動作します。 BTW、e1.find()は正しい関数です。 – Igor

+0

@Igor:暗黒時代のコンパイラを使用しています。明らかに、C++ 14より前には、型を指定する必要があります。 –

+0

は本当にありません。私の目的(C++ 11) – Igor

関連する問題