Is it possible to replace one std::function
from within itself with another std::function
?
The following code does not compile:
#include <iostream>
#include <functional>
int main()
{
std::function<void()> func = []()
{
std::cout << "a\n";
*this = std::move([]() { std::cout << "b\n"; });
};
func();
func();
func();
}
Can it be modified to compile?
The error message right now is: 'this' was not captured for this lambda function - which I completely understand. I don't know, however, how I could capture func
's this
-pointer. I guess, it is not even a std::function
inside the lambda, yet?! How can this be done?
Background: What I want to achieve is the following: In the first invocation of a given std::function
, i would like do some initialization work and then replace the original function with an optimized one. I want to achieve this transparently for the user of my function.
The expected output of the example above is:
a
b
b
You cannot use this
inside a lambda to refer to the lambda. this
will only refer to the enclosing class, which in your case there is none so you cannot use this
. What you can do however is capture func
and reassign that:
std::function<void()> func = [&func]()
{
std::cout << "a\n";
func = []() { std::cout << "b\n"; }; // note the missing move, a lambda
// is already an rvalue
};
Note however that if you let func
outlive its scope (say by returning it from a function by value) without calling it first (effectively reassigning the stored function object) then you'll get a dangling reference.
I guess, it is not even a
std::function
inside the lambda, yet?!
It actually is. A name comes into scope right after its declarator, so right before the =
, func
of type std::function<void()>
is introduced. So at the point where you introduce the lambda, you can already capture func
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With