std :: remove_if и стереть не удаляя элементы из std :: vector - PullRequest
0 голосов
/ 05 июня 2018

Я практикую легкий код проблемы.Я хочу удалить _if из вектора с помощью лямбда (впервые, это здорово).Я получаю отрицательный указатель для new_end.

#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>   // std::greater

using namespace std;
int main()
{
    vector<int> a = { 2, 7, 11, 15 };
    int target = 9;

    auto new_end = std::remove_if(a.begin(), a.end(), [&a, target](const int x)
    {
        return std::count(a.begin(), a.end(), x) > target;  
    });
    a.erase(new_end, a.end());
    return 0;
}

Нет ошибки, но new_end является отрицательным значением указателя.

enter image description here

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

std::remove_if(begin, end, pred) возвращает итератор , указывающий на первый удаляемый элемент, или end, если нет элемента, соответствующего pred.Последнее верно в вашем случае:

auto new_end = std::remove_if(a.begin(), a.end(),
    [&a, target](const int x) { return std::count(a.begin(), a.end(), x) > target; }
);

new_end равно a.end().Это значение выводится в качестве мусора вашим отладчиком.Но это случается просто случайно в вашем случае.

Как указывалось несколькими комментаторами, как только ваш предикат однажды возвратил true, диапазон [a.begin(), a.end) изменяется, и последний элемент имеет неопределенное значение 1 .

. Это заставляет std::count(a.begin(), a.end(), x) возвращать неопределенные значения.


Рекомендуется исправитькопия a до того, как remove_if начнет двигаться.Это делается путем захвата его значением:

auto new_end = std::remove_if(a.begin(), a.end(),
    [b=a, target](const int x) { return std::count(b.begin(), b.end(), x) > target; }
);

Инициализация копии под новым именем b просто подчеркивает, что это копия.


1) С std::remove_if:

Итераторы, указывающие на элемент между новым логическим концом и физическим концом диапазона, все еще разыменовываются, но сами элементы не определенызначения (согласно MoveAssignable постусловию).

0 голосов
/ 05 июня 2018

Я предполагаю, что хочу удалить числа больше 9 из вектора. Вот код

    vector<int> a = { 2, 7, 11, 15 };
    int target = 9;

    auto new_end = std::remove_if(a.begin(), a.end(), [](const int x)
    {
        return x > 9;

    });
    a.erase(new_end, a.end());
    return 0;

Лямбда-аргумент 'x' будет предоставлен remove_if, вам не нужно добавлятьчто-нибудь в списке захвата

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...