lambda_feature_image

In some cases, you may need to create a useful piece of code, which will be used just once. That moment, you might find yourself thinking about creating a function for that (which, in this particular case, will only get called once) and I imagine that while you’re thinking that you might be cringing (at least I would). Consider the following example:

You need to destroy an Actor after let’s say 5 seconds . Well that’s easy huh? You will just enable a timer and call the function Destroy() after 5 seconds using the following block of code:

However, when you do compile your code the following error occurs:

error

This happens because the above block of code is valid when the function you provided has a void return type and no parameters. The Destroy function has a bool return type so that’s why you get the compile error.

Then you find yourself thinking “That’s ok, I will just use a TimerDelegate and use a different overload of the SetTimer function”. Let’s see how this turns out. Consider the following code:

Ok, this code will compile just fine, however….when the time comes and the TimerManager will try to execute your bound function this is the result:

error1

Ok…now I’m kinda frustrated. “I will just create the following wrapper function and get it over with:”

If you resorted to such a solution this might happen again and again until you have more useless functions that you can count. Let’s see the easy solutions for this kind of problem!

Lambda Expressions

A Lambda expression is an anonymous function which does something useful*. You will find yourself using lambdas in cases similar to the one I described above. You need to create a functionality that will get called once and you don’t really need to name them.

*This means that you can’t use a lambda with the same way you use a function(ie this->DoSomething()).

Before we jump in and write our first lambdas, let’s breakdown their syntax first. A Lambda expression is defined using the following syntax:

[ ]( ) { //code goes here }

Ok.. wait what? What is this? Don’t worry! Everything will be clear in the following lines – so keep on reading! Lambdas (in this post at least) are divided into three “sections” (they are not really sections, I just used this word to better describe them)

  1. The Capture List: which is the [ ]
  2. The Argument List: which is the ( )
  3. And the Function Body which is enclosed in { }

Capture List

The capture list defines what from the outside of the lambda should be available inside your function body and how. For example, the capture list can be either:

  • A Reference of a variable or instance or whatever you want: [&] (This means that we passed as a reference the whole object which the lambda resides in)
  • A value: [x] (This means that we passed the variable x by value)
  • Any combination of the above

For example, the following capture list contains a reference of the current object and a value of the x variable: [&this, x]

Argument List

The argument list is exactly the same as the argument list of your “ordinary” functions. For example: (int n)

Function Body

The function body contains the logic of our function

Writing our first Lambda Expression

Let’s go back to the problem introduced in the intro section of the post. I will recap just in case you forgot: We need to destroy an Actor after 5 seconds however everything we’ve tried has not worked. The workaround is pretty simple (and slick!). We’ll just use a lambda expression:

I hope you have noticed the “&” inside the capture list. I passed as reference the whole object in order to have access to it’s Destroy function. If you ommit the “&” symbol your code won’t compile because the compiler will not be able to access the function you need in this case.

I created a C++ class which inherits from Actor and typed the above code right after the Super::BeginPlay. Then, created a blueprint based on my class and placed in on my level. The output after 5 seconds is:

output

Wow! That’s cool, right!? We got away from declaring and typing logic for a function that is going to be used only once!

Let’s create more lambdas just to demonstrate their usage and better understand the capture list!

Lambda with parameters

In the following example, I want to have an Array with all my actors in the current level. Then, I will choose a random one by index and print out its’ name.

To do this, I created a First Person Blueprint Project and added a C++ class which inherits from the Actor class. After that, I’ve modified my BeginPlay function:

After creating  a Blueprint and placing it inside my level here is my output:

output2

Please note that your output might differ since this example depends on your map!

Share postShare on Facebook23Tweet about this on TwitterShare on LinkedIn0Share on Reddit0