可以在C++ 11 lambdas中隐式捕获参数包吗?

Fai*_*ali 23 c++ lambda language-lawyer variadic-templates c++11

有谁知道以下隐含的'ts'捕获是否格式正确:

template<class ... Ts> void bar(Ts ... ts) { }

template<class ... Ts> int foo(Ts ... ts) {
    auto L = [=] () {
       bar(ts...);
    };
    L();
    return 0;
}
int g = foo(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)

标准是否清楚地说明了这个不应该很好的形成?

Pot*_*ter 12

14.5.3/6:

不是sizeof...表达式的包扩展的实例化产生列表E1,E2,...,EN,其中N是包扩展参数中的元素的数量.通过实例化模式并用其第i个元素替换每个包扩展参数来生成每个Ei.所有的Ei都成为封闭列表中的元素.

无论您是否允许明确捕获包(您可以使用[ts ...]),扩展的一般规则将导致捕获列表中的每个元素.

  • 或者`[&ts ...]`.此外,这一段讲述了包扩展规则,但没有说明任何有用的参数包被捕获规则......恕我直言,它没有回答这个问题. (2认同)

pep*_*ico 7

我猜它形成得很好,我没有找到一个直接的陈述(对于某些情况,措辞有时缺乏清晰度/说明)但我想可能会推断:

§5.1.2/ 23:

捕获后跟省略号是包扩展(14.5.3).[例如:

      template<class... Args>
      void f(Args... args) {
        auto lm = [&, args...] { return g(args...); };
        lm();
      }
Run Code Online (Sandbox Code Playgroud)

- 结束例子]

  • 捕获后跟省略号,argslambda-capture中暗示是捕获的示例(在本例中为显式),值得注意的事实是它args是参数包标识符.这个简短的段落唯一的工作是描述lambda-capture如何保持包扩展,这表明参数包可以被捕获,即使它的目的不是允许它们被捕获.

§5.1.2/ 12:

如果明确隐含地捕获实体,则捕获实体.[...]

§3/ 3:

一个实体是一个值,对象,参考,功能,枚举,类型,类的成员,模板,模板特,命名空间参数包,或此.

由此我假设参数包是可以显式或隐式捕获的实体,因此,应采用与普通变量相同的捕获规则,但参数包应相应扩展.

我猜你的问题(以及相同的论证)可以同样适用于参考变量(例如,无论引用是否需要存储,都没有说明.§8.3.2/ 4).当你被允许或不在lambda中引用参数包标识符时,你似乎感兴趣.

您可以对外部作用域中的引用变量进行相同的思考,因为您可以访问它们,但甚至不允许访问原始变量的标识符.

它们和参数包一样空灵.