3

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.

M.M
  • 138,810
  • 21
  • 208
  • 365
siemanko
  • 1,389
  • 1
  • 13
  • 26
  • That's small letter L. Also irrelevant... – siemanko Mar 12 '15 at 03:38
  • damn it! not the first time I've done this on a question. – RamblingMad Mar 12 '15 at 03:40
  • There's no current way to do this. – T.C. Mar 12 '15 at 04:26
  • Whenever your statement begins with `Type (anything)` , be on guard – M.M Mar 12 '15 at 04:30
  • The main question has been somewhat obscured by the MVP issue ... if your main thrust was to ask "How do I design an object so that it cannot be created as a temporary" then the answer is, as TC says, "You can't"; (and `lock_guard` does not have this property either). – M.M Mar 12 '15 at 04:33

1 Answers1

3

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.