【问题标题】:Empty lambda capture still shadows outer scope?空的 lambda 捕获仍然会影响外部范围?
【发布时间】:2016-09-26 02:02:32
【问题描述】:

一个空的lambda 捕获列表[] 创建一个没有闭包对象的普通函数。为什么,那么,给出这个例子:

int main(int argc, const char *argv[]) {
  auto _foo = [] (int argc) {
      return argc - 1;
  };
  return _foo(argc);
}

gcc(4.8.5 和 5.4.0)是否警告 lambda 的 argc 会影响外部作用域的 argc 变量?

In lambda function:
warning: declaration of ‘int argc’ shadows a parameter [-Wshadow]
     auto _foo = [] (int argc) {
                             ^
note: shadowed declaration is here
 int main(int argc, const char *argv[]) {
              ^

毕竟,没有可以被遮蔽的外部/周围闭包状态。

【问题讨论】:

    标签: c++11 lambda gcc-warning


    【解决方案1】:

    这是一个警告。 lambda 中的代码可能会使读者混淆正在使用的变量。

    警告不是关于不良行为,只是不可读的代码,事实上它是一个非捕获 lambda 并不能真正使代码更具可读性。

    在内部作用域中隐藏变量的规则与非捕获 lambda 和同名参数的规则一样清晰,并且出于相同的原因存在警告。

    【讨论】:

    • 不确定我是否同意这一点。警告应该是关于潜在问题的,例如有符号与无符号整数比较。如果这里关注可读性,那么它最多需要一个注释。声明具有相同参数名称的函数也不会导致警告。
    • @jens 遮蔽变量不会导致任何实际问题。它在它的作用中得到了很好的定义。除非您注意到阴影,否则代码看起来不再像它所做的那样,这就是出现警告的原因。
    • 我原则上同意阴影。我要说的是,对于一个空的闭包[],没有可能被遮蔽的外部argc。如果闭包将包含外部argc,那么是的,该参数将——可能是意外的——阴影,在这种情况下将需要发出警告。上面的代码是一个纯函数没有闭包上下文,因此没有任何可以被遮蔽的东西。
    • 对不同的事物使用相同的变量名不仅完全是多余的——任何其他名称在 lambda 中都可以——这也是一个愚蠢的习惯。我很高兴有一个警告,但如果您不想看到它,可以将其关闭。 - 更清楚地说,没有什么可以合法地阻止您将所有儿子命名为“亚当”;尽管大多数父母会认为这是一个愚蠢的想法。
    • @Aganju 如果我编写了一些对整数进行操作的函数,那么最常见的是用相同的名称命名所有参数,例如x 或其他一些算术名称。将迭代器命名为it 并将它们这样传递是很常见的。我不在 SSA 中操作,我需要为每个变量发明一个新的变量名。
    猜你喜欢
    • 1970-01-01
    • 2021-05-04
    • 2022-08-04
    • 2017-12-02
    • 2019-10-10
    • 2020-02-13
    • 2017-11-08
    • 1970-01-01
    • 2023-02-23
    相关资源
    最近更新 更多