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 постусловию).