gez*_*eza 10 c++ lambda language-lawyer c++14
看这个例子(godbolt):
\nvoid foo(int &par) {\n auto l = [par]() {\n decltype(par) x;\n };\n}\nRun Code Online (Sandbox Code Playgroud)\n这个程序无法编译,因为parindecltype(par)引用的是 in 的参数foo,而不是 lambda 的变量(所以decltype(par)实际上是一个引用类型,需要初始化)。
这是 C++14 标准的相关引用(很抱歉引用旧标准,但我认为它更容易理解)。
\nexpr.prim.lambda/18(重点是我的):
\n“lambda 表达式的复合语句中的每个 id 表达式(通过复制捕获的实体的 odr 使用)都会转换为对闭包类型的相应未命名数据成员的访问。[注:id 表达式这不是 odr-use 指的是原始实体,而不是闭包类型的成员。此外,这样的 id 表达式不会导致实体的隐式捕获。 \xe2\x80\x94 尾注]"
\n标准确保如果 decltype 在非 id 表达式上使用,那么即使它不使用该变量,也会使用捕获的变量(expr.prim.lambda/19):
\n“decltype((x)) 的每次出现(其中 x 可能是一个带括号的 id 表达式,它命名了自动存储持续时间的实体)被视为 x 被转换为对闭包类型的相应数据成员的访问,该数据成员本来可以被如果 x 是指定实体的 ODR 使用,则声明。”
\n因此,根据这些规则(也许该标准还有其他相关规则),lambda 中的变量可能引用捕获的变量,也可能引用封闭函数中的原始变量。
\n我有两个问题:
\n(注意:之前的一个相关问题:引用的按值 lambda 捕获的类型是什么?)
\nThere are various ways to design with those dozen different explicit and implicit captures. Other ways may be similarly confusing or more wasteful. You are transforming a reference into copy with same name so it can happen to be confusing on its own.
Can do by-copy capture with an initialiser:
void foo(int &par) {
auto l = [cap = par]() {
decltype(cap) x; // no confusion about names
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
204 次 |
| 最近记录: |