2010-09-15 63 views
8

当我使用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 
} 

回答

7

我不认为你可以捕捉价值的一员,你可以捕捉this但因为成员是this一部分,你会使用共享成员,而不是一个新的变量。

不知道什么类型的成员是像这应该工作:

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

我不知道,明白为什么你用在你的例子一个shared_ptr,如果你想通过值捕捉肯定shared_ptr是你应该考虑的最后一件事。

+0

我需要按值进行捕获,以便将shared_ptr引用计数递增。否则,在父对象被销毁时对象将被销毁,从而在异步操作中导致潜在的访问冲突。 (忘了在lambda中添加*)。 我不明白你的例子与我的不同。 – ronag 2010-09-15 14:41:31

+0

“不知道什么类型的成员是这样的应该工作:”,我写std :: shared_ptr而不是auto的原因是明确“my_member”的类型,即shared_ptr 。 – ronag 2010-09-15 15:39:48

-1

现在,我面临同样的问题,解决它自己:

  1. this指针。
  2. 然后写里面拉姆达语法this->member

也就是说,

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

这对我的作品。我希望它也适用于你。但是,我对这些知识并不完全满意。在我工作之后,我会寻找为什么需要这个语法的原因,或者它是一个编译器错误。我正在使用GCC 4.5.0(MinGW)。

那么,我发现以下主题,其中说this指针应该被捕获,以便使用类的成员。

+4

但是,这捕获“this”不是实际的成员变量,所以如果“this”被删除,那么它将导致未定义的行为。 – ronag 2011-10-30 16:12:48

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

注意,有在GCC的4.6.2之前版本的导致无法复制的价值的错误。见Capturing reference variable by copy in C++0x lambda

第二种方法是使用结合,使复印件:

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

在这个例子中,绑定将作出自己的my_member副本,该副本然后将通过参考被传递给lambda表达式。

+0

你的例子都不同于我的例子。 – ronag 2012-03-02 12:46:42

+3

@ronag我的例子和你的解决方法之间的主要区别是我的例子没有额外拷贝'my_member'。我的第一个例子仅仅是将成员绑定到本地引用,允许它在lambda捕获中被值捕获而不被首先复制。我的第二个例子是避免需要一起使用局部变量的一种方法,使用bind通过值来捕获my_member而不是lambda捕获。 – rkjnsn 2012-03-02 22:23:14

+0

@ronag:rkjnsn是正确的,他的例子在构建'my_member_copy'时保存了递增/递减/指针拷贝,因此应该更快。你为什么会低调回答他的答案? – marton78 2012-11-12 13:23:24

2

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

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

它做同样的事情作为自己的“工作 - 周围“(如果my_member是shared_ptr)。

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

auto &(above)也可以工作并避免复制两次。尽管这种方法比传递[this]的语法更多,但它避免了将对象[this]所指向的依赖关系传递给闭包。