2016-12-16 45 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