常量方法中的非常量 lambda 捕获

Non-const lambda capture in const method

本文关键字:常量 lambda 捕获 非常 方法      更新时间:2023-10-16
#include <iostream>
#include <functional>
class Blub {
public:
int i = 0;
std::function<void()> create() const {
return [this]() {
this->i = 100;
};
}
};
int main() {
Blub blub = Blub();
blub.create()();
std::cout << blub.i << std::endl;
return 0;
}

我知道this在 lambda 中被捕获为 const,因为该方法标记为 const。 除了删除方法的恒定性之外,还有没有办法存档我可以修改 lambda 函数内的成员变量?

添加mutable关键字不起作用。

您可以将成员变量i声明为mutable,这样即使对象声明为const,它也可以更改:

class Blub {
public:
mutable int i = 0;
//  ^^^^^^^
std::function<void()> create() const {
return [this]() {
this->i = 100;
};
}
};

住在这里。

您可以执行以下解决方法

class Blub {
public:
int i = 0;
std::function<void()> create() const {
return [my_this=const_cast<Blub*>(this)]() {
my_this->i = 100;
};
}
};

但是在实际上标记为const的函数中更改数据成员是误导性的,所以我不建议以这种方式设计您的类。

现场查看。

:注:值得一提的是,只有当const_cast用于强制转换最初非const的变量时,它才能安全使用。如果变量最初是const的,使用const_cast可能会导致未定义的行为。因此,在以下代码(OP 提供(中:

int main() {
Blub blub = Blub();
blub.create()();
std::cout << blub.i << std::endl;
return 0;
}

使用const_cast是安全的,因为对象最初是非const的。但是,如果我们像下面的代码一样const它:

int main() {
const Blub blub = Blub();
blub.create()();
std::cout << blub.i << std::endl;
return 0;
}

这将导致未定义的行为。