首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >仅捕获lambda中类的特定成员

仅捕获lambda中类的特定成员
EN

Stack Overflow用户
提问于 2021-07-08 19:19:21
回答 3查看 67关注 0票数 0

我知道我们必须捕获lambda中的*this指针才能访问lambda中的任何成员变量。那么,为什么我不能在lambda中只捕获对象的一个成员呢?

代码语言:javascript
运行
复制
 #include <iostream>

class Foo
{
public:
    Foo () : a(5) {}
    void func ()
    {
        [this->a] () { std::cout << a; } ();
    }

private:
        int a;
};

int main()
{
    Foo f;
    f.func();
}

上面的代码抛出了一个语法错误,

代码语言:javascript
运行
复制
<source>: In member function 'void Foo::func()':
<source>:9:14: error: expected ',' before '->' token
    9 |         [this->a] () { std::cout << a; } ();
      |              ^~
<source>:9:14: error: expected identifier before '->' token

我在godbolt上试过了。组织与gcc 11.1

编辑我知道有一些方法可以捕获对象的单个成员,但我想了解为什么this->member在捕获列表中是无效的。

EN

回答 3

Stack Overflow用户

发布于 2021-07-08 19:27:07

代码语言:javascript
运行
复制
void func ()
{
    [a = this->a] () { std::cout << a; } ();
}

您需要指定变量的名称才能在lambda中访问它。

编辑:

引擎盖下的Lambda:

当执行lambda定义时,对于lambda捕获的每个变量,在lambda中创建该变量的克隆(具有相同的名称)。此时,这些克隆的变量是从同名的外部作用域变量初始化的。

所以[this->a]没有任何意义。编译器需要为捕获的变量分配空间,并且为了使内存可访问,它需要一个名称。

票数 2
EN

Stack Overflow用户

发布于 2021-07-08 19:40:05

,但我的问题是,为什么这是无效的

首先要理解的是lambda是如何在幕后表达的。编译器将其替换为具有重载operator()的匿名类。例如,下面的lambda:

代码语言:javascript
运行
复制
[a](int b){return a + b;}

可以由编译器转换为以下类:

代码语言:javascript
运行
复制
class __lambda_some_random_unique_identifier {
public:
    int operator() (int b) const {
        return a + b;
    }
private:
    int a;
};

现在,如果您允许expression this->a出现在捕获列表中,应该如何将其转换为类成员?可以说,它可以称为a,但如果允许使用表达式this->a,为什么不允许使用this->a.size() (假设astd::vector)?那么它将如何命名呢?

由于这个问题可以通过命名捕获或整体捕获this轻松解决,因此没有充分的理由在其中添加处理复杂的表达式。

票数 2
EN

Stack Overflow用户

发布于 2021-07-08 19:39:56

这只是什么语法有效和什么语法无效的问题。您的问题不是特定于this的。您也不能像这样捕获另一个对象的成员:

代码语言:javascript
运行
复制
struct foo { int x; };

int main() {
    foo obj;
    foo* f = &obj;
    auto l = [f->x](){};
}

虽然这是可以的:

代码语言:javascript
运行
复制
struct foo { int x; };

int main() {
    foo obj;
    foo* f = &obj;
    auto l = [x = f->x](){};
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68300641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档