我有这段带有嵌套 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类?
这是 cppinsight 中的一个错误。
这条线应该是
__lambda_12_32 innerLambda = __lambda_12_32{*__this};
__this
是指向构造外部 lambda 时传递的 this
实例的 MyClass2
指针。
考虑一下 cppinsight 显示的输出实际上并不完全是 gcc 内部所做的事情。它也不是实际的 C++ 代码。例如,输出中使用的所有标识符都保留用于实现,如果您在用户代码中使用它们,那么您的代码将调用未定义的行为。 cppinsight 的输出是由 cppinsight 生成的,它可以让您了解编译器内部的操作,但对此应持保留态度。它没有准确地向您显示编译器内部执行的操作。可能会有错误。