强制C++ 11 lambda捕获变量

Gle*_*Low 7 c++ lambda c++11

假设复制变量具有所需的副作用.我想声明一个复制变量但不使用该变量的lambda.这样做的最低要求是什么?

Copiable copyable;

auto lambda1 = [=](){};
auto lambda2 = [copyable](){};
auto lambda3 = [=](){ copyable; }
auto lambda4 = [=](){ volatile copy = copyable; }
Run Code Online (Sandbox Code Playgroud)

lambda1使用隐式捕获,并且由于正文没有提及copyable,我不相信它实际上是复制它.

lambda2使用显式捕获,似乎根据这个,它应该通过副本捕获.是否允许编译器删除副本?有关此问题的另一个讨论,请参阅

lambda3使用隐式捕获,但身体提到copyable.这是否构成了一种使用方式copyable

lambda4使用隐式捕获并强制另一个volatile副本.我确信这实际上会有效,但它的副本数量超过了最低限度.

激励案例:我需要在完成任意数量的lambda调用后运行清理,可能在不同的线程中.我可以通过使用一个std::shared_ptr运行清理的自定义删除器来实现这一点,并以某种方式将其传递给每个lambda.然后,当所有共享ptrs超出范围时,清理将运行.

编辑:lambda3并且lambda4错过了=隐式捕获.

Mik*_*our 4

执行此操作的最低要求是多少?

按值显式捕获,如lambda2.

lambda1使用隐式捕获,并且由于正文没有提到可复制,因此我不相信它实际上会复制它。

这是正确的。仅当变量在 lambda 中使用 odr时,才会隐式捕获它们。

lambda2使用显式捕获,并且根据this看来,它应该通过复制捕获。

这是正确的。任何显式捕获的变量都将被捕获,无论它们是否被使用。这就是您想要确保捕获您的对象所要做的。

编译器是否允许删除副本?有关于此的另一次讨论请参阅此。

不。如果一个变量被捕获,那么它就被捕获了。该链接并没有真正“讨论”这一点;而是 唯一的答案通过标准中的适当措辞证实了情况确实如此。

lambda3使用隐式捕获,但正文提到可复制。这是否构成可复制的ODR 使用

是的。odr-use的定义是

名称显示为潜在计算表达式的变量是odr-used,除非它是满足出现在常量表达式中的要求的对象,并且立即应用左值到右值转换。

并且该异常不适用,因为它不是常量(因此不能出现在常量表达式中)。(但请注意,这是格式不正确的,因为没有默认捕获。)

lambda4使用隐式捕获并强制另一个易失性副本。我确信这实际上会起作用,但它的副本数量超出了最低限度。

的确; 您通过使用该值强制隐式捕获,并强制执行额外的副本。这是不必要的,因为lambda2它就是你想要的。

  • @GlenLow:默认捕获必须位于捕获列表“[=,copyable]”之前。 (3认同)
  • `[=,copyable]` 格式不正确。如果 capture-default 是 `=`,那么 lambda-capture 中的每个标识符必须前面有 `&`。 (2认同)