How would I catch a member variable by value when using C++11 lambda expressions?
Using the [my_member]
syntax doesn't se开发者_Python百科em to work, and implicit capture uses the this
pointer. What is need is a way to explicitly specify capture type of member variables. Is that possible?
My workaround for now is:
void member_function()
{
std::shared_ptr<my_member_class> my_member_copy = my_member; // this shouldn't be necessary
std::async([=]{ std::cout << *my_member_copy; });
// std::async([=]{ std::cout << *my_member_; }); // wrong, my member could be potentially out of scope
}
I don't think you can capture a member by value, you can capture this
but since the member is part of this
you'll be using a shared member and not a new variable.
Not knowing what type your member is something like this should work:
auto copy = my_member;
std::async([copy]{ std::cout << copy; });
I don't understand why you're using a shared_ptr
in your example, if you want to capture by value surely shared_ptr
is the last thing you should consider.
Unfortunately, I don't think there is a straight-forward way to do this, but I can think of a couple of ways to capture a member without making an extra copy.
The first option is similar to your example but uses a reference for the local variable:
void member_function()
{
std::shared_ptr<my_member_class> &my_member_ref = my_member;
// Copied by the lambda capture
std::async([my_member_ref]{ std::cout << *my_member_ref; });
}
Note that there is a bug in pre 4.6.2 versions of GCC that cause the value not to be copied. See Capturing reference variable by copy in C++0x lambda.
A second approach would be to use bind to make the copy:
void member_function()
{
// Copied by std::bind
std::async(std::bind([](const shared_ptr<my_member_class>& my_member){
std::cout << *my_member; }, my_member));
}
In this example, bind will make its own copy of my_member
, and this copy will then be passed to the lambda expression by reference.
Since your question is about C++11 this is not really an answer, but in C++14 you can do like this:
void member_function()
{
std::async([my_member=my_member]{ std::cout << *my_member; });
}
It does the same thing as your own "work-around" (if my_member is a shared_ptr).
auto& copy = my_member;
std::async([copy]{ std::cout << copy; });
auto& (above) also works and obviates copying twice. Although this approach is more syntax than passing [this], it obviates passing into the closure a dependency on the object [this] points to.
Right now, I faced the same problem and solved it myself:
- Capture the
this
pointer. - then write
this->member
syntax inside the lambda:
That is,
std::async([this]{ std::cout << this->my_member_; } );
// ^^^^ ^^^^^^ use this syntax
// |
// ^
// capture `this` as well
It works for me. I hope it should work for you too. However, I'm not completely satisfied with this knowledge. After my work, I'll look for the reason why this syntax is required, or it is a compiler bug. I'm using GCC 4.5.0
(MinGW).
Well, I found the following topic which says this
pointer should be captured in order to use the member of the class.
- Capturing this required to access member functions?
精彩评论