这是我能想到的重现这个问题的最简单的例子。
template<class T>
struct X
{
static void foo()
{
static int z = 0;
[]{ z = 1; }();
}
};
int main()
{
X<int>::foo();
return 0;
}我已经在Ubuntu4.6和4.7以及MinGW的g++ 4.6上尝试过了,它们都给了我一个链接错误"undefined reference to `z'“。所以现在我开始怀疑这是不是合法的。VC10对此没有问题。
如果X是普通类而不是模板,那么它就会起作用。此外,我不认为它与lambda相关,因为即使我用本地类替换lambda,我也会得到错误。
发布于 2011-12-29 18:23:03
g++接受以下内容,但VC++不接受:
[&z]{ z = 1; }();这里捕获了z,因此g++不会抱怨未定义的引用。但是:
5.1.2/10:
捕获列表中的标识符使用非限定名称查找的常用规则(3.4.1)进行查找;每次这样的查找都应该找到一个在本地lambda表达式的到达范围内声明的具有自动存储持续时间的变量。
z不是自动存储。因此,无法捕获z。因此,g++行为是不正确的,而VC++是正确的。
在您代码中,VC++接受而g++不接受:
[]{ z = 1; }();VC++将z作为静态存储访问,这在lambda body中是允许的。g++显然没有将名称z解析为上面声明的静态变量,因此抛出了未定义的引用,而它不应该这样做。
tl;dr这可能是g++中的错误
编辑: It is indeed a bug,已在4.7中修复。
发布于 2011-12-29 19:08:30
我不明白为什么它只适用于普通类,而不适用于模板。但是,如果通过引用捕获本地变量z,则可以使示例正常工作:
static void foo()
{
static int z = 0;
[&z]{ z = 1; }(); // Note: [&z]
}维基百科有更多信息here。
https://stackoverflow.com/questions/8666492
复制相似问题