有谁知道以下对“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);
标准是否在任何地方明确说明这不应该形成良好的格式?
有谁知道以下对“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);
标准是否在任何地方明确说明这不应该形成良好的格式?
14.5.3/6:
不是
sizeof...
表达式的包扩展的实例化生成列表 E1, E2, ..., EN ,其中 N 是包扩展参数中的元素数。每个 Ei 是通过实例化模式并用其第 i 个元素替换每个包扩展参数来生成的。所有的 Ei 都成为封闭列表中的元素。
无论您是否被允许显式捕获一个包(您可以,使用[ts ...]
),扩展的一般规则将导致捕获列表中的每个元素。
我想它的格式很好,我还没有找到一个直截了当的陈述(在某些情况下,措辞有时缺乏清晰/说明),但我想可能是这样推断的:
§5.1.2/23:
省略号后的捕获是包扩展 (14.5.3)。[ 例子:
template<class... Args>
void f(Args... args) {
auto lm = [&, args...] { return g(args...); };
lm();
}
—结束示例]
args
在lambda-capture中,后跟省略号的捕获是捕获的一个示例(在这种情况下是显式的),值得注意的事实是它args
是一个参数包标识符。这个简短的段落的唯一作用是描述lambda-captures如何保持包扩展,这表明参数包可以被捕获,即使它的目的不是让它们被捕获。§5.1.2/12:
如果实体被显式或隐式捕获,则该实体被捕获。 [...]
§3/3:
实体是值、对象、引用、函数、枚举器、类型、类成员、模板、模板特化、命名空间、参数包或 this。
由此我假设参数包是可以显式或隐式捕获的实体,因此,应适用与普通变量相同的捕获规则,但参数包应相应扩展。
我想您的问题(以及相同的论点)可以同样适用于参考变量,例如(未指定参考是否需要存储。§8.3.2/4)。当您被允许或不允许在 lambda中引用参数包标识符时,您似乎很感兴趣。
您可以对外部范围内的引用变量进行相同的思考,因为您可能可以访问它们,但甚至不能被允许访问原始变量的标识符。
它们与参数包一样空灵。