C ++中的Lambda表达式,OS X的clang与GCC

码头94

c ++的lambda表达式的一个特殊属性是在声明它们的范围内捕获变量。例如,即使'c'不是作为参数发送,而是由[[]'捕获的,我也可以在lambda函数中使用已声明和初始化的变量c:

 #include<iostream>
 int main ()
 {int c=5; [c](int d){std::cout<<c+d<<'\n';}(5);}

因此,预期的输出为10。当至少两个变量具有相同的名称时,就会出现问题:一个被捕获,另一个作为参数发送。

 #include<iostream>
 int main ()
 {int c=5; [c](int c){std::cout<<c<<'\n';}(3);}

我认为2011年的c ++标准说,在名称重合的情况下,捕获的变量优先于lambda表达式的参数。实际上,在Linux上使用GCC 4.8.1编译代码时,得到的输出是预期的输出5如果使用苹果版本的clang编译器(clang-503.0.40,即Mac OS X 10.9.4上Xcode 5.1.1附带的版本)编译相同的代码,则会得到另一个答案3

我试图弄清楚为什么会这样。仅仅是苹果的编译器错误(如果该语言的标准确实说捕获的'c'具有优先权)还是类似的错误?这个问题可以解决吗?

编辑

我的老师向GCC帮助台发送了一封电子邮件,他们回答说这显然是GCC编译器的错误,并将其报告给Bugzilla。因此Clang的行为是正确的!

埃里克·施密特

根据C ++ 11标准,第5.1.2节“ Lambda表达式” [expr.prim.lambda]#7:

所述 λ-表达 化合物语句 产生的 功能体 的函数调用操作的(8.4),但对于名称查找(3.4)的目的,在确定的类型和值 this (9.3.2)和转化 ID-表达 小号使用 (*this) (9.3.1)将非静态类成员引用到类成员访问表达式 中时,在lambda-expression的上下文中考虑 复合语句

另外,从3.3.3“块范围” [basic.scope.local]#2开始:

函数参数名称(包括出现在 lambda-declarator 中的一个)或函数定义(8.4)中的函数局部预定义变量的潜在范围 从其声明点开始。

捕获列表中的名称不是声明,因此不会影响名称查找。捕获列表仅允许您使用局部变量。它不会将其名称引入lambda的范围。例:

int i, j;
int main()
{
    int i = 0;
    [](){ i; }; // Error: Odr-uses non-static local variable without capturing it
    [](){ j; }; // OK
}

因此,由于lambda的参数在内部块范围内,并且由于名称查找是在lambda表达式(而不是生成的类)的上下文中完成的,因此参数名称的确在隐藏函数中隐藏了变量名称。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章