mutable关键字解析

c++11引入mutable关键字,它是一个类型修饰符,用来修饰成员变量或者是lambda函数,接下来分布来说明。

修饰成员变量

mutable用来修饰成员变量时,表明该成员变量属于对象内部可变状态,对外不可见。即使在const函数也可改变,不影响外部使用者对此const函数的逻辑语义。比如,基于mutex的线程安全队列。

class Queue{
public:
        void push(int x);
        void pop(int& x);
        bool empty()const{
            std::lock_guard<std::mutex> lk(mutex_);
        }
        
private:
	// 一定要加`mutable`修饰,否则会编译出错。
    mutable std::mutex mutex_;  
};

在上述例子中,empty函数用来判断当前队列是否为空,从语义上看,该函数不会改变队列内部元素个数,加上const修饰,向编译器明确明该语义。由于内部访问了队列,因此需要加锁,加锁这个动作会改变锁状态,这和const的语义有冲突,不增加mutable修饰该锁变量,会编译失败,因此标准引入mutable修饰符,声明该变量是始终可修改的。

修饰lambda函数

当它用来修饰lambda函数时,可在lambda函数体内修改外部的拷贝入参,实例如下:


int x{ 0 };
auto f1 = [x]() mutable{x = 42; printf("2. %d\n", x); };
auto f2 = [x]() {x = 42; printf("2. %d\n", x); };	// 编译出错
auto f3 = [&x]() {x = 42; printf("2. %d\n", x); }; // 编译通过

编译f2会触发编译错误,提示无法在非可变lambda中修改通过复制捕获。对此函数加上mutable,使得该匿名函数支持修改拷贝入参。
注意,通过拷贝传参时,lambda函数内部对该参数的修改不会影响外部值。如果是传引用,可不加mutable

posted @ 2021-01-12 13:19  浩天之家  阅读(1155)  评论(0编辑  收藏  举报