【发布时间】:2014-06-29 20:30:06
【问题描述】:
ISO C++11 规范的第 5.1.2 p10 节规定:
使用常规规则查找捕获列表中的标识符 用于非限定名称查找 (3.4.1);每个这样的查找都会找到一个 具有在到达中声明的自动存储持续时间的变量 本地 lambda 表达式的范围。一个实体(即一个变量或 如果 this) 出现在 lambda-expression 的捕获列表。
这似乎意味着 lambda 无法捕获文件范围变量。例如,这个程序应该是非法的:
#include <iostream>
int x = 13;
int main()
{
auto l = [](){ return x; };
std::cout << l() << std::endl;
return 0;
}
但是,g++ 4.7.1 产生了我期望的结果:
$ g++ --version
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -std=c++11 lambda.cpp
$ ./a.out
13
但是clang 3.0 崩溃了:
$ clang --version
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: i386-pc-linux-gnu
Thread model: posix
$ clang -std=c++11 lambda.cpp
0 libLLVM-3.0.so.1 0xb70a59e8
1 libLLVM-3.0.so.1 0xb70a5f34
2 0xb775d400 __kernel_sigreturn + 0
3 clang 0x0869f2e9 clang::Sema::DeduceAutoType(clang::TypeSourceInfo*, clang::Expr*, clang::TypeSourceInfo*&) + 73
<snip>
我的程序是否非法?如果是非法的,那么禁止捕获文件范围变量的理由是什么?
【问题讨论】:
-
你没有在你的例子中捕获
x,你只是使用它。毕竟它是一个全球性的(所以你可以使用它,因为它是可见且可访问的)。见this question -
"如果是非法的,禁止捕获文件范围变量的理由是什么?"您只需要捕获自动变量,所以你只能可以捕获自动变量。见stackoverflow.com/a/13827928/420683
-
感谢您的解释!如果您将您的 cmets 合并到一个简短的答案中,我会接受它。
-
clang 崩溃只是因为 lambda 支持在 clang 中直到 3.1 才完成。这在已完成 lambda 支持的版本中运行良好。