在学校的面向对象编程课上,我们学习了C++中的Lambda表达式,教授明确表示捕获Lambda表达式内变量的到达范围只是最内层的封装范围。
考虑到讲座,我的结论是下面的代码不应该起作用,因为变量b和c是在 lambda 自身范围的最内部封装范围之外定义的。不幸的是,它确实有效。
我曾尝试使用g++和clang编译代码,并且两者都产生了正确的结果?结果。
我的问题是这是否是未定义的行为,或者编译器正在尝试用它做一些事情,或者我们可能被错误地教导?
int main(int argc, char const *argv[])
{
int a = 5;
{
int b = 10;
{
int c = 15;
{
int a = 10;
auto f = [&]()
{
std::cout << a << b << c;
};
f();
std::cout << a;
}
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
另外,在和助理教授一起练习Lambda表达式时,他告诉我们尝试编译以下.cpp文件。
int main(int argc, char *argv[])
{
int x = 7;
std::function<void()> foo;
{
int z = 19;
foo = [x, z]() mutable
{
x = 5;
std::cout << x << " " << z << std::endl;
};
}
foo();
std::cout << x;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译后,他表示这种情况不应该发生,但编译器仍然这样做,并且xlambda 表达式不应该访问该变量。
您的示例代码似乎是有效的,至少对于 C++17 来说是这样(我猜其他的,但 17 是我手头上碰巧有的标准)。关于 lambda 捕获的第 8.1.5.2 节说(强调我的):
\n\n\n最小封闭作用域是块作用域 (6.3.3) 的 lambda 表达式是局部 lambda 表达式;任何\n其他 lambda 表达式在其 lambda 引入器中不应有 capture-default 或 simple-capture。本地 lambda 表达式的到达作用域是一组封闭作用域,直至并包括最内层的封闭函数及其参数。[ 注意:此到达范围包括任何介入的 lambda 表达式。\n\xe2\x80\x94 尾注 ]
\n
所以看起来编译器的行为符合标准的预期
\n| 归档时间: |
|
| 查看次数: |
136 次 |
| 最近记录: |