我的lambda参数是否真的影响我的本地人?
我正在处理一些需要一些数据的C代码,并将其转发给传入的函数:
void foo(int* data, void (*fun)(int*)){
(*fun)(data);
};
以下工作没有警告:
void bar(int* data){};
int main(){
int data=0;
foo(&data,bar);
}
但是,如果我使用lambda代替:
int main(){
int data=0;
foo(&data,[](auto data){});
}
我收到以下警告:
warning: declaration of ‘data’ shadows a previous local [-Wshadow]
foo(&data,[](auto data){});
^
o.cpp:14:7: note: shadowed declaration is here
int data=0;
但我认为一个空的捕获组在查找过程中会排除第一个实例化。
这个警告是否合法?
为什么不是空的捕捉足以避免警告?
lambda封闭范围中的名称也在lambda范围内。
没有捕获的名字可能仍然可以使用,只要它们没有被使用。 必须捕获odr使用的变量。 例:
#include <iostream>
template<typename T> void foo(const int *, T f) { std::cout << f(5) << 'n'; }
int main()
{
const int data=0;
foo(&data,[](int baz){
return data;
});
}
因为读取一个常量表达式不是odr-use,所以这段代码是正确的, data
是指main
的变量。
该程序输出0
,但如果将int baz
更改为int data
,则输出5
。
参考MISRA C ++ 2008:在内部范围内声明的标识符永远不应该与在外部范围内声明的标识符具有相同的名称。
在你的示例中, int data
在外部范围中声明,但通过引用进入lambda的内部范围。 问题在于,在lambda的参数列表中还有一个名为data(inner scope)的参数。 这导致在lambda内从外部范围隐藏数据变量。
顺便一提。 你的函数指针的第一个例子也应该被重写,因为在内部和外部范围内,标识符的命名也有冲突。 在这种情况下,因为内部分数中只有一个数据变量正在使用,所以它不是很有效。 但是,当调用函数的外部作用域的参数列表变量和变量名称相同时,可能会导致程序员混淆,因此应该避免。
链接地址: http://www.djcxy.com/p/91797.html