In the following example program, I would expect the counter to reset at the beginning of each cycle:
#include <iostream>
#include <functional>
void run_lambda(std::function<void()> fun){ fun(); fun(); }
int main(){
for(int i = 0; i < 3 ; i){
run_lambda([i](){
static int testVal = 0;
std::cout << "value[" << i << "]:" << testVal << std::endl;
testVal;
});
}
return 0;
}
Instead the output is:
value[0]:0
value[0]:1
value[1]:2
value[1]:3
value[2]:4
value[2]:5
According to this answer:
The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.
In my understanding this means, that the lambda object life cycle is bound to the loops block scope, thus the static variable is not resetting at the start of the loop.
Is there a specific reason for this? Intuitively one would think that a lambda expression is essentially a temporary object, and as such in this example it would cease to exist after the statement.
CodePudding user response:
Your code is basically equivalent to:
#include <iostream>
#include <functional>
struct lambda
{
lambda(int i): i(i) {}
int i;
void operator()()
{
static int testVal = 0;
std::cout << "value[" << i << "]:" << testVal << std::endl;
testVal;
}
};
void run_lambda(std::function<void()> fun){ fun(); fun(); }
int main(){
for(int i = 0; i < 3 ; i){
lambda l{i};
run_lambda(l);
}
return 0;
}
Whilst each iteration of the loop does indeed create a new lambda object each object is an instance of the same class and therefore shares the same static variables.
The statement you're quoting is saying that the type is declared inside the scope where the lambda is declared. It isn't saying that each time the code enters that scope a new type is created (c doesn't have dynamic types like that).