【问题标题】:Why move capture is not supported in C++ lambda?为什么 C++ lambda 不支持移动捕获?
【发布时间】:2012-11-11 10:02:13
【问题描述】:

当前的 C++11 标准不支持在 lambda 表达式中移动捕获变量,如

unique_ptr<int[]> msg(new int[1000000]);
async_op([&&msg] { // compile error : move capture is not supported
   /* do something */
});

由于消息传递和唯一所有权在某些异步系统设计中具有一些关键作用,我认为移动语义应该被视为一流的语言语义。但是 lambda 不支持移动捕获。

当然我知道使用移动捕获代理有一些解决方法 - 但我想知道 原因 决定此功能不包含在 C++11 标准中,尽管它很重要.

【问题讨论】:

  • 原因很可能是他们在引入 lambdas 时根本没有想到这一点。 FWIW,委员会正在重新设计捕获部分,并考虑通过允许初始化程序捕获来概括它(又名[m = std::move(msg)]{ ... })。
  • 感谢您的回答。在捕获列表中允许初始化表达式看起来很有希望。
  • @rubenvb:每次调用 lambda 时都会复制捕获吗? :P 对于复制,我假设捕获也被复制。如果它是只能移动的,那么 lambda 将不可复制。
  • @rubenvb:我看不出哪里有隐藏动作。如果移动 lambda,则移动捕获。如果您复制 lambda,您(尝试)复制捕获。我看不出这有多令人困惑,但也许这就是我。

标签: c++ c++11 lambda move-semantics


【解决方案1】:

C++ 规范试图相当保守。下一个语言规范破坏符合上一个规范的程序真的很糟糕。

移动语义需要一段时间才能成熟。如果我记得的话,直到 2009 年才有变化。同时,直到类似的时间框架,许多编译器才实现 lambda。来不及填补空白,2011年还是发布标准,已经很晚了。 (使用编译器对规范进行原型设计,测试编译器,返回并讨论规范、草稿、原型、测试、重复。需要一段时间。)

Lambda 将在下一个标准中得到很大的扩展,获得类型推导(auto 多态性)。 Xeo 提到了一种移动初始化的潜在解决方案。

请注意,lambda 只是语法糖。它们是根据自动定义的类指定的,但不包含您不能自己做的任何事情。至于目前的语言标准,当糖用完时,您应该手动充实该实现。

顺便说一句,您可以通过捕获老式的auto_ptr 来解决缺少的功能,这是 C++03 现在已弃用的智能指针尝试。它被自己的复制构造函数无效,本质上实现了移动复制。但它已被 C++11 弃用,可能会导致警告。不过,您可以尝试实现类似的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-26
    • 2017-10-28
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 2019-05-01
    • 1970-01-01
    相关资源
    最近更新 更多