Reputation: 6255
I have a following class:
class Foo
{
public:
void Fill();
private:
std::vector<std::wstring> vec;
};
And then the implementation is:
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" );
}
What I'd like to do to delete an element from this vector, lets say one that contains "def". What would be the easiest way to do so?
I'm thinking to use remove_if, but the comparator accept only 1 parameter - container element.
Is there an elegant solution? I'd use looping as a last resort.
Upvotes: 1
Views: 493
Reputation: 385144
If it's a class rather than a function, the predicate has a constructor, and constructors can take arguments.
You can pass your search string into this constructor, store it as a member, then use it inside the function call operator:
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 "shortcut" to doing this is to use a lambda for the predicate, then the passing through of the search string is done for you either via the lambda capture, or by virtue of the fact that you literally typed it in right there and then:
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.
If the predicate is a function, and you want it to invoke a binary comparator, you could mess about with std::bind
to achieve the same result.
Upvotes: 4