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

C++ 基礎からマスターまで — 第11回

ラムダと標準アルゴリズムの使用

INTERACTIVE READING MODE →

本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。

コンテナから特定のモンスターを探したり整列したり、死んだモンスターを削除するコードは頻繁に登場する。 for文で直接作成することもできますが、標準アルゴリズムを使用すると、コードの目的がよりよく見えます。

ラムダ

Lambdaは名前なしで直接書く関数です。

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は条件を満たす最初の要素の反復子を返します。 見つからない場合は、渡した範囲の終了を返します。

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要素が削除されると参照数が減り、最後の所有者であればオブジェクトも破壊されます。

ラムダとアルゴリズムを使用してもコードが無条件に高速化されるわけではありません。 代わりに、検索、並べ替え、削除という意図がコードにそのまま現れるのが最大の利点です。