一般类中的mutable
假如一个类的某个成员函数被是const
修饰,那么这个类的隐藏对象参数将会被添加const
限定符(见在C++中this是什么),此时我们将无法修改任何成员,除非通过const_cast
。
加入我们需要在这类函数被调用时修改某个成员变量(可能是用于统计),将会十分困难。
此时可以在需要被修改的成员变量前添加mutable
限定符使其可以被修改,但是这个成员变量不可以是引用类型,不可以拥有顶层的const
限定符,也不可以是静态成员。
lambda中的mutable
在lambda中,被捕获的变量无法修改,如果在lambda的小括号后面添加mutable
,那么这些变量将可以被修改。
不应该假设被捕获变量的类型的限定符,御三家对被捕获的变量的类型有着不同的看法,看下面的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class M { mutable int i = 0; public: bool operator()() const { return std::is_same_v<decltype(i), const int>; } };
class T { int i = 0; public: bool operator()() const { return std::is_same_v<decltype(i), const int>; } };
class C { const int i = 0; public: bool operator()() const { return std::is_same_v<decltype(i), const int>; } };
int main() { auto check_const = [i = 0] () { return std::is_same_v<decltype(i), const int>; }; auto check_mutable = [i = 0] () mutable { return std::is_same_v<decltype(i), const int>; }; cout << check_const(); cout << check_mutable(); cout << M()(); cout << T()(); cout << C()(); }
|
可以有如下的推测。
gcc在被捕获的变量上添加const
,在添加mutable
后移除;
而clang和msvc则在成员函数的隐藏对象形参上添加const
,在添加mutable
后在所有的成员上添加mutable
或移除隐藏对象形参上的const
。