[utility.arg.requirements]

# 16 Library introduction [[library]](./#library)

## 16.4 Library-wide requirements [[requirements]](requirements#utility.arg.requirements)

### 16.4.4 Requirements on types and expressions [[utility.requirements]](utility.requirements#utility.arg.requirements)

#### 16.4.4.2 Template argument requirements [utility.arg.requirements]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1780)

The template definitions in the C++ standard library
refer to various named requirements whose details are set out in
Tables [28](#tab:cpp17.equalitycomparable "Table 28: Cpp17EqualityComparable requirements")â[35](#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements")[.](#1.sentence-1)

In these tables,

- [(1.1)](#1.1)

T denotes an object or reference type to be
supplied by a C++ program instantiating a template,

- [(1.2)](#1.2)

a,b, andc denote values of type (possibly const) T,

- [(1.3)](#1.3)

s and t denote modifiable lvalues of type T,

- [(1.4)](#1.4)

u denotes an identifier,

- [(1.5)](#1.5)

rv denotes an rvalue of type T, and

- [(1.6)](#1.6)

v denotes an lvalue of type (possibly const) T or an
rvalue of type const T[.](#1.sentence-2)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1804)

In general, a default constructor is not required[.](#2.sentence-1)

Certain container class
member function signatures specify T() as a default argument[.](#2.sentence-2)

T() shall be a well-defined expression ([[dcl.init]](dcl.init "9.5 Initializers")) if one of those
signatures is called using the [default argument](dcl.fct.default "9.3.4.7 Default arguments [dcl.fct.default]")[.](#2.sentence-3)

Table [28](#tab:cpp17.equalitycomparable) — *Cpp17EqualityComparable* requirements [[tab:cpp17.equalitycomparable]](./tab:cpp17.equalitycomparable)  

| [ð](#tab:cpp17.equalitycomparable-row-1)<br>**Expression** | **Return type** | **Requirement** |
| --- | --- | --- |
| [ð](#tab:cpp17.equalitycomparable-row-2)<br>a == b | decltype(a == b) models *boolean-testable* | == is an equivalence relation, that is, it has the following properties: <br> <br>For all a, a == a[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1)<br>   If a == b, then b == a[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1)<br>   If a == b and b == c, then a == c[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1) |

Table [29](#tab:cpp17.lessthancomparable) — *Cpp17LessThanComparable* requirements [[tab:cpp17.lessthancomparable]](./tab:cpp17.lessthancomparable)  

| [ð](#tab:cpp17.lessthancomparable-row-1)<br>**Expression** | **Return type** | **Requirement** |
| --- | --- | --- |
| [ð](#tab:cpp17.lessthancomparable-row-2)<br>a < b | decltype(a < b) models *boolean-testable* | < is a strict weak ordering relation ([[alg.sorting]](alg.sorting "26.8 Sorting and related operations")) |

Table [30](#tab:cpp17.defaultconstructible) — *Cpp17DefaultConstructible* requirements [[tab:cpp17.defaultconstructible]](./tab:cpp17.defaultconstructible)  

| [ð](#tab:cpp17.defaultconstructible-row-1)<br>**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.defaultconstructible-row-2)<br>T t; | object t is default-initialized |
| [ð](#tab:cpp17.defaultconstructible-row-3)<br>T u{}; | object u is value-initialized or aggregate-initialized |
| [ð](#tab:cpp17.defaultconstructible-row-4)<br>T()   T{} | an object of type T is value-initialized  or aggregate-initialized |

Table [31](#tab:cpp17.moveconstructible) — *Cpp17MoveConstructible* requirements [[tab:cpp17.moveconstructible]](./tab:cpp17.moveconstructible)  

| [ð](#tab:cpp17.moveconstructible-row-1)<br>**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.moveconstructible-row-2)<br>T u = rv; | u is equivalent to the value of rv before the construction |
| [ð](#tab:cpp17.moveconstructible-row-3)<br>T(rv) | T(rv) is equivalent to the value of rv before the construction |
| [ð](#tab:cpp17.moveconstructible-row-4)<br>rv's state is unspecified <br>[*Note [1](#tab:cpp17.moveconstructible-row-4-column-1-note-1)*:<br>rv must still meet the requirements of the library  component that is using it[.](#tab:cpp17.moveconstructible-row-4-column-1-sentence-1)<br>The operations listed in those requirements must  work as specified whether rv has been moved from or not[.](#tab:cpp17.moveconstructible-row-4-column-1-sentence-2) â *end note*] | |

Table [32](#tab:cpp17.copyconstructible) — *Cpp17CopyConstructible* requirements (in addition to [*Cpp17MoveConstructible*](#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]")) [[tab:cpp17.copyconstructible]](./tab:cpp17.copyconstructible)  

| [ð](#tab:cpp17.copyconstructible-row-1)<br>**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.copyconstructible-row-2)<br>T u = v; | the value of v is unchanged and is equivalent to  u |
| [ð](#tab:cpp17.copyconstructible-row-3)<br>T(v) | the value of v is unchanged and is equivalent to T(v) |

Table [33](#tab:cpp17.moveassignable) — *Cpp17MoveAssignable* requirements [[tab:cpp17.moveassignable]](./tab:cpp17.moveassignable)  

| [ð](#tab:cpp17.moveassignable-row-1)<br>**Expression** | **Return type** | **Return value** | **Post-condition** |
| --- | --- | --- | --- |
| [ð](#tab:cpp17.moveassignable-row-2)<br>t = rv | T& | t | If t and rv do not refer to the same object,  t is equivalent to the value of rv before the assignment |
| [ð](#tab:cpp17.moveassignable-row-3)<br>rv's state is unspecified[.](#tab:cpp17.moveassignable-row-3-column-1-sentence-1)<br>[*Note [2](#tab:cpp17.moveassignable-row-3-column-1-note-2)*:<br>rv must still meet the requirements of the library  component that is using it, whether or not t and rv refer to the same object[.](#tab:cpp17.moveassignable-row-3-column-1-sentence-2)<br>The operations listed in those requirements must  work as specified whether rv has been moved from or not[.](#tab:cpp17.moveassignable-row-3-column-1-sentence-3) â *end note*] | | | |

Table [34](#tab:cpp17.copyassignable) — *Cpp17CopyAssignable* requirements (in addition to [*Cpp17MoveAssignable*](#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]")) [[tab:cpp17.copyassignable]](./tab:cpp17.copyassignable)  

| [ð](#tab:cpp17.copyassignable-row-1)<br>**Expression** | **Return type** | **Return value** | **Post-condition** |
| --- | --- | --- | --- |
| [ð](#tab:cpp17.copyassignable-row-2)<br>t = v | T& | t | t is equivalent to v, the value of v is unchanged |

Table [35](#tab:cpp17.destructible) — *Cpp17Destructible* requirements [[tab:cpp17.destructible]](./tab:cpp17.destructible)  

| [ð](#tab:cpp17.destructible-row-1)<br>**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.destructible-row-2)<br>u.~T() | All resources owned by u are reclaimed, no exception is propagated[.](#tab:cpp17.destructible-row-2-column-2-sentence-1) |
| [ð](#tab:cpp17.destructible-row-3)<br>[*Note [3](#tab:cpp17.destructible-row-3-column-1-note-3)*:<br>Array types and non-object types are not [*Cpp17Destructible*](#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#tab:cpp17.destructible-row-3-column-1-sentence-1) â *end note*] | |
