3

当有人像这样在 C++ 中使用 lock_guard 时:

 lock_guard<mutex>(lock);

编译器抱怨:

no matching constructor for initialization of 'std::lock_guard<std::mutex>'

因为正确的用法是:

 lock_guard<mutex> guard(lock);

我想编写一个自定义的 RAII 分配器,当这种情况发生时它也会发生故障 - 我尝试禁用复制构造函数和分配运算符,但到目前为止没有任何效果。

4

1 回答 1

3

我不知道如何实现你的目标,但我想我知道发生了什么事lock_guard<mutex>(lock)

让我们做一些实验。

实验一

int(x);
x = 1;
std::cout << x << std::endl;

实验表明我们已经声明了一个变量x,即使有一对括号。

实验二

class Widget
{
};

class WidgetGuard
{
private:
    Widget& widget;
public:
    WidgetGuard(Widget& w)
        : widget(w)
    {}
};

int main()
{
    Widget w1;

    WidgetGuard wg1(w1);
    WidgetGuard(w1);     //Error!
    WidgetGuard{ w1 };   //Pass!
}

我们定义了一个Widget类和WidgetGuard类来模拟std::mutexstd::lock_guard。当我们尝试WidgetGuard用方括号声明一个临时变量时,它会报错。但是用大括号编译。

这可以用实验 1 来解释。编译器解析WidgetGuard{ w1 }为“创建临时”。但它解析WidgetGuard(w1)为“声明变量w1”!有两个错误来源:重用相同的名称,以及在WidgetGuard.

实验 0

回到std::mutexand std::lock_guard,让我们试试大括号...

std::mutex m;
std::lock_guard<std::mutex> {m};

...它的工作原理。

std::lock_guard可以创建一个临时的。我们只是可以。

于 2015-03-12T04:12:06.503 回答