The error message says
no operator found which takes a left-hand operand of type 'const
std::basic_string<_Elem,_Traits,_Ax>'
Note the const. The compiler is correct that std::wstring
doesn't have an operator=
which can be called on a const object.
Why is the string const? The answer is that the values in a std::set
are immutable, because values in a set are ordered, and changing a value could change its ordering in the set, invalidating the set.
Why is the compiler trying to copy a value of the set?
std::remove_if
(and std::remove
) don't actually erase anything (nor can they, because they don't have the container, only iterators). What they do is to copy all values in the range which don't match the criterion to the beginning of the range, and return an iterator to the next element after the matching elements. You are then supposed to manually erase from the returned iterator to the end of the range. Since a set keeps its elements in order, it would be wrong to move any elements around, so remove_if
cannot be used on a set (or any other associative container).
In short, you do have to use a loop of std::find_if
and set::erase
, like so:
template<class V, class P>
void erase_if(std::set<V>& s, P p)
{
std::set<V>::iterator e = s.begin();
for (;;)
{
e = std::find_if(e, s.end(), p);
if (e == s.end())
break;
e = s.erase(e);
}
}