可变的仿函数仍然“有效”使用

时间:2013-01-08 11:16:50

标签: c++ c++11 const mutability

看完You don't know const and mutable之后,我对如何正确处理mutable感到困惑。 虽然我认为const的情况非常安全,因为默认情况下会假设物理只读(减去旧的逻辑异常),正确处理mutable会困扰我。 例如,对于新的线程安全条件,以下似乎是错误的:

int main() {
    int n;
    [=]() mutable {n = 10;}();
    return n;
}

我认为,在这种情况下,n必须包含在std::atomic中,或n的副本被另一种方式的并发写入保护!?

1 个答案:

答案 0 :(得分:1)

如果我们明确地写出lambda,你可能会更清楚:

struct mylambda
{
    mylambda(int n) : n(n) {}

    void operator()() /* const <- lambda specified as mutable, operator not const */
    {
        n = 10;
    }

private:
    int n;
};

int main() {
    int n = 0;
    mylambda(n)();
    return n;
}

(旁注:您的示例中实际上有未定义的行为,因为当您的lambda复制n时,它正在从未初始化的变量中读取。我已在此处初始化它以修复该小错误。)

正如您所看到的,您没有可变成员,因此不需要将任何内容更改为线程安全(根据谈话)。只是一个可以通过非const 成员函数更改的常规成员变量;不假定非const成员函数是线程安全的。

我不知道你是否可以将lambda成员标记为mutable;如果可以的话,您可能处于一个需要关注线程安全的位置(与const函数调用操作符相结合)。但我不认为这是可能的。