Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use std::lock_guard on a class member mutex

Tags:

c++

c++11

mutex

In the following code the bad method fails to compile, but the good method does not. Why is providing the explicit reference to this making a difference here?

#include <mutex>

class Foo
{
 private:
  std::mutex lock_;

 public:
  Foo() = default;
  ~Foo() = default;

  void bad();
  void good();
};

void Foo::bad()
{
  std::lock_guard<std::mutex>(lock_);
}

void Foo::good()
{
  std::lock_guard<std::mutex>(this->lock_);
}

int main()
{
  return 0;
}

compile error:

test.cpp: In member function ‘void Foo::bad()’:
test.cpp:18:36: error: no matching function for call to ‘std::lock_guard<std::mutex>::lock_guard()’
   std::lock_guard<std::mutex>(lock_);

You can play with the ideone if you want.

like image 609
maxywb Avatar asked Nov 28 '25 00:11

maxywb


1 Answers

This is an instance of the most vexing parse. The parentheses here don't do what you think they do. This:

std::lock_guard<std::mutex>(lock_);

is equivalent to:

std::lock_guard<std::mutex> lock_;

which should make it clear why what you're trying to do won't compile, and why you're getting the compile error you're getting. What you need to do is provide a name for the lock_guard:

std::lock_guard<std::mutex> _(lock_);

The good version works because the this-> qualification prevents the name from being able to be treated as an identifier.


Note: lock_ is a std::mutex and not any kind of lock, which makes it a very confusing name. You should name it something more reflective of what it is. Like mutex_.

like image 64
Barry Avatar answered Nov 30 '25 14:11

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!