为什么尽管捕获了所有内容'this'但仍然有必要

Why is 'this' necessary despite capturing everything

本文关键字:this 为什么      更新时间:2023-10-16

有人能向我解释为什么即使我捕获了所有内容,我也必须在第二个lambda中显式写入"this->"吗?

完整性的错误消息:

在没有对象的情况下无法调用成员函数"result_ttest::get()"

#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
using result_t = std::function<void()>;
struct test
{
    bool noMore = false;
    result_t get()
    {
        return [this]
        {
            std::vector<int> vec;
            vec.push_back(1);
            vec.push_back(2);
            vec.push_back(3);
            if(not noMore)
            {
                noMore = true;
                std::for_each(vec.begin(), vec.end(),
                    [&](const auto& i)
                    {
                        auto value1 = this->get(); // compiles
                        auto value2 = get(); // error
                    });
            }
        };
    }
};
int main() {
    test t;
    t.get()();
}

Godbolt

这是一个gcc错误。来自[expr.prim.lambda]:

lambda表达式复合语句生成函数调用运算符的function body(8.4),但出于名称查找(3.4)的目的,确定其类型和值(9.3.2)并转换id表达式使用(*this)(9.3.1)将非静态类成员引用到类成员访问表达式中,在lambda表达式的上下文中考虑复合语句[示例:

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

-结束示例]

在这种情况下,get()应该等效于test::get(),并且this被捕获,所以这是良好形成的。clang按原样编译代码。如果将i更改为int而不是const auto&传递,则gcc会编译代码,这与get()的查找方式无关。