C++ Borrando elementos


Ejemplo

Eliminando el último elemento:

std::vector<int> v{ 1, 2, 3 };
v.pop_back();                           // v becomes {1, 2}

Eliminando todos los elementos:

std::vector<int> v{ 1, 2, 3 };
v.clear();                              // v becomes an empty vector

Eliminando elemento por índice:

std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 3);                 // v becomes {1, 2, 3, 5, 6}

Nota: Para un vector elimina un elemento que no es el último elemento, todos los elementos más allá del elemento eliminado deben copiarse o moverse para llenar el espacio, consulte la nota a continuación y std :: list .

Borrar todos los elementos en un rango:

std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(v.begin() + 1, v.begin() + 5);  // v becomes {1, 6}

Nota: Los métodos anteriores no cambian la capacidad del vector, solo el tamaño. Ver Tamaño y Capacidad del Vector .

El método de erase , que elimina una gama de elementos, se utiliza a menudo como parte del lenguaje de borrado-eliminar . Es decir, primero std::remove mueve algunos elementos al final del vector, y luego erase cortes. Esta es una operación relativamente ineficiente para cualquier índice menor que el último índice del vector porque todos los elementos después de los segmentos borrados deben reubicarse en nuevas posiciones. Para aplicaciones críticas de velocidad que requieren la eliminación eficiente de elementos arbitrarios en un contenedor, vea std :: list .

Eliminando elementos por valor:

std::vector<int> v{ 1, 1, 2, 2, 3, 3 };
int value_to_remove = 2;
v.erase(std::remove(v.begin(), v.end(), value_to_remove), v.end()); // v becomes {1, 1, 3, 3}

Eliminando elementos por condición:

// std::remove_if needs a function, that takes a vector element as argument and returns true, 
// if the element shall be removed
bool _predicate(const int& element) {
    return (element > 3); // This will cause all elements to be deleted that are larger than 3
}
...
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(), _predicate), v.end()); // v becomes {1, 2, 3}

Eliminar elementos por lambda, sin crear una función de predicado adicional

C ++ 11
std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
v.erase(std::remove_if(v.begin(), v.end(),
     [](auto& element){return element > 3;} ), v.end()
);

Borrar elementos por condición de un bucle:

std::vector<int> v{ 1, 2, 3, 4, 5, 6 };
std::vector<int>::iterator it = v.begin();
while (it != v.end()) {
    if (condition)
        it = v.erase(it); // after erasing, 'it' will be set to the next element in v
    else
        ++it;             // manually set 'it' to the next element in v
}

Si bien es importante que no se incrementará it en caso de una eliminación, se debe considerar el uso de un método diferente cuando el entonces borrar repetidamente en un bucle. Considere remove_if para una manera más eficiente.

Eliminar elementos por condición de un bucle inverso:

std::vector<int> v{ -1, 0, 1, 2, 3, 4, 5, 6 };
typedef std::vector<int>::reverse_iterator rev_itr;
rev_itr it = v.rbegin();

while (it != v.rend()) { // after the loop only '0' will be in v
    int value = *it;
    if (value) {
        ++it;
        // See explanation below for the following line.
        it = rev_itr(v.erase(it.base()));
    } else
        ++it;
}

Note algunos puntos para el bucle anterior:

  • Dado un iterador inverso it apunta a algún elemento, la base del método proporciona el iterador regular (no inverso) que apunta al mismo elemento.

  • vector::erase(iterator) borra el elemento apuntado por un iterador y devuelve un iterador al elemento que siguió al elemento dado.

  • reverse_iterator::reverse_iterator(iterator) construye un iterador inverso a partir de un iterador.

Poner en total, la línea it = rev_itr(v.erase(it.base())) dice: tomar el iterador inverso it , han v borrar el elemento señalado por su iterador regular; tomar el iterador resultante, construir un iterador inverso de ella, y asignarla al iterador inverso it .


Eliminar todos los elementos usando v.clear() no libera memoria (la capacity() del vector permanece sin cambios). Para reclamar espacio, usa:

std::vector<int>().swap(v);
C ++ 11

shrink_to_fit() libera la capacidad vectorial no utilizada:

v.shrink_to_fit();

shrink_to_fit no garantiza reclamar realmente el espacio, pero la mayoría de las implementaciones actuales lo hacen.