Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a shorthand for std::lock_guard<std::mutex> lock(m)?

Tags:

c++

c++11

Exactly what the question states. In C++, ideally 11, but curious about 14 and later too, is there a shorthand syntax for:

std::mutex someMutex; std::lock_guard<std::mutex> lg(someMutex); 

Ideally something that infers the type of mutex to avoid the refactoring if I ever wanted to change to a std::recursive_mutex.

In other words, a way to do this:

std::mutex someMutex; std::lock_guard lg(someMutex); 

Or

auto lg = make_lock_guard(someMutex); 

For all the type deduction powers of modern C++, it just seems awfully redundant to go typing std::lock_guard<std::mutex> every time I want to make one.

like image 532
Brian McFarland Avatar asked Aug 08 '16 18:08

Brian McFarland


People also ask

What is lock_guard mutex?

The class lock_guard is a mutex wrapper that provides a convenient RAII-style mechanism for owning a mutex for the duration of a scoped block.

What is the difference between lock_guard and unique_lock?

A lock_guard always holds a lock from its construction to its destruction. A unique_lock can be created without immediately locking, can unlock at any point in its existence, and can transfer ownership of the lock from one instance to another.

What is the role of std :: mutex and std :: lock_guard?

std::lock_guard A lock guard is an object that manages a mutex object by keeping it always locked. On construction, the mutex object is locked by the calling thread, and on destruction, the mutex is unlocked.

Should lock_guard be const?

A const instance of std::lock_guard behaves identically to a non- const one. There is no benefit to adding the const , nor to omitting it. The type has no member functions, and is not copyable or movable, so there is essentially no difference at all. I would consider the const as noise and remove it.


1 Answers

For pre-C++17:

template<class Mutex> std::lock_guard<Mutex> make_lock_guard(Mutex& mutex) {     mutex.lock();     return { mutex, std::adopt_lock }; } 

Use as:

std::mutex someMutex; auto&& lg = make_lock_guard(someMutex); 

This takes advantage of the fact that copy-list-initialization doesn't create an additional temporary (even conceptually). The one-parameter constructor is explicit and can't be used for copy-list-initialization, so we lock the mutex first and then use the std::adopt_lock constructor.

The return value is then directly bound to lg, which extends its lifetime to that of the reference, once again creating no temporary (even conceptually) in the process.

like image 64
T.C. Avatar answered Oct 11 '22 05:10

T.C.