开发者

capture member variable by value

开发者 https://www.devze.com 2023-01-16 19:08 出处:网络
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

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:

  1. Capture the this pointer.
  2. 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?
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号