[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)
**Expression** | **Return type** | **Requirement** |
| --- | --- | --- |
| [ð](#tab:cpp17.equalitycomparable-row-2)
a == b | decltype(a == b) models *boolean-testable* | == is an equivalence relation, that is, it has the following properties:
For all a, a == a[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1)
If a == b, then b == a[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1)
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)
**Expression** | **Return type** | **Requirement** |
| --- | --- | --- |
| [ð](#tab:cpp17.lessthancomparable-row-2)
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)
**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.defaultconstructible-row-2)
T t; | object t is default-initialized |
| [ð](#tab:cpp17.defaultconstructible-row-3)
T u{}; | object u is value-initialized or aggregate-initialized |
| [ð](#tab:cpp17.defaultconstructible-row-4)
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)
**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.moveconstructible-row-2)
T u = rv; | u is equivalent to the value of rv before the construction |
| [ð](#tab:cpp17.moveconstructible-row-3)
T(rv) | T(rv) is equivalent to the value of rv before the construction |
| [ð](#tab:cpp17.moveconstructible-row-4)
rv's state is unspecified
[*Note [1](#tab:cpp17.moveconstructible-row-4-column-1-note-1)*:
rv must still meet the requirements of the library component that is using it[.](#tab:cpp17.moveconstructible-row-4-column-1-sentence-1)
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)
**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.copyconstructible-row-2)
T u = v; | the value of v is unchanged and is equivalent to u |
| [ð](#tab:cpp17.copyconstructible-row-3)
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)
**Expression** | **Return type** | **Return value** | **Post-condition** |
| --- | --- | --- | --- |
| [ð](#tab:cpp17.moveassignable-row-2)
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)
rv's state is unspecified[.](#tab:cpp17.moveassignable-row-3-column-1-sentence-1)
[*Note [2](#tab:cpp17.moveassignable-row-3-column-1-note-2)*:
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)
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)
**Expression** | **Return type** | **Return value** | **Post-condition** |
| --- | --- | --- | --- |
| [ð](#tab:cpp17.copyassignable-row-2)
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)
**Expression** | **Post-condition** |
| --- | --- |
| [ð](#tab:cpp17.destructible-row-2)
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)
[*Note [3](#tab:cpp17.destructible-row-3-column-1-note-3)*:
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*] | |