Reputation: 26335
There are sometimes cases where I do a std::find_if
(for example) in a local function that has 5 local variables, including parameters. However, the lambda I pass into the STL algorithm only needs access to 1 of those. I could capture this in one of two ways:
void foo(int one, int two, int three)
{
std::vector<int> m_numbers;
int four, five;
std::find_if(m_numbers.begin(), m_numbers.end(), [=](int number) {
return number == four;
});
}
Or I can do:
void foo(int one, int two, int three)
{
std::vector<int> m_numbers;
int four, five;
std::find_if(m_numbers.begin(), m_numbers.end(), [four](int number) {
return number == four;
});
}
(Note I didn't compile this code, apologies for any syntax errors or other mistakes)
I know that implicit captures are based on odr-used rules, so functionally and implementation-wise, I think both are identical. When would you use explicit captures over implicit ones? My only thought is somewhat related to principles of encapsulation: Having access to only the stuff you need allows the compiler to help you determine when you access a variable you shouldn't. It also keeps the local state of the method (it's invariants, for the lifetime of the function during its execution) safer. But are these really practical concerns?
Are there functional reasons to use explicit captures over implicit ones? What is a good rule of thumb or best practice to follow?
Upvotes: 12
Views: 5454
Reputation: 1104
Upvotes: 8
Reputation: 141554
It is simplest and the most efficient at runtime to use [=]
or [&]
, without naming any names.
In these cases, as described by this answer, variables are only captured if they are odr-used. In other words the compiler only captures what is needed.
If you specify a capture list then two differences can happen:
In the second case, if capturing by value, this means the object is unnecessarily copied.
So, my advice would be to use []
, [&]
, or [=]
unless you can think of a good reason otherwise for a specific situation. One such case might be if you wanted to capture some variables by reference and some by value.
Upvotes: 5