Reputation: 1409
When one uses lock_guard in C++ like this:
lock_guard<mutex>(lock);
The compiler complains:
no matching constructor for initialization of 'std::lock_guard<std::mutex>'
Because the correct use is:
lock_guard<mutex> guard(lock);
I would like to write a custom RAII allocator that also coplains when this happens - I tried disabling copy consturctor and assigment operator, but so far nothing works.
Upvotes: 3
Views: 347
Reputation:
I don't know how to achieve your goal, but I guess I know what's happened to lock_guard<mutex>(lock)
.
Let's do some experiment.
Experiment 1
int(x);
x = 1;
std::cout << x << std::endl;
The experiment reveals we have declared a variable x
, even though there is a pair of brackets.
Experiment 2
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!
}
We define a Widget
class and WidgetGuard
class to emulate std::mutex
and std::lock_guard
. When we try to declare a temporary WidgetGuard
with brackets, it gives an error. But doing so with braces compiles.
This can be explained with Experiment 1. The compiler parses WidgetGuard{ w1 }
to be "create temporary". But it parses WidgetGuard(w1)
to be "declare variable w1
"! There are two sources of error: reusing the same name, and no default constructor in WidgetGuard
.
Experiment 0
Returning to std::mutex
and std::lock_guard
, let's try braces...
std::mutex m;
std::lock_guard<std::mutex> {m};
... and it works.
A temporary of std::lock_guard
can be created. We just can.
Upvotes: 3