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

C++ 기초부터 마스터까지 — 11화

람다와 표준 알고리즘 사용하기

INTERACTIVE READING MODE →

본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.

컨테이너에서 특정 몬스터를 찾거나 정렬하고 죽은 몬스터를 제거하는 코드는 자주 등장한다. for문으로 직접 만들 수도 있지만 표준 알고리즘을 사용하면 코드의 목적이 더 잘 보인다.

람다

람다는 이름 없이 바로 작성하는 함수이다.

int monsterId = 10;

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

[]는 캡처 목록이다. [monsterId]는 값을 복사해서 캡처하고, [&]는 외부 변수를 참조로 캡처한다. [this]는 현재 객체를 사용한다.

참조 캡처는 편하지만 람다가 원본 변수보다 오래 살아남으면 위험할 수 있다. 필요한 값만 명확하게 캡처하는 편이 코드를 읽기 쉽다.

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는 조건을 만족하는 첫 원소의 반복자를 반환한다. 찾지 못하면 전달한 범위의 end를 반환한다.

sort

체력이 낮은 몬스터부터 정렬하고, 체력이 같으면 ID가 낮은 몬스터를 먼저 둘 수 있다.

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();
    }
);

비교 함수가 true를 반환하면 a가 b보다 앞에 와야 한다는 뜻이다. 비교 기준이 서로 모순되면 정렬 결과를 믿을 수 없으므로 엄격 약순서를 지켜야 한다.

remove_if와 erase

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

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

remove_if는 컨테이너 크기를 직접 줄이지 않는다. 남길 원소를 앞으로 옮기고 새로운 논리적 끝을 반환한다. 실제 삭제는 erase가 수행한다.

vector에서 원소가 삭제되면 뒤쪽 반복자와 참조가 무효화될 수 있다. shared_ptr 원소가 제거되면 참조 횟수가 감소하고, 마지막 소유자였다면 객체도 파괴된다.

람다와 알고리즘을 사용한다고 코드가 무조건 빨라지는 것은 아니다. 대신 찾기, 정렬, 제거라는 의도가 코드에 그대로 나타나는 것이 가장 큰 장점이다.