Greetings, GameDev.tv Community! Thank you all for your time reading, I wanted to introduce myself and share a bit about my goals for this blog. I'm a bit of an odd duck! I don't actually know Unreal or Unity all that well, my interests are mostly in the languages and more advanced topics and techniques. I like to fancy myself an engine developer, but truthfully, I'm not there yet! I am a fairly competent C++ developer, however, and I find myself digging into obscure and rare aspects of system programming pretty regularly, so if you're looking for advanced topics, click that subscribe button, and I'll do my best to come through for you!

Let's take a look in my prototype archives and see if there's anything interesting there to talk about... Hmm. How about lambdas? I know I had a lot of struggle understanding lambdas, so let's dig in and go through some examples of how to use them!

What is a lambda? Well, to be honest, it's really just a fancy language feature that you don't really need to use, but what it provides you is a compact way to express certain kinds of code. A C++ lambda follows a specific form: [] () {}

You might notice that this is similar to a standard function declaration, except that instead of naming the function, we replace it with []. This is the "capture" clause, and instead of using something like void MyFunction you'd instead define what you want to "capture" from the calling scope to be used inside the lambda.

The easiest thing to do is put [&] there, which essentially says "capture everything in the calling scope by reference". Note this is probably not the best practice here, you should only capture what you NEED, but this is a valid way to write a lambda.

Before we get too deep into this, let's actually look at some example code, and I'll show you how to use this capture clause.

std::vector CollectionToIterate{ 11, 21, 31, 41 };
int VariableToCapture = 10;

std::for_each(CollectionToIterate.cbegin(), CollectionToIterate.cend(),
[&](auto& element) { VariableToCapture += element; }
);

Here we are using the Standard Template Library's Algorithm for_each which, as you might expect, executes a for loop on each element in the collection. We'll get into the "element" part of it in a moment, but let's first look at where that capture lives and what it does...

std::for_each has three arguments, the collection begin and end, and a "predicate" argument. The predicate in this case is where we provide either a function, a functor, or a lambda expression to "do something" with the elements in the collection. In this case, we've entered a lambda expression, can you see it?

std::vector CollectionToIterate{ 11, 21, 31, 41 };
int VariableToCapture = 10;

std::for_each(CollectionToIterate.cbegin(), CollectionToIterate.cend(),
[&](auto& element) { VariableToCapture += element; }
);

And as you can see, we've put in our "capture everything" statement [&] here. What this does is it means that the variables VariableToCapture and also the collection CollectionToIterate are both available within the scope of the lambda. In this case, we're NOT using the capture of the CollectionToIterate IN the lambda, it's only being used by the for_each algorithm.

So then, what's this second part with the (auto& element) ??? This is tricky, because it's totally voodoo magic that happens, but remember where I said the last argument to for_each was the predicate? Well, weirdly, this allows you to name the predicate so that you can then use it in the lambda. What happens here is the algorithm for_each presents a pointer to the element in the collection to your lambda, you then decide what you're going to call it, in this case, I called it "element", but you can name it anything you'd like.

What happens here then is the elements in our collection (11, 21, 31, 41) are then presented to the predicate as a thing named "element" that we can perform operations with. In this case, we add the value of the element to the VariableToCapture variable. What do you think the result of running this program would be?

Did you guess VariableToCapture would equal 114? You'd be right! The collection contains the values 11, 21, 31 and 41, which are presented as "element" in our expression. Each time we loop (it will loop four times because there are four things in the collection), we take the current value of VariableToCapture and we add the value of the element to it. First loop, 10 + 11, second loop 21 + 21, third loop 42 + 31, last loop 73 + 41 = 114!

We can dig so much more deeply into this, and in our next blog we'll demonstrate some really fancy lambda usage, including using a collection of lambda expressions to define multiple filter values to use against a collection of elements. Stay tuned, and feedback appreciated! Until next time...