Почему я получаю другой результат, если вместо 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]
имеют одинаковую ценность.
Ответы
Причина в том, что 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)
as value
.
Для иллюстрации представьте, что вы получаете такой же неправильный результат, ar[0]
как если бы вы объявили x
в качестве ссылки:
int& x=ar[0];
ar.erase(remove(ar.begin(),ar.end(),x),ar.end());
Здесь x
передается как const
ссылка, но алгоритм изменяется ar[0]
.