[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*] | |