2014年5月12日

範囲ベースの for ループ

作成 James Golding

アンリアル・エンジン 4 のコードベースでは、C++11 に追加された素晴らしい新機能がいくつか利用されています。言語の新たな機能を使用する場合、私たちは慎重になります。と言うのも、扱わなければならないプラットフォームが多岐にわたり、さまざまなコンパイラがサポートされているからです。とは言うものの、私が好きな新機能には「範囲ベースの for ループ」があります。これは、アンリアルの TArray、TMap、TSet のコンテナで使われています。この機能によって通常のゲームコードが非常にすっきりする例をあげてみます。AActor クラス型のポインタの配列をイテレートする場合は、これまでであれば次のようにしていたものです。

TArray<AActor*> Actors;

for (int32 ActorIndex=0; ActorIndex<Actors.Num(); ActorsIndex++)

{

AActor* Actor = Actors[ActorIndex];

Actor->SetActorLocation(NewLocation);

}

ところが、「範囲ベースの for ループ」の構文を使うと、次のように書けます。

TArray<AActor*> Actors;

for (AActor* Actor : Actors)

{

Actor->SetActorLocation(NewLocation);

}

見事です!もう一つ、TMap の例をご覧に入れましょう。以前であれば、次のように書いていました。

TMap<AActor*, FMyStruct> ActorStructs;

for (auto ActorStructIt = ActorStructs.CreateIterator(); ActorStructIt; ++ActorStructIt)

{

AActor* Actor = ActorStructIt.Key();

FMyStruct& Data = ActorStructIt.Value();

}

今は、次のようにできます。

TMap<AActor*, FMyStruct> ActorStructs;

for (const auto& Entry : ActorStructs)

{

AActor* Actor = Entry.Key;

const FMyStruct& Data = Entry.Value;

}

なお、宣言した変数には、まだ「const」や「&」を付けなければなりません。

TArray<FVector> Positions;

for (FVector& Position : Positions)

{

Position.z += 10.f;

}

FVector のコピーではなく、参照を使えるようにするためには、「&」を追加する必要があります。私たちがエンジン内にある for ループの形式をこれからすべて書き直すということはありませんが、私は今後この構文を必ず使用することにします。

この機能に関する皆さんの意見をぜひお聞かせください。また、質問がありましたら、ご遠慮なくどうぞ。私の Twitter のアカウントは、@EpicJamesG です。フォーラムにもいますので、ぜひ探してください。