对于一个类而言,类的成员发生变化,并不意味着这个类在语义上发生变化。比如:
class Website
{
public:
void readPage() const
{
// show this page
++visitorNum; // 改变访问者数量,并不意味着这个网站发生了变化
}
private:
mutable int visitorNum;
};
mutable的出现将const从意义上分成两种层面
- 二进制层面:绝对的常量,任何状态下都不可以修改
- 逻辑层面:从外部观察是常量不可修改,但是内部却可以有非常量的状态
mutable的两种使用场景
- 类的const成员函数
如上述代码,在类Website中,readPage()理论上不应该修改Website,但是实际上在里面却做了++visitorNum的操作。监视访问者数量,从逻辑上并没有修改这个网站。 - lambda表达式
在lambda表达式中,按值捕获的变量不允许被修改,但是使用mutable可以打破这种限制,如下代码所示。
int x = 0;
auto f1 = [x]() mutable { x = 10; }; // right
auto f2 = [x]() { x = 10; }; // error, 按值捕获的外部变量值不能被修改
在lambda表达式中对x的修改,不会影响到外部变量x,即外部的x始终为0。
reference: https://liam.page/2017/05/25/the-mutable-keyword-in-Cxx/