¿Por qué obtengo un resultado diferente si en lugar de x paso directamente el elemento de matriz ar [0] en la función std :: remove? [duplicar]
#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;
}
¿Por qué obtengo un resultado diferente si en lugar de x
pasar directamente ar[0]
la std::remove
función?
x
y ar[0]
tienen el mismo valor.
Respuestas
El motivo es que std::remove
toma por referencia el último parámetro. Desde cppreference :
Debido a que std :: remove toma valor por referencia, puede tener un comportamiento inesperado si es una referencia a un elemento del rango [primero, último].
Es un poco complicado, porque el parámetro se pasa como const
referencia:
template< class ForwardIt, class T > ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
Sin embargo, el hecho de que ar[0]
se pase como const
referencia no implica que ar[0]
no pueda modificarse por otros medios. En este caso se modifica mediante first
/ last
. En realidad, no puedo pensar en un caso en el que estaría "bien" tener un elemento dentro [first, last)
como value
.
A modo de ilustración, considere que obtiene la misma salida incorrecta con ar[0]
como si declarara x
como referencia:
int& x=ar[0];
ar.erase(remove(ar.begin(),ar.end(),x),ar.end());
Aquí x
se pasa como const
referencia, pero el algoritmo se modifica ar[0]
.