是否有std :: lock_guard <std :: mutex> lock(m)的简写?

时间:2016-08-08 18:27:10

标签: c++ c++11

问题究竟是什么。在C ++中,理想情况下是11,但是对于14和更晚的时候也很好奇,有一个简写语法:

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

理想情况下,如果我想要更改为std::recursive_mutex,则可以推断互斥锁的类型以避免重构。

换句话说,这是一种方法:

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

或者

auto lg = make_lock_guard(someMutex);

对于现代C ++的所有类型演绎功能,每次我想制作一个C std::lock_guard<std::mutex>时,似乎都是多余的。

3 个答案:

答案 0 :(得分:23)

对于预C ++ 17:

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

用作:

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

这利用了复制列表初始化不会创建额外临时(甚至概念上)的事实。单参数构造函数是explicit,不能用于复制列表初始化,因此我们先锁定互斥锁,然后使用std::adopt_lock构造函数。

然后,返回值直接绑定到lg,这会将其生命周期延长到引用的生命周期,再次在过程中不创建临时(甚至概念上)。

答案 1 :(得分:18)

除了@ T.C.的答案所暗示的,这里是C ++ 17的方式:

auto lock = std::lock_guard(someMutex);

您可以阅读此提案中的更改:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html

答案 2 :(得分:6)

目前的答案都建议使用auto关键字来避免输入类型名称。这没有错,但我更喜欢我的代码包含typename,因此非常谨慎地使用auto关键字。我会提倡别名类型:

using MutexLockGuard = std::lock_guard<std::mutex>;