Что происходит с элементом при использовании remove_if?

Я пытаюсь понять как remove_if работает (<< перегружен) и для этого я хочу удалить все строки, которые начинаются с 'C':

vector<string> langs = { "Python", "C++", "C", "Java", "C#" };
cout << "Initial vector: " << langs << " | Size = " << langs.size() << endl;

Выход: Initial vector: Python C++ C Java C# | Size = 5

Тогда я пишу:

auto it = remove_if(begin(langs), end(langs), [](const string& s) 
                                              { return s[0]== 'C';});
cout << "After remove_if: " << langs << " | Size = " << langs.size() << endl;

Выход 2: After remove_if: Python Java C C# | Size = 5

Что я понимаю: элементы, которые должны остаться, удаляются в начале и *it теперь равняется "C"

Вопрос: что происходит с "C++"? Если "Java" заменил, почему

for(auto& _it = it; _it != end(langs); _it++)
    cout << *_it << " ";

дает вывод 3: C C# и не "C", "Java", "C#"?

1 ответ

remove_if в основном вариация copy_if где место назначения перезаписывает источник, а смысл предиката меняется на противоположный, наряду с оптимизацией, что он фактически не копирует ведущие элементы, если они не перемещаются. Он также использует ходы вместо копий, если это уместно.

Итак все remove_if на самом деле это двигаться вниз (вперед) элементы, для которых предикат является ложным. Это не касается тех "оставшихся" элементов, поэтому они все еще будут там, и вам нужно позвонить erase с возвращаемым значением remove_if если хочешь от них избавиться.

Другие вопросы по тегам