Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Temporary captured-variables in lambda functions - C++11

Tags:

c++

c++11

lambda

I was trying out something like this to pre-populate a map using a vector-list of strings. The code is self-explanatory:

Constructor(const vector<string>& names) {
  for_each(names.begin(), names.end(),
                     [this, counter = 1](const String& choice) mutable {
                            nameMapping.emplace(choice, counter++);
                        }
  );
}

Something I didnt really understand is how does counter work?

FYI: counter is no-where declared outside of the lambda function.

But yet, I am able to create a local-variable in class-scope and modify it in a mutable lambda fn?

Can someone please help me understand whats going on.

like image 764
Serial Lazer Avatar asked Oct 21 '25 04:10

Serial Lazer


1 Answers

When you set counter = 1 you're declaring a new temporary counter equal to 1. The compiler does the work of determining the type. This temporary object is deduced to type int by default, and lives while the lambda is alive.

By setting mutable you can both modify counter and this

Aside: since it appears that you're inserting into a map/unordered map, you're probably better off with the following:

#include <algorithm> // For transform
#include <iterator>  // For inserter

Constructor(const vector<string>& names) {
    auto const example = [counter = 1](const string& item) mutable {
        return {item, counter++};
    };
    std::transform(names.begin(), names.end(),
                   std::inserter(nameMapping, nameMapping.end()), example);
}

By moving the nameMapping call outside of the lambda, you don't have to confuse yourself with what is in scope and what is not.

Also, you can avoid unnecessary captures, and anything else that might confuse yourself or other readers in the future.

like image 51
Alex Shirley Avatar answered Oct 23 '25 20:10

Alex Shirley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!