2

I have this piece of code:

    void function1(char c, bool b){

         auto get_allowed = [&](int x){
                if(b){
                  .... some code...
                }
                ...some code...
         }

         get_allowed(0);
         ...other_code...
}

Can I use b inside the lambda function in this case??

I means, is the same thing to add that parameter into signature of lambda function, something like:

    void function1(char c, bool b){

         auto get_allowed = [&](int x,bool b){
                if(b){
                  .... some code...
                }
                ...some code...
         }

         get_allowed(0, false);
         ...other_code...
}

To clearify, the difference is here:

 auto get_allowed = [&](int x){
get_allowed(0);

VS

 auto get_allowed = [&](int x,bool b){
get_allowed(0, false);

where b is a parameter of the function function1.

2
  • What happens when you try it? If it's not allowed, the compiler would report an error. Commented Oct 18, 2016 at 17:01
  • @Barmar, as I'm sure you know C++ is not that easy. Commented Oct 18, 2016 at 17:06

4 Answers 4

2

In your example, the effect of both version of you lambda is roughly the same. However, there is a significant difference that lies in captured parameters vs "normal" parameters.

Here is how a lambda is created:

[ capture-list ] ( params ) { body }

The capture-list can give you access to variables that exist in the scope surrounding your lambda. There are some of the different capture modes:

  • [&] captures by reference all local variables in the surrounding scope (ie. b and c in your example)
  • [&b] captures only b by reference, you can put as many named variables as you wish (comma separated)
  • [=] captures by value all local variables in the surrounding scope (in other words: your lambda holds a copy of those variables)
  • [b] captures only b by copy
  • [b, &c] you can mix copy and reference captures

You should ask yourself : what are those captures for?

Well, it defines a closure, a context, which is the same each time the lambda is used. That kind of state added on top of a function is very useful in many situations.

One example: you are mapping a lambda on each element of a collection:

std::vector<int> numbers = {1, 2, 3, 4, 5};

int sum = 0;
std::for_each(std::begin(numbers), std::end(numbers),
              [&sum](int n){ sum += n; });

Here, we are using a variable captured by reference to store (and update) the sum of all the numbers in the vector.

Take some time to reflect on this example, make some experiments of your own, and this is about all there is to know about lambdas. :)

Sign up to request clarification or add additional context in comments.

Comments

1

The [&] capture list makes sure that the variables in the scope surrounding the definition of the lambda can be used by reference in the body of the lambda function.

So yes: in the first snippet, b is usable in the lambda (just don't forget the semi-column to end the function assignment). And you even can change its value (affecting b in get_allowed() would change the value of the parameter b of function1() as it is captured by reference) !

In the second snippet, you pass b as parameter by value. This works differently. There b is the name of a parameter passed by value, and it has nothing to do with the b of the enclosing scope.

Additional remarks

Attention: if your lambda survives the scope that defines it (for example, if you'd return the lambda from function1() or store the value of get_allowed), you could have problems with a capture by reference ; invoking the lambda later in another context could reference variables which no longer exist (dangling reference).

If you prefer a looser coupling, you may consider the [=] capture list instead: it has a similar effect, but the captured variables are passed by value (i.e. no accidental modification nor dangling references). This makes the lambda more independent the context in which it was created.

Comments

1

In the first example get_allowed is a function of one argument where b is captured implicitly (because you captured with [&]).

In the second, get_allowed is a function of two arguments where b is passed explicitly to get_allowed rather than taken from the surrounding function.

The lambda is unnecessary in this example so the difference is a bit academic.

Comments

1

Can I use b inside the lambda function in this case??

Yes, you can use b inside the lambda.

[&] captures all automatic variables odr-used in the body of the lambda by reference

b is captured by reference

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.