std :: remove vs std :: remove_if

时间:2016-12-16 19:36:08

标签: c++11 vector stl

我有以下课程:

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 :(得分: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.

执行此操作的“快捷方式”是使用lambda作为谓词,然后通过lambda捕获为您完成搜索字符串的传递,或者通过您在字面上键入它的事实然后:

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以获得相同的结果。