GCC 如何处理这样一个嵌套的 lambda,其中“this”被捕获

问题描述 投票:0回答:1

我有这段带有嵌套 lambda 的代码,并且都捕获“this”:

class MyClass2 {
public:
    int value;

    MyClass2(int initialValue) : value(initialValue) {}

    void executeLambda() {
        auto outerLambda = [this]()  {
            value++;
            auto innerLambda = [*this]() mutable {
                value++;
            };
            innerLambda();
        }; 
        outerLambda();
    }
};

cppinsights.io显示编译器转换如下:

class MyClass2  /* size: 4, align: 4 */
{
  
  public: 
  int value;                      /* offset: 0, size: 4 */
  inline MyClass2(int initialValue)
  : value{initialValue}
  {
  }
  
  inline void executeLambda()
  {
        
    class __lambda_10_28  /* size: 8, align: 8 */
    {
      public: 
      inline void operator()() const
      {
        __this->value++;
                
        class __lambda_12_32  /* size: 4, align: 4 */
        {
          public: 
          inline /*constexpr */ void operator()()
          {
            (&__this)->value++;
          }
          
          private: 
          MyClass2 __this;                /* offset: 0, size: 4 */
          
          public:
          __lambda_12_32(const MyClass2 & _this)
          : __this{_this}
          {}
          
        };
        
        __lambda_12_32 innerLambda = __lambda_12_32{*this}; // LINE_UNDER_CONSIDERATION
        innerLambda.operator()();
      }
      
      private: 
      MyClass2 * __this;              /* offset: 0, size: 8 */
      
      public:
      __lambda_10_28(MyClass2 * _this)
      : __this{_this}
      {}
      
    };
    
    __lambda_10_28 outerLambda = __lambda_10_28{this};
    static_cast<const __lambda_10_28>(outerLambda).operator()();
  }
  
  // inline constexpr MyClass2(const MyClass2 &) noexcept = default;
};

请参阅标记为“LINE_UNDER_CONSIDERATION”的行。

引用类

*this

__lambda_10_28
被传递给以
MyClass2
的对象作为参数的构造函数。这怎么可能是正确的呢?从测试用例的角度来看,构造函数接受
MyClass2
参数是正确的,因为我们仅在
innerLambda
中捕获该参数。

看到这段代码这样的转变,我很好奇GCC怎么知道传递过来的

this
是类
MyClass2
而不是内部创建的lambda类?

c++ gcc lambda c++17 this
1个回答
0
投票

这是 cppinsight 中的一个错误。

这条线应该是

__lambda_12_32 innerLambda = __lambda_12_32{*__this};

__this
是指向构造外部 lambda 时传递的
this
实例的
MyClass2
指针。

考虑一下 cppinsight 显示的输出实际上并不完全是 gcc 内部所做的事情。它也不是实际的 C++ 代码。例如,输出中使用的所有标识符都保留用于实现,如果您在用户代码中使用它们,那么您的代码将调用未定义的行为。 cppinsight 的输出是由 cppinsight 生成的,它可以让您了解编译器内部的操作,但对此应持保留态度。它没有准确地向您显示编译器内部执行的操作。可能会有错误。

© www.soinside.com 2019 - 2024. All rights reserved.