为什么我们可以锁定在 const 对象中定义的互斥量?

why can we lock a mutex defined inside a const object?

工作案例:

template<typename T>
class threadsafe_queue
{
private:
    mutable std::mutex mut;
    std::queue<T> data_queue;

public:
    threadsafe_queue()
    {}

    threadsafe_queue(const threadsafe_queue& other)
    {
        std::lock_guard<std::mutex> lk(other.mut);
        data_queue=other.data_queue;
    }
};

应该失败的案例:注意 std::mutex mut;

上没有 mutable
template<typename T>
class threadsafe_queue
{
private:
    std::mutex mut;
    std::queue<T> data_queue;

public:
    threadsafe_queue()
    {}

    threadsafe_queue(const threadsafe_queue& other)
    {
        std::lock_guard<std::mutex> lk(other.mut);
        data_queue=other.data_queue;
    }
};

以上两种情况我都试过了,编译没有问题。我在内部假设 lock_guard 调用 mutex::lock 函数,它本身不是一个 const 函数。

问题> 为什么我们可以在复制构造函数中锁定来自 const 对象的互斥量?

第一个 示例可以编译,因为互斥锁被限定为mutable。这意味着这个字段可以被修改、改变,而不认为包含的对象被认为已经改变。所以,从某种意义上说,互斥锁的状态不是"part of the queue"。编译器允许 const 方法修改 mutable 成员。

second 示例仅在您实际不尝试实例化 class 并使用该方法时编译。如果你这样做,it fails。模板很神奇...