vectores una pila matriz lista ingresar eliminar elementos elemento datos contenido como clase borrar arreglo array c++ vector erase

c++ - una - Eliminar elementos de un vector dentro del bucle



ingresar datos en una matriz c++ (6)

C ++ 11 ha presentado una nueva colección de funciones que serán de utilidad aquí.

allPlayers.erase( std::remove_if(allPlayers.begin(), allPlayers.end(), [](auto& x) {return x->getpMoney() <= 0;} ), allPlayers.end());

Y luego tienes la ventaja de no tener que hacer tanto desplazamiento de los elementos finales.

Sé que hay preguntas similares a esta, pero no pude encontrar el camino en mi código con su ayuda. Simplemente quiero eliminar / eliminar un elemento de un vector verificando un atributo de este elemento dentro de un bucle. ¿Cómo puedo hacer eso? Probé el siguiente código pero recibí el vago mensaje de error:

La función ''operator ='' no está disponible en ''Player''.

for (vector<Player>::iterator it = allPlayers.begin(); it != allPlayers.end(); it++) { if(it->getpMoney()<=0) it = allPlayers.erase(it); else ++it; }

¿Que debería hacer?

Actualización: ¿Cree que la pregunta vector :: borrar con el miembro del puntero se relaciona con el mismo problema? ¿Necesito de ahí un operador de asignación? ¿Por qué?


No debes incrementarlo en el ciclo for :

for (vector<Player>::iterator it=allPlayers.begin(); it!=allPlayers.end(); /*it++*/) <----------- I commented it. { if(it->getpMoney()<=0) it = allPlayers.erase(it); else ++it; }

Observe la parte comentada; it++ no es necesario allí, ya it se está incrementando en el for-body en sí mismo.

En cuanto al error " ''operator ='' la función no está disponible en ''Player'' ", proviene del uso de erase() que internamente usa operator= para mover elementos en el vector. Para usar erase() , los objetos de la clase Player deben ser asignables, lo que significa que debe implementar operator= for Player class.


O haz el ciclo hacia atrás.

for (vector<Player>::iterator it = allPlayers.end() - 1; it != allPlayers.begin() - 1; it--) if(it->getpMoney()<=0) it = allPlayers.erase(it);


Olvídate del bucle y utiliza los algoritmos de rango std o boost.
Usando Boost.Range en Lambda se vería así:

boost::remove_if( allPlayers, bind(&Player::getpMoney, _1)<=0 );


Su problema específico es que su clase de Player no tiene un operador de asignación. Debes hacer que "Player" se pueda copiar o mover para eliminarlo de un vector. Esto se debe a que el vector debe ser contiguo y, por lo tanto, debe volver a ordenar los elementos para llenar los espacios creados al eliminar los elementos.

También:

Usar el algoritmo std

allPlayers.erase(std::remove_if(allPlayers.begin(), allPlayers.end(), [](const Player& player) { return player.getpMoney() <= 0; }), allPlayers.end());

o incluso más simple si tienes impulso:

boost::remove_erase_if(allPlayers, [](const Player& player) { return player.getpMoney() <= 0; });

Consulte la respuesta de TimW si no tiene soporte para C ++ 11 lambdas.


if(allPlayers.empty() == false) { for(int i = allPlayers.size() - 1; i >= 0; i--) { if(allPlayers.at(i).getpMoney() <= 0) { allPlayers.erase( allPlayers.begin() + i ); } } }

Esta es mi manera de eliminar elementos en el vector. Es fácil de entender y no necesita ningún truco.