2

I have the following function, in which I want to prune my std::set<QString> words from words longer/shorter than main_word by more than 4 characters.

void Cluster::prune(QString main_word)
{
    words.erase(std::remove_if(words.begin(),
                               words.end(),
                               [=](QString w){return std::abs(main_word.length() - w.length()) > 4;}),
                words.end());
}

I get the following error while building:

d:\qt\tools\mingw48_32\lib\gcc\i686-w64-mingw32\4.8.0\include\c++\bits\stl_algo.h:1176: błąd: passing 'const QString' as 'this' argument of 'QString& QString::operator=(const QString&)' discards qualifiers [-fpermissive]
             *__result = _GLIBCXX_MOVE(*__first);
                       ^

I'm a bit confused - what am I doing wrong with this lambda?

Cartier
  • 429
  • 4
  • 15
pkrysiak
  • 182
  • 5
  • 14

1 Answers1

2

You can't use the erase remove-if idiom on sets - because a set<K> internally contains elements of type const K - they're nonmodifiable and std::remove_if requires the objects to be MoveAssignable.

You'll have to use a loop:

for (auto it = words.begin(); it != words.end(); /* nothing */)
{
    if (std::abs(main_word.length() - it->length()) > 4) {
        it = words.erase(it);
    }
    else {
        ++it;
    }
}
Barry
  • 286,269
  • 29
  • 621
  • 977
  • Works like charm, thanks! So this lambda should work with vector, right? – pkrysiak Jan 29 '15 at 13:42
  • 1
    @pkrysiak Right. Except in that case, I would suggest improvements to your lambda: both `main_word` and `w` should be taken by reference. As is, you're taking lots of extra copies. – Barry Jan 29 '15 at 14:44