erase () после выполнения remove_if ()

Я создал функцию для запуска вектора строк и удаления любых строк длиной 3 или менее. Это урок использования библиотеки алгоритмов STL.

У меня проблемы с тем, что функции работают, но он не только удаляет строки длиной 3 или меньше, но также добавляет строку «вектор» в конец.

Выход должен быть

This test vector

и вместо этого

This test vector vector"

Как я могу это исправить?

/*
* using remove_if and custom call back function, write RemoveShortWords 
* that accepts a vector<string> and removes all strings of length 3 or
* less from it. *shoot for 2 lines of code in functions.
*/

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;

bool StringLengthTest(string test) //test condition for remove_if algo.  
{
    return test.length() <= 3;
}

void RemoveShortWords(vector<string> &myVector)
{
    //erase anything in vector with length <= 3
    myVector.erase(remove_if(myVector.begin(),
                             myVector.end(),
                             StringLengthTest));
}

int main ()
{
    //add some strings to vector
    vector<string> myVector;
    myVector.push_back("This");
    myVector.push_back("is");
    myVector.push_back("a");
    myVector.push_back("test");
    myVector.push_back("vector");

    //print out contents of myVector (debugging)
    copy(myVector.begin(), myVector.end(), ostream_iterator<string>(cout," "));
    cout << endl; //flush the stream

    RemoveShortWords(myVector); //remove words with length <= 3

    //print out myVector (debugging)
    copy(myVector.begin(), myVector.end(), ostream_iterator<string>(cout," "));
    cout << endl;

    system("pause");
    return 0;
}

Ответы на вопрос(2)

Решение Вопроса

auto iter(remove_if(myVector.begin(), myVector.end(), StringLengthTest));
myVector.erase(iter);

Эти 2 строки делают то же самое, что и ваша строка. И теперь должно быть ясно, что такое «ошибка». remove_if, работает первым Он перебирает весь вектор и перемещает все «выбранные» записи «в конец» (лучше сказать: он перемещает невыбранные записи вперед). После запуска он возвращает итератор в «последнюю» позицию оставшихся записей, что-то вроде:

это
контрольная работа
вектор
тест <- итератор указывает здесь
вектор

Затем вы запускаете стирание с помощью одного итератора. Это означает, что вы удаляете единственный элемент, на который указывает указатель - поэтому вы удаляете элемент «test». - То, что осталось, это то, что вы видите.

Чтобы исправить это, просто удалите вектор, возвращаемый remove_if в конец ().

myVector.erase(remove_if(myVector.begin(), myVector.end(), StringLengthTest), myVector.end()); //erase anything in vector with length <= 3
 MCP29 янв. 2012 г., 15:50
Великолепные детали. Большое спасибо за разъяснение, что происходит!
 Ruslan07 авг. 2015 г., 10:48
Это будет кусать еще больше, еслиmyVector были пусты. затемiter будет равноmyVector.end()и стирая используяerase(iter) приведет к UB.

myVector.erase(remove_if(myVector.begin(), myVector.end(), StringLengthTest),
               myVector.end());

Ваш ответ на вопрос