【问题标题】:Closure default capture overhead关闭默认捕获开销
【发布时间】:2015-10-30 12:36:47
【问题描述】:

使用默认捕获模式是否有任何开销?

{
   Foo foo = ...;
   Bar bar = ...;
   [&]()
   {
       write(foo);
   }
}

{
   Foo foo = ...;
   Bar bar = ...;
   [&foo]()
   {
       write(foo);
   }
}

澄清一下,即使不使用,使用与捕获条相关的前者是否有任何成本?

【问题讨论】:

  • 当你说“成本”时,你是什么意思?贮存?执行时间处理时间?编译时间?还有什么?
  • @JoachimPileborg 我的意思是在第一种情况下是否有任何运行时成本,例如更多存储
  • 没有任何费用。在第一种情况下,仅捕获您实际使用的变量。

标签: c++ lambda c++14


【解决方案1】:

未指定 lambda 如何处理通过引用捕获的实体,来自 C++14 标准草案 (N4140) 部分 5.1.2 [expr.prim.lambda]:

一个实体被隐式或显式引用捕获 捕获但未通过副本捕获。未指定是否 在闭包中声明了其他未命名的非静态数据成员 通过引用捕获的实体的类型。一个匿名的成员 union 不应被引用捕获

此措辞是故意保留的,以允许实现对此进行优化,请参阅 defect report 750: Implementation constraints on reference-only closure objects 引用 N2927 ,其中说:

新的措辞不再指定任何重写或关闭成员 “通过引用”捕获。 “通过引用”捕获的实体的使用 影响原始实体,实现这一点的机制是 完全留给实现。

【讨论】:

    【解决方案2】:

    N3337 5.1.2/15 或 N4527(C++14 最终草案)5.1.2/16

    一个实体被隐式或显式引用捕获 捕获但未通过副本捕获。 未指定是否 在闭包中声明了其他未命名的非静态数据成员 通过引用捕获的实体的类型。

    【讨论】:

    • 注意N3337 是最接近 C++11 的草案,而 N4140 是最接近 C++14 的草案,这是 OP 标记问题的内容。我们可以从我的回答中看到N4140 的引用是不同的,尽管差异不会影响这个问题。在很多情况下,C++11 和 C++14 的答案是不同的。虽然N4527 将是当前可用的最新工作草案,但基本上是 C++1z。
    猜你喜欢
    • 1970-01-01
    • 2020-07-25
    • 2017-04-23
    • 2021-08-10
    • 2013-12-28
    • 2011-05-22
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    相关资源
    最近更新 更多