Range-Based For Loops, They're Great!

In the UE4 code base, we have started taking advantage of some of the cool features added in C++11. We are cautious when adopting new language features because we target a wide range of platforms with varying compiler support. One of my favorite new features though is ‘range-based for loops’, which now works on Unreal’s TArray, TMap and TSet containers. Here is an example of how this can really clean up common game code. Previously if I wanted to iterate over an array of AActor* pointers, it used to look like:


TArray<AActor*> Actors;
for (int32 ActorIndex=0; ActorIndex<Actors.Num(); ActorsIndex++)
{
	AActor* Actor = Actors[ActorIndex];
	Actor->SetActorLocation(NewLocation);
}

But using the ‘range-based for loop’ syntax it now looks like:


TArray<AActor*> Actors;
for (AActor* Actor : Actors)
{
	Actor->SetActorLocation(NewLocation);
}

How nice is that! Here is another example with a TMap – it used to look like this:


TMap<AActor*, FMyStruct> ActorStructs;
for (auto ActorStructIt = ActorStructs.CreateIterator(); ActorStructIt; ++ActorStructIt)
{
	AActor* Actor = ActorStructIt.Key();
	FMyStruct& Data = ActorStructIt.Value();
}

But now it looks like:


TMap<AActor*, FMyStruct> ActorStructs;
for (const auto& Entry : ActorStructs)
{
	AActor* Actor = Entry.Key;
	const FMyStruct& Data = Entry.Value;
}

Note that you are still responsible for putting ‘const’ or ‘&’ on the variable you declare e.g.


TArray<FVector> Positions;
for (FVector& Position : Positions)
{
	Position.z += 10.f;
}

You need to add the ‘&’ to have a reference to rather than a copy of the FVector. We are not going to start reformatting every for loop in the engine, but I certainly plan to use this syntax a lot going forward.
I’d love to hear what you guys think about this feature and answer any questions you might have.

Handy :wink:

Like that!

Great a “C# Foreach” like loop!
A lot less tedious to declare and also safe against out-of-range access! .
Congrats! Nice addition! :smiley:

Nice post. Although I still prefer to create Iterators explicitly in some cases. They are nice at handling cases, when amount of items and order of them can change in array dynamically. Range loop will create memory leak if it hit index that no longer exist, but have been present when loop has been still active.

IIRC, isn’t a foreach loop a little slower than a standard for loop? They are certainly handy, but I’m curious about the speed difference, especially with Unreal’s classes.

Pretty much like a C# Foreach without copying the reference which is faster! :rolleyes:
But I don’t mind the old C++ way! :slight_smile:

Cool feature!
thanks for the tip :smiley:

I use C++11 features in my projects. And “range-based for loops” is one of the best features, IMHO.
It gives us a good code readability and errors checking.
I think that you would (should) use new standard, so

  • clang on ps4/mac/ios with 100% c++11 support,
  • gcc 4.8/4.9 on GNU/linux,
  • mingw on win32/64 (don’t trust msvc…).

:slight_smile:

I love this post! Give us some more Programming post please…

Range based for loop are guaranteed to be as fast as possible, so faster than many manually written loop:

Thanks! Will try and think of some more… any ideas?

I will think about it while working on my Git Source Control Plugin, but here a few remarks:

Some blog posts could go deeper into code, thus we would learn a lot more and get some useful insights! For instance, the post about template libraries was only a basic intro. you could make a new one to dive a bit more with more complete examples, some useful algorithms…

Subjects:
Threading, synchronisation primitives, job queue in Tick()…
Executing process/commands (like in source control plugins)
Parsing strings, XML, j’en…

And why not a few real game or engine code reading & architecture review: Plugin Manager, Renderer…

My point is that you would help devs diving into the Engine, so they can help improve/extend it :slight_smile:

Cheers