← SEARCHABLE ARCHIVE
C / C++ · 2026-07-07

C++ de los fundamentos al dominio — Lección 11

Uso de algoritmos Lambda y estándar

INTERACTIVE READING MODE →

Los artículos escritos en este blog fueron creados con el objetivo de enseñar. Además, la información del artículo puede ser incorrecta, así que tenga cuidado.

El código para encontrar u ordenar monstruos específicos en un contenedor y eliminar monstruos muertos aparece con frecuencia. Puedes crear el tuyo propio con una declaración for, pero el uso de un algoritmo estándar hace que el propósito del código sea más visible.

lambda

Una lambda es una función que se escribe directamente sin nombre.

int monsterId = 10;

auto isTarget = [monsterId](const std::shared_ptr<Monster>& monster)
{
    return monster->GetId() == monsterId;
};

[]es la lista de captura. [monsterId]captura el valor copiándolo,[&]captura variables externas por referencia.[this]utiliza el objeto actual.

La captura de referencia es conveniente, pero puede ser peligrosa si la lambda sobrevive más que la variable original. El código es más fácil de leer si captura claramente solo los valores necesarios.

find_if

auto iter = std::find_if(
    activeMonsters.begin(),
    activeMonsters.end(),
    [monsterId](const auto& monster)
    {
        return monster->GetId() == monsterId;
    }
);

if (iter != activeMonsters.end())
{
    currentTarget = *iter;
}

find_if devuelve un iterador del primer elemento que satisface la condición. Si no se encuentra, se devuelve el final del rango pasado.

sort

Primero ordena los monstruos con la salud más baja y, si la salud es la misma, puedes colocar primero los monstruos con la ID más baja.

std::sort(
    activeMonsters.begin(),
    activeMonsters.end(),
    [](const auto& a, const auto& b)
    {
        if (a->GetHealth() != b->GetHealth())
        {
            return a->GetHealth() < b->GetHealth();
        }

        return a->GetId() < b->GetId();
    }
);

Si la función de comparación devuelve verdadero, significa que a debe ir antes de b. Si los criterios de comparación son contradictorios, no se puede confiar en los resultados de la clasificación, por lo que se debe observar un orden abreviado estricto.

remove_if y borrar

auto newEnd = std::remove_if(
    activeMonsters.begin(),
    activeMonsters.end(),
    [](const auto& monster)
    {
        return monster->IsDead();
    }
);

activeMonsters.erase(newEnd, activeMonsters.end());

remove_if no reduce directamente el tamaño del contenedor. Mueve los elementos restantes hacia adelante y devuelve el nuevo final lógico. El borrado real se realiza mediante borrado.

Cuando se elimina un elemento de un vector, los iteradores y referencias posteriores pueden dejar de ser válidos. Cuando se elimina un elemento share_ptr, su recuento de referencias disminuye y, si fue el último propietario, el objeto también se destruye.

El uso de lambda y algoritmos no necesariamente hace que el código sea más rápido. En cambio, la mayor ventaja es que la intención de buscar, ordenar y eliminar se expresa claramente en el código.