因为 std::unique_lock 实例并没有拥有与其相关的互斥元,所以通过四处移动(moving)实例,互斥元的所有权可以在实例之间进行转移。在某些情况下这种转移是自动的,比如从函数中返回一个实例,而在其他情况下,你必须通过调用 std::move() 来显式实现。从根本上说,这取决于是否为左值lvalue)——实变量或对实变量的引用——或者是右值rvalue)——某种临时变量。如果源为右值,则所有权转移是自动的,而对于作者,所有权转移必须显式地完成,以避免从变量中意外地转移了所有权。std::unique_lock 就是可移动的moveable)但不可复制copyable)的类型的例子。

一种可能的用法,是允许函数锁定一个互斥元,并将此锁的所有权转移给调用者,于是调用者接下来可以在同一个锁的保护下执行额外的操作。下面的代码片段展示了这样的例子:函数 get_lock()锁定了互斥元,然后再将锁返回给调用者之前准备数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
std::unique_lock<std::mutex> get_lock()
{
extern std::mutex m;
std::unqiue_lock<std::mutex> lk(m);
prepare_data();
return lk;
}

void process_data()
{
std::unique_lock<std::mutext> lk(get_lock());
do_something();
}

因为 lk 是在函数内声明的变量,它可以被直接返回而无需调用 std::move(),编译器负责调用移动构造函数。