Lambda捕获和具有相同名称的参数-谁遮蔽了另一个? (c声与gcc) [英] Lambda capture and parameter with same name - who shadows the other? (clang vs gcc)

查看:120
本文介绍了Lambda捕获和具有相同名称的参数-谁遮蔽了另一个? (c声与gcc)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

auto foo = "You're using g++!";
auto compiler_detector = [foo](auto foo) { std::puts(foo); };
compiler_detector("You're using clang++!");

  • clang ++ 3.6.0 及更高版本,打印出您正在使用clang ++!" 并警告捕获 未使用.

    • clang++ 3.6.0 and newer print out "You're using clang++!" and warn about the capture foo being unused.

      g ++ 4.9.0 及更高版本,打印出您正在使用g ++!" 并警告参数 未使用.

      g++ 4.9.0 and newer print out "You're using g++!" and warn about the parameter foo being unused.

      在这里,哪种编译器更准确地遵循C ++标准?

      What compiler is more accurately following the C++ Standard here?

      wandbox示例

      推荐答案

      更新:Core主席在底引号中承诺,代码为

      Update: as promised by the Core chair in the bottom quote, the code is now ill-formed:

      如果简单捕获中的标识符作为 lambda-declarator的参数的 declarator-id 出现, /em>的 parameter-declaration-clause ,该程序格式不正确.

      If an identifier in a simple-capture appears as the declarator-id of a parameter of the lambda-declarator's parameter-declaration-clause, the program is ill-formed.


      前一段时间,有一些关于在lambda中查找名称的问题.它们已通过 N2927 解决:


      There were a few issues concerning name lookup in lambdas a while ago. They were resolved by N2927:

      新措词不再依赖于查找来重新映射捕获的实体的使用. 更清晰 否认以下解释:lambda的 compound-statement 是在两次处理中处理的,或者该 compound-statement 中的任何名称都可能解析为闭包类型的成员.

      The new wording no longer relies on lookup to remap uses of captured entities. It more clearly denies the interpretations that a lambda's compound-statement is processed in two passes or that any names in that compound-statement might resolve to a member of the closure type.

      查找总是在 lambda-expression 的上下文中完成的,永远不要转换"到闭包类型的成员函数体之后.参见 [expr.prim.lambda]/8 :

      Lookup is always done in the context of the lambda-expression, never "after" the transformation to a closure type's member function body. See [expr.prim.lambda]/8:

      lambda表达式复合语句产生函数的功能体([dcl.fct.def])调用运算符,但出于名称查找[…]的目的, compound-statement 是在 lambda-expression 的上下文中考虑的. [示例:

      The lambda-expression's compound-statement yields the function-body ([dcl.fct.def]) of the function call operator, but for purposes of name lookup, […], the compound-statement is considered in the context of the lambda-expression. [ Example:

      struct S1 {
        int x, y;
        int operator()(int);
        void f() {
          [=]()->int {
            return operator()(this->x+y);  // equivalent to: S1::operator()(this->x+(*this).y)
                                           // and this has type S1*
          }; 
        }
      };
      

      示例]

      (该示例还表明,查找并不会以某种方式考虑生成的闭包类型的捕获成员.)

      捕获中未(重新)声明名称foo;它在包含lambda表达式的块中声明.参数foo在嵌套在该外部块中的块中声明(请参见从内部到外部块.因此应该选择该参数,即Clang是正确的.

      The name foo is not (re)declared in the capture; it is declared in the block enclosing the lambda expression. The parameter foo is declared in a block that is nested in that outer block (see [basic.scope.block]/2, which also explicitly mentions lambda parameters). The order of lookup is clearly from inner to outer blocks. Hence the parameter should be selected, that is, Clang is right.

      如果要使捕获成为初始捕获,即foo = ""而不是foo,答案将不清楚.这是因为捕获现在实际上产生了一个声明,该声明的块"没有给出.我就此向核心主席发了信息,谁回答了

      If you were to make the capture an init-capture, i.e. foo = "" instead of foo, the answer would not be clear. This is because the capture now actually induces a declaration whose "block" is not given. I messaged the core chair on this, who replied

      这是第2211期(不久之后,新问题列表将显示在open-std.org网站上,很遗憾,其中仅包含占多数的占位符;这是其中的一个;我正在努力填补这些空白在月底的科纳会议之前). CWG在我们一月份的电话会议上对此进行了讨论,如果捕获名称也是参数名称,则方向是使程序格式错误.

      这篇关于Lambda捕获和具有相同名称的参数-谁遮蔽了另一个? (c声与gcc)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆