Perché ottengo un risultato diverso se invece di x passo direttamente l'elemento dell'array ar [0] nella funzione std :: remove? [duplicare]
#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;
}
Perché ottengo un risultato diverso se invece di x
passare direttamente ar[0]
alla std::remove
funzione?
x
e ar[0]
hanno lo stesso valore.
Risposte
Il motivo è che std::remove
prende l'ultimo parametro per riferimento. Da cppreference :
Poiché std :: remove assume valore per riferimento, può avere un comportamento imprevisto se è un riferimento a un elemento dell'intervallo [first, last).
È un po 'complicato, perché il parametro viene passato come const
riferimento:
template< class ForwardIt, class T > ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
Tuttavia, solo perché ar[0]
viene passato come const
riferimento non implica che ar[0]
non possa essere modificato con altri mezzi. In questo caso viene modificato tramite first
/ last
. In realtà non riesco a pensare a un caso in cui sarebbe "ok" avere un elemento all'interno [first, last)
come value
.
A titolo illustrativo, considera che ottieni lo stesso output sbagliato con ar[0]
come se avessi dichiarato x
come riferimento:
int& x=ar[0];
ar.erase(remove(ar.begin(),ar.end(),x),ar.end());
Qui x
viene passato come const
riferimento, ma l'algoritmo viene modificato ar[0]
.