[thread.lock.scoped]

# 32 Concurrency support library [[thread]](./#thread)

## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.scoped)

### 32.6.5 Locks [[thread.lock]](thread.lock#scoped)

#### 32.6.5.3 Class template scoped_lock [thread.lock.scoped]

[ð](#lib:scoped_lock)

namespace std {template<class... MutexTypes>class scoped_lock {public:using mutex_type = *see below*; // Only if sizeof...(MutexTypes) == 1 is trueexplicit scoped_lock(MutexTypes&... m); explicit scoped_lock(adopt_lock_t, MutexTypes&... m); ~scoped_lock();

 scoped_lock(const scoped_lock&) = delete;
 scoped_lock& operator=(const scoped_lock&) = delete; private: tuple<MutexTypes&...> pm; // *exposition only*};}

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8276)

An object of type scoped_lock controls the ownership of lockable objects
within a scope[.](#1.sentence-1)

A scoped_lock object maintains ownership of lockable
objects throughout the scoped_lock object's [lifetime](basic.life#def:lifetime "6.8.4 Lifetime [basic.life]")[.](#1.sentence-2)

The behavior of a program is undefined if the lockable objects referenced bypm do not exist for the entire lifetime of the scoped_lock object[.](#1.sentence-3)

- [(1.1)](#1.1)

  If sizeof...(MutexTypes) is one,
let Mutex denote the sole type constituting the pack MutexTypes[.](#1.1.sentence-1)
  Mutex shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2 Cpp17BasicLockable requirements [thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2 Cpp17BasicLockable requirements"))[.](#1.1.sentence-2)
  The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") mutex_type denotes the same type as Mutex[.](#1.1.sentence-3)

- [(1.2)](#1.2)

  Otherwise, all types in the template parameter pack MutexTypes shall meet the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3 Cpp17Lockable requirements"))
and there is no member mutex_type[.](#1.2.sentence-1)

[ð](#lib:scoped_lock,constructor)

`explicit scoped_lock(MutexTypes&... m);
`

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8303)

*Effects*: Initializes pm with tie(m...)[.](#2.sentence-1)

Then if sizeof...(MutexTypes) is 0, no effects[.](#2.sentence-2)

Otherwise if sizeof...(MutexTypes) is 1, then m.lock()[.](#2.sentence-3)

Otherwise, lock(m...)[.](#2.sentence-4)

[ð](#lib:scoped_lock,constructor_)

`explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8317)

*Preconditions*: The calling thread holds a non-shared lock on each element of m[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8321)

*Effects*: Initializes pm with tie(m...)[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8325)

*Throws*: Nothing[.](#5.sentence-1)

[ð](#lib:scoped_lock,destructor)

`~scoped_lock();
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8336)

*Effects*: For all i in [0, sizeof...(MutexTypes)),get<i>(pm).unlock()[.](#6.sentence-1)
