Почему я получаю другой результат, если вместо x я напрямую передаю элемент массива ar[0] в функцию std::remove?
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
int main()
{
vector<int> ar = {1, 2, 2, 2, 3, 4, 5, 5, 5, 6, 7};
vector<int> sum;
int n = ar.size();
for (int i = 0; i < n; i++)
{
int x = ar[0];
int frq = count(ar.begin(), ar.end(), x);
int q = frq / 2;
sum.push_back(q);
ar.erase(remove(ar.begin(), ar.end(), x), ar.end()); // Doubt
}
int count = 0;
int n1 = sum.size();
for (int i = 0; i < n1; i++)
{
count = count + sum[i];
}
cout << count;
}
Почему я получаю другой результат, если вместо x
Я прямо передаю ar[0]
в std::remove
функция?
x
а также ar[0]
имеют такое же значение.
1 ответ
Причина в том, что std::remove
берет последний параметр по ссылке. Из cppreference:
Поскольку std::remove принимает значение по ссылке, он может иметь неожиданное поведение, если это ссылка на элемент диапазона [first, last).
Это немного сложно, потому что параметр передается как const
Справка:
template< class ForwardIt, class T > ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
Однако только потому, что ar[0]
передается как const
ссылка не означает, что ar[0]
не могут быть изменены другими способами. В этом случае он модифицируется черезfirst
/ last
. На самом деле я не могу представить себе случая, когда было бы "нормально" иметь элемент внутри[first, last)
в качестве value
.
Для иллюстрации представьте, что вы получаете тот же неправильный результат с ar[0]
как если бы вы заявили x
в качестве справки:
int& x=ar[0];
ar.erase(remove(ar.begin(),ar.end(),x),ar.end());
Вот x
передается как const
ссылка, но алгоритм изменяет ar[0]
.