默认闭包捕获开销

6

使用默认捕获模式会有任何开销吗?

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

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

请问在使用前一个选项时,即使不使用 bar 被捕获,是否会产生任何费用?

4
当你说“成本”时,你指的是什么?存储?执行时间?编译时间?还是其他什么东西? - Some programmer dude
@JoachimPileborg 我的意思是,如果第一种情况下有任何运行时成本,比如更多的存储空间。 - José
3
没有费用。只有你实际使用的变量被捕获在第一种情况下。 - jalf
2个回答

4
这段话来自C++14标准草案(N4140)第5.1.2节[expr.prim.lambda],其中未指定lambda如何处理被引用捕获的实体:

如果实体是被隐式或显式地捕获但不是通过复制捕获,则该实体将被引用捕获。对于被引用捕获的实体,闭包类型中是否声明了额外的未命名非静态数据成员是未指定的。匿名联合体的成员不得被引用捕获。

这种措辞故意保持开放,以允许实现围绕此进行优化,请参见缺陷报告750:Implementation constraints on reference-only closure objects,其中引用了N2927,该文档表示:

新措辞不再为“按引用”捕获指定任何重写或闭包成员。被引用捕获的实体的使用会影响原始实体,而实现这一点的机制完全留给实现者。


2

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

如果实体被隐式或显式捕获但未被复制捕获,则其被引用捕获。对于被引用捕获的实体,未指定是否在闭包类型中声明了额外的未命名非静态数据成员。


1
请注意,N3337是最接近C++11的草案,而N4140是最接近C++14的草案,这也是OP标记问题所使用的草案。从我的答案中可以看出,N4140的引用不同,尽管这种差异不会影响本问题。在许多情况下,对于C++11与C++14来说,答案是不同的。虽然N4527是当前可用的最新工作草案,但实际上已基本上成为了C++1z。 - Shafik Yaghmour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接