Gam*_*ama 4 c++ lambda shadow clang++
我有一个看起来像这样的代码 - 它大大简化了,但这个代码片段编译并展示了相同的行为:
template <typename TFunc>
float FloatSelect( const float in_value, TFunc&& Predicate) {
return std::forward<TFunc>(Predicate)(in_value) ? in_value : 0.0f;
};
void DisplayFloatSelect() {
const float value = FloatSelect(
-1.0f,
[] (const float value) { return value > 0.0f; }
);
std::cout << value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
随着-Wshadow使编译器发出如下警告(如看到这里):
12 : warning: declaration shadows a local variable [-Wshadow]
[] (const float value) { return value > 0.0f; }
^
10 : note: previous declaration is here
const float value = FloatSelect(
^
Run Code Online (Sandbox Code Playgroud)
哪个不是真的有用 - 我理解变量的阴影是什么,但是因为lambda没有捕获任何东西,所以在这里应该没问题.
我错过了什么?
ric*_*ici 10
是的,非捕获变量可以被lambda参数遮蔽.
在OP中lambda的特定情况下,你可能会认为内部声明value不会影响外部声明的范围,因为lambda没有捕获.尽管如此,外部value可以在lambda的主体内部看到,因为lambda的主体仍然在封闭块的范围内:
(C++14§5.1.2/ p.7):lambda-expression的复合语句产生函数调用操作符的函数体(8.4),但为了查找名称(3.4),确定类型和这个(9.3.2)的值和使用(*this)(9.3.1)将非静态类成员转换为类成员访问表达式的idexpressions转换,在lambda表达式的上下文中考虑复合语句.
来自外部作用域的非捕获变量的使用是一个错误,但是如果没有捕获的lambda可能使用在外部作用域中定义的名称,如果它不是odr-use(并且在这样的情况下)例如,不捕获变量.)特别是,可以使用const外部范围的变量:
const int i = 20;
int f = ([](){return i + 3;})();
Run Code Online (Sandbox Code Playgroud)
因此,即使lambda没有捕获,名称的显式参数i肯定会影响外部i.(请参阅http://coliru.stacked-crooked.com/a/006f5f20cca841d5 ;您可能想尝试启用-Wshadow.)
由于-Wshadow准确地用于揭示这种模糊的名称用法,因此在OP中的情况下触发警告似乎并不太令人惊讶.
-Wshadow-Wall既不是-Wextra正确的,也不正是因为它经常会警告你关于你并不真正关心的事情.
| 归档时间: |
|
| 查看次数: |
931 次 |
| 最近记录: |