按值捕获成员变量

时间:2010-09-15 13:22:02

标签: c++ lambda c++11

使用C ++ 11 lambda表达式时,如何按值捕获成员变量?

使用[my_member]语法似乎不起作用,隐式捕获使用this指针。需要的是一种明确指定成员变量的捕获类型的方法。这可能吗?

我的解决方法目前是:

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
}

5 个答案:

答案 0 :(得分:7)

我认为您不能按值捕获成员,您可以捕获this但由于该成员是this的一部分,您将使用共享成员而不是新变量。

不知道你的成员是什么类型的东西应该有用:

auto copy = my_member;
std::async([copy]{ std::cout << copy; });

我不明白为什么你在你的例子中使用shared_ptr,如果你想要按值捕获肯定shared_ptr是你应该考虑的最后一件事。

答案 1 :(得分:4)

不幸的是,我认为没有直接的方法可以做到这一点,但我可以想到几种方法来捕获一个成员而不需要额外的副本。

第一个选项与您的示例类似,但使用了对局部变量的引用:

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; });
}

请注意,4.6.2版本的GCC中存在导致值无法复制的错误。请参阅Capturing reference variable by copy in C++0x lambda

第二种方法是使用bind来制作副本:

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));
}

在此示例中,bind将创建自己的my_member副本,然后通过引用将此副本传递给lambda表达式。

答案 2 :(得分:3)

由于你的问题是关于C ++ 11,这不是一个真正的答案,但在C ++ 14中你可以这样做:

void member_function()
{
    std::async([my_member=my_member]{ std::cout << *my_member; });
}

它与你自己的“解决方法”相同(如果my_member是shared_ptr)。

答案 3 :(得分:1)

auto& copy = my_member;
std::async([copy]{ std::cout << copy; });

自动&安培; (上图)也可以工作并避免复制两次。虽然这种方法比传递[this]更多的语法,但它避免了传递给对象[this]所指向的对象的依赖。

答案 4 :(得分:-1)

现在,我遇到了同样的问题,并自己解决了这个问题:

  1. 捕获this指针。
  2. 然后在lambda:
  3. 中写入this->member语法

    即,

     std::async([this]{ std::cout << this->my_member_; } ); 
     //          ^^^^                ^^^^^^ use this syntax
     //           | 
     //           ^
     //           capture `this` as well
    

    它对我有用。我希望它也适合你。但是,我对这方面的知识并不完全满意。在我的工作之后,我将查找需要此语法的原因,或者它是编译器错误。我正在使用GCC 4.5.0(MinGW)。

    好吧,我找到了以下主题,其中应该捕获this指针以便使用该类的成员。