2016-12-16 44 views
1

我有以下類:的std ::刪除VS的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'期望期望一個單一的謂詞。您可以傳遞一個基於您的搜索返回true或false的lambda。 – 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. 

A「捷徑」這樣做是要使用的拉姆達謂語,那麼通過搜索字符串爲您完成或者通過拉姆達捕獲,或憑藉的事實是,你從字面上鍵入它在那裏,然後:

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

不是真的。我有MSVC 2010,這是足夠的我的目的(C + + 11) – Igor