【发布时间】:2021-04-07 14:13:51
【问题描述】:
当我写[&,x](){ /* making use of x */ }时,x被值捕获。
当我写[=,&x](){ /* making use of x */ } 时,x 被引用捕获。
如果我尝试编写 [&x, x](){ … },我收到一条错误消息,告诉我 x 只能在捕获列表中出现一次。
但是,[&x, y = std::move(x)](){ /* making use of x and y */ }(); 可以正常编译,但出现分段错误。
为什么代码甚至可以编译?为什么标准允许我通过引用捕获变量,并且我还在“通过移动捕获”初始化捕获中使用它?
【问题讨论】:
-
“但我遇到了分段错误。”。这是由于 lambda 的主体不正确。因为您似乎错误地使用了已移动的
x。 -
“一个错误告诉我 x 只能在捕获列表中出现一次” - 很难将有关 init-capture 的所有约束都放入一个简洁的错误消息中。重要的是要记住捕获的哪些部分被转换为闭包的成员。我们不能有两个同名的不同成员。这就是“必须出现一次”的上下文。
-
@Jarod42,这就是我的观点。我可以(错误地)在正文中使用
x,因为我也通过引用捕获它,除了将它移动到y。 -
@StoryTeller-UnslanderMonica,我认为您的评论可能是一个很好的答案。
-
rust 不允许使用从对象移动,C++ 允许,你甚至可能有有效的情况。另请注意,
auto y = std::move(x); auto lambda = [&x, &y](){/*..*/};的行为与您的相似。