Стирание многих векторных элементов при прохождении через 'auto' - PullRequest
1 голос
/ 24 января 2020

Допустим, у меня есть vector пар, где каждый pair соответствует индексам (строка и столбец) определенной матрицы, над которой я работаю

using namespace std;
vector<pair<int, int>> vec;

Я хотел, используя auto, go через весь вектор и удалите сразу все пары, которые удовлетворяют определенным условиям, например что-то вроде

for (auto& x : vec) {
    if (x.first == x.second) {
        vec.erase(x); 
    }
}

, но это не работает, так как я предполагаю, что vec.erase() должен иметь итератор в качестве аргумента и x на самом деле pair, который является элементом вектора vec, а не итератором. Я пытался изменить его несколькими способами, но я не уверен, как точно работает прохождение элементов контейнера с auto и как я могу это исправить.

Можно ли легко изменить приведенный выше код, чтобы он работал и стереть несколько элементов вектора, проходя через него с auto? Или я должен изменить свой подход?

Пока это просто вектор пар, но позже будет намного хуже, поэтому я хотел бы использовать auto для простоты.

Ответы [ 2 ]

5 голосов
/ 24 января 2020

vector::erase() делает недействительными все выдающиеся итераторы, включая тот, который использует ваш диапазон для l oop. Используйте std::remove_if():

vec.erase(
    std::remove_if(
        vec.begin(),
        vec.end(),
        [](const pair<int,int> &xx) { return xx.first == xx.second; }
    ), vec.end()
);

std::remove_if(), чтобы поменять элементы в конце вектора, а затем вы можете безопасно стереть их.

0 голосов
/ 24 января 2020

Я бы предпочел что-то вроде этого:

  pair<int, int> pair = nullptr;
  auto iter = vec.begin();
    while(iter != vec.end()){
        pair = (*iter);
        if(pair.first == pair.second){
            iter = this->vec.erase(iter);
        }else{
            ++iter;
        }
    }
...