Trying to keep an object alive (but not needing to reference the shared_ptr to do so) I found myself writing stuff like this:
void ClassDerivedFromSharedFromThis::countdown(ThreadPool &pool, std::string name){
auto self = shared_from_this();
pool.then([=, self]{
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
But then got an error in visual studio that said I couldn't copy-capture explicitly because I was already copy-capturing implicitly... This forced me to write:
void countdown(ThreadPool &pool, std::string name){
auto self = shared_from_this();
pool.then([=]{
self; //Capture self.
for(int i = 0;i < 10;++i){
atomic_cout() << "Hey [" << name << "]! Our counter is: " << atomicCounter++ << "\n";
}
});
}
I know this works, but it feels wrong. Since I only need the side-effect of the shared_ptr ownership and do not need to reference it directly I would like to express this in the capture list instead of the lambda body.
In my real code I have about 5 or 6 variables I wanted to capture across a couple nested lambdas in network code and implicit capture was way nicer and easier to edit.
My question is: is this standard behaviour or Visual Studio 2015's own take on lambda capture limitations? Do newer versions of the standard allow for this, or has anyone talked about it?
Yes this is standard behavior. From C++14 (N4140) [expr.prim.lambda]/8
If a lambda-capture includes a capture-default that is
=
, each simple-capture of that lambda-capture shall be of the form “& identifier”.
So if you have [=]
then any other capture you do must be done by reference like
[=, &some_var]{} // copy all implicitly but explicitly capture some_var by reference
The rules do change in C++17 but it is to allow
[=, *this]{};
Which will capture a copy of the object into the lambda.
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