I want to dynamically change the behaviour of a method of a class, so I implemented these method calling the operator() of a std::function holding a copy of one lambda function, that depends on some values known only after the class construction, at a time.
The lambdas change the state of the class, so they reset a container holding the behaviours of all dynamic methods.
Executing the above idea I was not able to access the capture list of the lamba after resetting the container.
The following snippet reproduces the problem:
std::vector< std::function<void(std::string)> > vector;
int main() {
//Change class state when variable value will be known
std::string variableValue = "hello";
auto function = [variableValue](std::string arg) {
std::cout <<"From capture list, before: "<< variableValue << std::endl;
std::cout <<"From arg, before: " << arg << std::endl;
vector.clear();
std::cout << "From capture list, after: " << variableValue << std::endl;
std::cout << "From arg, after: " << arg << std::endl;
};
vector.push_back(function);
//Dynamic method execution
vector[0](variableValue);
return 0;
}
Producing output:
From capture list, before: hello
From arg, before: hello
From capture list, after:
From arg, after: hello
where variableValue is invalidated after vector was clean.
Is the capture list invalidation an expected result? Is safe using any other local variable, not only in the capture list, after calling std::function destructor? Is there a suggested way / pattern to accomplish the same behaviour in a safer way (excluding huge switches/if on class states)?