gpt4 book ai didi

c++ - 如果存在非捕获局部变量,为什么不能在 Lambda 中使用非限定成员变量?

转载 作者:可可西里 更新时间:2023-11-01 18:39:25 30 4
gpt4 key购买 nike

简单的例子:

class Foo {
int x;

void bar(int x) {
[this]() -> void {
x = 6;
}();
}
};

这不会在 GCC、Clang、MVC 或 ICC 上编译 (see it live)。如果我将 void bar(int x) 更改为 void bar(int y),或者如果我将 x = 6; 更改为 this->x = 6; 然后就可以正常工作了。

这对我来说没有意义。对 bar 的调用中的局部变量 x 故意不在 lambda 中捕获。唯一有意义的 xFoo 的成员变量。

问题:这是预期的行为吗,如果是,请解释原因?

最佳答案

来自 cppreference :

For the purpose of name lookup, determining the type and value of the this pointer and for accessing non-static class members, the body of the closure type's function call operator is considered in the context of the lambda-expression.

在方法 bar(int x) 的主体中,标记“x”指的是方法的参数,而不是类的成员。该成员已隐藏。[注意这肯定是糟糕的编码习惯,但并不违法]

如果你在当前有 lambda 定义的地方说 x = 6,你会期望局部变量 x(即按值传递的参数到要更改的方法),而不是成员 x,对吗?

因此唯一的问题是局部变量可以被 lambda 隐式捕获吗?我想说编译器非常清楚地解释了它不能。

cppreference 在这个声明中也明确了这一点:

A variable can be used without being captured if it does not have automatic storage duration (i.e. it is not a local variable or it is static or thread local) or if it is not odr-used in the body of the lambda.

注意:odr-used 意味着您必须知道变量的地址,而不仅仅是它的值。为变量赋值算作 ODR 使用它。

考虑这段代码:

class Foo {
int george;

void bar(int washington) {
int martha = washington;
washington = 7;
int jefferson = washington;
int adams = martha;
george = 6;
[this, jefferson]() -> void {
this->george = 15; // legal because `this` is captured
jefferson = adams; // legal because jefferson is explicitly
// captured, and because adams is not
// odr-used, so adams can be captured
// implicitly.
martha = 9; // not legal because it is an odr-use
// of a local variable so martha is not
// implicitly captured.
}();
}

关于c++ - 如果存在非捕获局部变量,为什么不能在 Lambda 中使用非限定成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44089625/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com