Подтвердить что ты не робот

Std:: erase и std:: remove комбинация для удаления определенного элемента не работает для конкретного примера

#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> a = {1,2,3,7,1,5,4};
    vector<int> b = {6,7,4,3,3,1,7};
    a.erase(remove(a.begin(),a.end(),a[0]),a.end());
    b.erase(remove(b.begin(),b.end(),b[0]),b.end());

    return 1;
}

В этом конкретном примере мой GNU gdb Ubuntu 7.7.1 утверждает, что при возврате 1 строка: a = {2,3,7,1,5,4}, который не ожидается (удаляет только один 1), и b = {7,4,3,3,1}, что не ожидается.

Мое ожидание: b должно быть a = 2,3,7,5,4 и b = 7,4,3,3,1,7.

Что здесь происходит?

4b9b3361

Ответ 1

Объявление std::remove() выглядит как

template <class ForwardIterator, class T>
  ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);

Обратите внимание, что последний параметр является ссылкой. Таким образом, после компиляции он эффективно передает адрес указанного элемента.

В remove(a.begin(), a.end(), a[0]) передается код, указывающий адрес 0-го элемента a. Когда выполняется remove(), как только обрабатывается 0-й элемент, значение, указанное ссылкой, переданной в измененной, приводит к к неожиданному результату.

Чтобы получить ожидаемый результат, сделайте копию перед вызовом std::remove().

int toberemoved = a[0];
a.erase(remove(a.begin(),a.end(),toberemoved),a.end());