1 Scope [intro.scope]

This document specifies requirements for implementations of the C++ programming language.
The first such requirement is that they implement the language, so this document also defines C++.
Other requirements and relaxations of the first requirement appear at various places within this document.
C++ is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:2011 Programming languages — C (hereinafter referred to as the C standard).
In addition to the facilities provided by C, C++ provides additional data types, classes, templates, exceptions, namespaces, operator overloading, function name overloading, references, free store management operators, and additional library facilities.

2 Normative references [intro.refs]

The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document.
For dated references, only the edition cited applies.
For undated references, the latest edition of the referenced document (including any amendments) applies.
  • Ecma International, ECMAScript Language Specification, Standard Ecma-262, third edition, 1999.
  • ISO/IEC 2382 (all parts), Information technology — Vocabulary
  • ISO/IEC 9899:2011, Programming languages — C
  • ISO/IEC 9899:2011/Cor.
    1:2012(E), Programming languages — C, Technical Corrigendum 1
  • ISO/IEC 9945:2003, Information Technology — Portable Operating System Interface (POSIX)
  • ISO/IEC 10646-1:1993, Information technology — Universal Multiple-Octet Coded Character Set (UCS) — Part 1: Architecture and Basic Multilingual Plane
  • ISO/IEC 10967-1:2012, Information technology — Language independent arithmetic — Part 1: Integer and floating point arithmetic
  • ISO/IEC/IEEE 60559:2011, Information technology — Microprocessor Systems — Floating-Point arithmetic
  • ISO 80000-2:2009, Quantities and units — Part 2: Mathematical signs and symbols to be used in the natural sciences and technology
The library described in Clause 7 of ISO/IEC 9899:2011 is hereinafter called the C standard library.1
The operating system interface described in ISO/IEC 9945:2003 is hereinafter called POSIX.
The ECMAScript Language Specification described in Standard Ecma-262 is hereinafter called ECMA-262.
The arithmetic specification described in ISO/IEC 10967-1:2012 is hereinafter called LIA-1.
With the qualifications noted in Clauses [language.support] through [thread] and in [diff.library], the C standard library is a subset of the C++ standard library.

3 Terms and definitions [intro.defs]

For the purposes of this document, the terms and definitions given in ISO/IEC 2382-1:1993, the terms, definitions, and symbols given in ISO 80000-2:2009, and the following apply.
ISO and IEC maintain terminological databases for use in standardization at the following addresses:
[definitions] defines additional terms that are used only in Clauses [library] through [thread] and Annex [depr].
Terms that are used only in a small portion of this document are defined where they are used and italicized where they are defined.

3.1 access [defns.access]

⟨execution-time action⟩ to read or modify the value of an object

3.2 argument [defns.argument]

⟨function call expression⟩ expression in the comma-separated list bounded by the parentheses ([expr.call])

3.3 argument [defns.argument.macro]

⟨function-like macro⟩ sequence of preprocessing tokens in the comma-separated list bounded by the parentheses ([cpp.replace])

3.4 argument [defns.argument.throw]

⟨throw expression⟩ the operand of throw ([expr.throw])

3.5 argument [defns.argument.templ]

⟨template instantiation⟩ constant-expression, type-id, or id-expression in the comma-separated list bounded by the angle brackets ([temp.arg])

3.6 block [defns.block]

a thread of execution that blocks is waiting for some condition (other than for the implementation to execute its execution steps) to be satisfied before it can continue execution past the blocking operation

3.7 conditionally-supported [defns.cond.supp]

program construct that an implementation is not required to support
[Note
:
Each implementation documents all conditionally-supported constructs that it does not support.
end note
]

3.8 diagnostic message [defns.diagnostic]

message belonging to an implementation-defined subset of the implementation's output messages

3.9 dynamic type [defns.dynamic.type]

⟨glvalue⟩ type of the most derived object ([intro.object]) to which the glvalue refers
[Example
:
If a pointer ([dcl.ptr]) p whose static type is “pointer to class B” is pointing to an object of class D, derived from B (Clause [class.derived]), the dynamic type of the expression *p is “D.
References ([dcl.ref]) are treated similarly.
end example
]

3.10 dynamic type [defns.dynamic.type.prvalue]

⟨prvalue⟩ static type of the prvalue expression

3.11 ill-formed program [defns.ill.formed]

program that is not well-formed ([defns.well.formed])

3.12 implementation-defined behavior [defns.impl.defined]

behavior, for a well-formed program construct and correct data, that depends on the implementation and that each implementation documents

3.13 implementation limits [defns.impl.limits]

restrictions imposed upon programs by the implementation

3.14 locale-specific behavior [defns.locale.specific]

behavior that depends on local conventions of nationality, culture, and language that each implementation documents

3.15 multibyte character [defns.multibyte]

sequence of one or more bytes representing a member of the extended character set of either the source or the execution environment
[Note
:
The extended character set is a superset of the basic character set ([lex.charset]).
end note
]

3.16 parameter [defns.parameter]

⟨function or catch clause⟩ object or reference declared as part of a function declaration or definition or in the catch clause of an exception handler that acquires a value on entry to the function or handler

3.17 parameter [defns.parameter.macro]

⟨function-like macro⟩ identifier from the comma-separated list bounded by the parentheses immediately following the macro name

3.18 parameter [defns.parameter.templ]

⟨template⟩ member of a template-parameter-list

3.19 signature [defns.signature]

⟨function⟩ name, parameter type list ([dcl.fct]), and enclosing namespace (if any)
[Note
:
Signatures are used as a basis for name mangling and linking.
end note
]

3.20 signature [defns.signature.templ]

⟨function template⟩ name, parameter type list ([dcl.fct]), enclosing namespace (if any), return type, and template parameter list

3.21 signature [defns.signature.spec]

⟨function template specialization⟩ signature of the template of which it is a specialization and its template arguments (whether explicitly specified or deduced)

3.22 signature [defns.signature.member]

⟨class member function⟩ name, parameter type list ([dcl.fct]), class of which the function is a member, cv-qualifiers (if any), and ref-qualifier (if any)

3.23 signature [defns.signature.member.templ]

⟨class member function template⟩ name, parameter type list ([dcl.fct]), class of which the function is a member, cv-qualifiers (if any), ref-qualifier (if any), return type (if any), and template parameter list

3.24 signature [defns.signature.member.spec]

⟨class member function template specialization⟩ signature of the member function template of which it is a specialization and its template arguments (whether explicitly specified or deduced)

3.25 static type [defns.static.type]

type of an expression ([basic.types]) resulting from analysis of the program without considering execution semantics
[Note
:
The static type of an expression depends only on the form of the program in which the expression appears, and does not change while the program is executing.
end note
]

3.26 unblock [defns.unblock]

satisfy a condition that one or more blocked threads of execution are waiting for

3.27 undefined behavior [defns.undefined]

behavior for which this International Standard imposes no requirements
[Note
:
Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data.
Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.
Evaluation of a constant expression never exhibits behavior explicitly specified as undefined ([expr.const]).
end note
]

3.28 unspecified behavior [defns.unspecified]

behavior, for a well-formed program construct and correct data, that depends on the implementation
[Note
:
The implementation is not required to document which behavior occurs.
The range of possible behaviors is usually delineated by this International Standard.
end note
]

3.29 well-formed program [defns.well.formed]

C++ program constructed according to the syntax rules, diagnosable semantic rules, and the one-definition rule ([basic.def.odr]).

4 General principles [intro]

4.1 Implementation compliance [intro.compliance]

The set of diagnosable rules consists of all syntactic and semantic rules in this International Standard except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior”.
Although this International Standard states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs.
Such requirements have the following meaning:
  • If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute2 that program.
  • If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this International Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
  • If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.
[Note
:
During template argument deduction and substitution, certain constructs that in other contexts require a diagnostic are treated differently; see [temp.deduct].
end note
]
For classes and class templates, the library Clauses specify partial definitions.
Private members (Clause [class.access]) are not specified, but each implementation shall supply them to complete the definitions according to the description in the library Clauses.
For functions, function templates, objects, and values, the library Clauses specify declarations.
Implementations shall supply definitions consistent with the descriptions in the library Clauses.
The names defined in the library have namespace scope ([basic.namespace]).
A C++ translation unit ([lex.phases]) obtains access to these names by including the appropriate standard library header ([cpp.include]).
The templates, classes, functions, and objects in the library have external linkage ([basic.link]).
The implementation provides definitions for standard library entities, as necessary, while combining translation units to form a complete C++ program ([lex.phases]).
Two kinds of implementations are defined: a hosted implementation and a freestanding implementation.
For a hosted implementation, this International Standard defines the set of available libraries.
A freestanding implementation is one in which execution may take place without the benefit of an operating system, and has an implementation-defined set of libraries that includes certain language-support libraries ([compliance]).
A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program.
Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard.
Having done so, however, they can compile and execute such programs.
Each implementation shall include documentation that identifies all conditionally-supported constructs that it does not support and defines all locale-specific characteristics.3
“Correct execution” can include undefined behavior, depending on the data being processed; see Clause [intro.defs] and [intro.execution].
This documentation also defines implementation-defined behavior; see [intro.execution].

4.2 Structure of this document [intro.structure]

Clauses [lex] through [cpp] describe the C++ programming language.
That description includes detailed syntactic specifications in a form described in [syntax].
For convenience, Annex [gram] repeats all such syntactic specifications.
Clauses [language.support] through [thread] and Annex [depr] (the library clauses) describe the C++ standard library.
That description includes detailed descriptions of the entities and macros that constitute the library, in a form described in Clause [library].
Annex [implimits] recommends lower bounds on the capacity of conforming implementations.
Annex [diff] summarizes the evolution of C++ since its first published description, and explains in detail the differences between C++ and C.
Certain features of C++ exist solely for compatibility purposes; Annex [depr] describes those features.
Throughout this document, each example is introduced by “[Example: ” and terminated by “end example]”.
Each note is introduced by “[Note: ” and terminated by “end note]”.
Examples and notes may be nested.

4.3 Syntax notation [syntax]

In the syntax notation used in this document, syntactic categories are indicated by italic type, and literal words and characters in constant width type.
Alternatives are listed on separate lines except in a few cases where a long set of alternatives is marked by the phrase “one of”.
If the text of an alternative is too long to fit on a line, the text is continued on subsequent lines indented from the first one.
An optional terminal or non-terminal symbol is indicated by the subscript “”, so
{ expression }
indicates an optional expression enclosed in braces.
Names for syntactic categories have generally been chosen according to the following rules:
  • X-name is a use of an identifier in a context that determines its meaning (e.g., class-name, typedef-name).
  • X-id is an identifier with no context-dependent meaning (e.g., qualified-id).
  • X-seq is one or more X's without intervening delimiters (e.g., declaration-seq is a sequence of declarations).
  • X-list is one or more X's separated by intervening commas (e.g., identifier-list is a sequence of identifiers separated by commas).

4.4 The C++ memory model [intro.memory]

The fundamental storage unit in the C++ memory model is the byte.
A byte is at least large enough to contain any member of the basic execution character set ([lex.charset]) and the eight-bit code units of the Unicode UTF-8 encoding form and is composed of a contiguous sequence of bits,4 the number of which is implementation-defined.
The least significant bit is called the low-order bit; the most significant bit is called the high-order bit.
The memory available to a C++ program consists of one or more sequences of contiguous bytes.
Every byte has a unique address.
[Note
:
The representation of types is described in [basic.types].
end note
]
A memory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having nonzero width.
[Note
:
Various features of the language, such as references and virtual functions, might involve additional memory locations that are not accessible to programs but are managed by the implementation.
end note
]
Two or more threads of execution ([intro.multithread]) can access separate memory locations without interfering with each other.
[Note
:
Thus a bit-field and an adjacent non-bit-field are in separate memory locations, and therefore can be concurrently updated by two threads of execution without interference.
The same applies to two bit-fields, if one is declared inside a nested struct declaration and the other is not, or if the two are separated by a zero-length bit-field declaration, or if they are separated by a non-bit-field declaration.
It is not safe to concurrently update two bit-fields in the same struct if all fields between them are also bit-fields of nonzero width.
end note
]
[Example
:
A structure declared as
struct {
  char a;
  int b:5,
  c:11,
  :0,
  d:8;
  struct {int ee:8;} e;
}
contains four separate memory locations: The field a and bit-fields d and e.ee are each separate memory locations, and can be modified concurrently without interfering with each other.
The bit-fields b and c together constitute the fourth memory location.
The bit-fields b and c cannot be concurrently modified, but b and a, for example, can be.
end example
]
The number of bits in a byte is reported by the macro CHAR_­BIT in the header <climits>.

4.5 The C++ object model [intro.object]

The constructs in a C++ program create, destroy, refer to, access, and manipulate objects.
An object is created by a definition ([basic.def]), by a new-expression, when implicitly changing the active member of a union ([class.union]), or when a temporary object is created ([conv.rval], [class.temporary]).
An object occupies a region of storage in its period of construction ([class.cdtor]), throughout its lifetime ([basic.life]), and in its period of destruction ([class.cdtor]).
[Note
:
A function is not an object, regardless of whether or not it occupies storage in the way that objects do.
end note
]
The properties of an object are determined when the object is created.
An object can have a name (Clause [basic]).
An object has a storage duration ([basic.stc]) which influences its lifetime ([basic.life]).
An object has a type ([basic.types]).
Some objects are polymorphic ([class.virtual]); the implementation generates information associated with each such object that makes it possible to determine that object's type during program execution.
For other objects, the interpretation of the values found therein is determined by the type of the expressions (Clause [expr]) used to access them.
Objects can contain other objects, called subobjects.
A subobject can be a member subobject ([class.mem]), a base class subobject (Clause [class.derived]), or an array element.
An object that is not a subobject of any other object is called a complete object.
If an object is created in storage associated with a member subobject or array element e (which may or may not be within its lifetime), the created object is a subobject of e's containing object if:
  • the lifetime of e's containing object has begun and not ended, and
  • the storage for the new object exactly overlays the storage location associated with e, and
  • the new object is of the same type as e (ignoring cv-qualification).
[Note
:
If the subobject contains a reference member or a const subobject, the name of the original subobject cannot be used to access the new object ([basic.life]).
end note
]
[Example
:
struct X { const int n; };
union U { X x; float f; };
void tong() {
  U u = {{ 1 }};
  u.f = 5.f;                          // OK, creates new subobject of u ([class.union])
  X *p = new (&u.x) X {2};            // OK, creates new subobject of u
  assert(p->n == 2);                  // OK
  assert(*std::launder(&u.x.n) == 2); // OK
  assert(u.x.n == 2);                 // undefined behavior, u.x does not name new subobject
}
end example
]
If a complete object is created ([expr.new]) in storage associated with another object e of type “array of N unsigned char” or of type “array of N std​::​byte” ([cstddef.syn]), that array provides storage for the created object if:
  • the lifetime of e has begun and not ended, and
  • the storage for the new object fits entirely within e, and
  • there is no smaller array object that satisfies these constraints.
[Note
:
If that portion of the array previously provided storage for another object, the lifetime of that object ends because its storage was reused ([basic.life]).
end note
]
[Example
:
template<typename ...T>
struct AlignedUnion {
  alignas(T...) unsigned char data[max(sizeof(T)...)];
};
int f() {
  AlignedUnion<int, char> au;
  int *p = new (au.data) int;     // OK, au.data provides storage
  char *c = new (au.data) char(); // OK, ends lifetime of *p
  char *d = new (au.data + 1) char();
  return *c + *d; // OK
}

struct A { unsigned char a[32]; };
struct B { unsigned char b[16]; };
A a;
B *b = new (a.a + 8) B;      // a.a provides storage for *b
int *p = new (b->b + 4) int; // b->b provides storage for *p
                             // a.a does not provide storage for *p (directly),
                             // but *p is nested within a (see below)
end example
]
An object a is nested within another object b if:
  • a is a subobject of b, or
  • b provides storage for a, or
  • there exists an object c where a is nested within c, and c is nested within b.
For every object x, there is some object called the complete object of x, determined as follows:
  • If x is a complete object, then the complete object of x is itself.
  • Otherwise, the complete object of x is the complete object of the (unique) object that contains x.
If a complete object, a data member ([class.mem]), or an array element is of class type, its type is considered the most derived class, to distinguish it from the class type of any base class subobject; an object of a most derived class type or of a non-class type is called a most derived object.
Unless it is a bit-field ([class.bit]), a most derived object shall have a nonzero size and shall occupy one or more bytes of storage.
Base class subobjects may have zero size.
An object of trivially copyable or standard-layout type ([basic.types]) shall occupy contiguous bytes of storage.
Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies.
Two objects a and b with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they have distinct addresses.5
[Example
:
static const char test1 = 'x';
static const char test2 = 'x';
const bool b = &test1 != &test2;      // always true
end example
]
[Note
:
C++ provides a variety of fundamental types and several ways of composing new types from existing types ([basic.types]).
end note
]
Under the “as-if” rule an implementation is allowed to store two objects at the same machine address or not store an object at all if the program cannot observe the difference ([intro.execution]).

4.6 Program execution [intro.execution]

The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine.
This International Standard places no requirement on the structure of conforming implementations.
In particular, they need not copy or emulate the structure of the abstract machine.
Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.6
Certain aspects and operations of the abstract machine are described in this International Standard as implementation-defined (for example, sizeof(int)).
These constitute the parameters of the abstract machine.
Each implementation shall include documentation describing its characteristics and behavior in these respects.7
Such documentation shall define the instance of the abstract machine that corresponds to that implementation (referred to as the “corresponding instance” below).
Certain other aspects and operations of the abstract machine are described in this International Standard as unspecified (for example, evaluation of expressions in a new-initializer if the allocation function fails to allocate memory ([expr.new])).
Where possible, this International Standard defines a set of allowable behaviors.
These define the nondeterministic aspects of the abstract machine.
An instance of the abstract machine can thus have more than one possible execution for a given program and a given input.
Certain other operations are described in this International Standard as undefined (for example, the effect of attempting to modify a const object).
[Note
:
This International Standard imposes no requirements on the behavior of programs that contain undefined behavior.
end note
]
A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input.
However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).
An instance of each object with automatic storage duration ([basic.stc.auto]) is associated with each entry into its block.
Such an object exists and retains its last-stored value during the execution of the block and while the block is suspended (by a call of a function or receipt of a signal).
The least requirements on a conforming implementation are:
  • Accesses through volatile glvalues are evaluated strictly according to the rules of the abstract machine.
  • At program termination, all data written into files shall be identical to one of the possible results that execution of the program according to the abstract semantics would have produced.
  • The input and output dynamics of interactive devices shall take place in such a fashion that prompting output is actually delivered before a program waits for input.
    What constitutes an interactive device is implementation-defined.
These collectively are referred to as the observable behavior of the program.
[Note
:
More stringent correspondences between abstract and actual semantics may be defined by each implementation.
end note
]
[Note
:
Operators can be regrouped according to the usual mathematical rules only where the operators really are associative or commutative.8
For example, in the following fragment
int a, b;
/* ... */
a = a + 32760 + b + 5;
the expression statement behaves exactly the same as
a = (((a + 32760) + b) + 5);
due to the associativity and precedence of these operators.
Thus, the result of the sum (a + 32760) is next added to b, and that result is then added to 5 which results in the value assigned to a.
On a machine in which overflows produce an exception and in which the range of values representable by an int is [-32768, +32767], the implementation cannot rewrite this expression as
a = ((a + b) + 32765);
since if the values for a and b were, respectively, -32754 and -15, the sum a + b would produce an exception while the original expression would not; nor can the expression be rewritten either as
a = ((a + 32765) + b);
or
a = (a + (b + 32765));
since the values for a and b might have been, respectively, 4 and -8 or -17 and 12.
However on a machine in which overflows do not produce an exception and in which the results of overflows are reversible, the above expression statement can be rewritten by the implementation in any of the above ways because the same result will occur.
end note
]
A constituent expression is defined as follows:
[Example
:
struct A { int x; };
struct B { int y; struct A a; };
B b = { 5, { 1+1 } };
The constituent expressions of the initializer used for the initialization of b are 5 and 1+1.
end example
]
The immediate subexpressions of an expression e are
A subexpression of an expression e is an immediate subexpression of e or a subexpression of an immediate subexpression of e.
[Note
:
Expressions appearing in the compound-statement of a lambda-expression are not subexpressions of the lambda-expression.
end note
]
A full-expression is
If a language construct is defined to produce an implicit call of a function, a use of the language construct is considered to be an expression for the purposes of this definition.
Conversions applied to the result of an expression in order to satisfy the requirements of the language construct in which the expression appears are also considered to be part of the full-expression.
For an initializer, performing the initialization of the entity (including evaluating default member initializers of an aggregate) is also considered part of the full-expression.
[Example
:
struct S {
  S(int i): I(i) { }       // full-expression is initialization of I
  int& v() { return I; }
  ~S() noexcept(false) { }
private:
  int I;
};

S s1(1);                   // full-expression is call of S​::​S(int)
void f() {
  S s2 = 2;                // full-expression is call of S​::​S(int)
  if (S(3).v())            // full-expression includes lvalue-to-rvalue and
                           // int to bool conversions, performed before
                           // temporary is deleted at end of full-expression
  { }
  bool b = noexcept(S());  // exception specification of destructor of S
                           // considered for noexcept
  // full-expression is destruction of s2 at end of block
}
struct B {
      B(S = S(0));
   };
   B b[2] = { B(), B() };  // full-expression is the entire initialization
                           // including the destruction of temporaries
end example
]
[Note
:
The evaluation of a full-expression can include the evaluation of subexpressions that are not lexically part of the full-expression.
For example, subexpressions involved in evaluating default arguments ([dcl.fct.default]) are considered to be created in the expression that calls the function, not the expression that defines the default argument.
end note
]
Reading an object designated by a volatile glvalue ([basic.lval]), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.
Evaluation of an expression (or a subexpression) in general includes both value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and initiation of side effects.
When a call to a library I/O function returns or an access through a volatile glvalue is evaluated the side effect is considered complete, even though some external actions implied by the call (such as the I/O itself) or by the volatile access may not have completed yet.
Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread ([intro.multithread]), which induces a partial order among those evaluations.
Given any two evaluations A and B, if A is sequenced before B (or, equivalently, B is sequenced after A), then the execution of A shall precede the execution of B.
If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced.
[Note
:
The execution of unsequenced evaluations can overlap.
end note
]
Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which.
[Note
:
Indeterminately sequenced evaluations cannot overlap, but either could be executed first.
end note
]
An expression X is said to be sequenced before an expression Y if every value computation and every side effect associated with the expression X is sequenced before every value computation and every side effect associated with the expression Y.
Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.9
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
[Note
:
In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations.
end note
]
The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.
If a side effect on a memory location ([intro.memory]) is unsequenced relative to either another side effect on the same memory location or a value computation using the value of any object in the same memory location, and they are not potentially concurrent ([intro.multithread]), the behavior is undefined.
[Note
:
The next section imposes similar, but more complex restrictions on potentially concurrent computations.
end note
]
[Example
:
void g(int i) {
  i = 7, i++, i++;    // i becomes 9

  i = i++ + 1;        // the value of i is incremented
  i = i++ + i;        // the behavior is undefined
  i = i + 1;          // the value of i is incremented
}
end example
]
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function.
For each function invocation F, for every evaluation A that occurs within F and every evaluation B that does not occur within F but is evaluated on the same thread and as part of the same signal handler (if any), either A is sequenced before B or B is sequenced before A.10
[Note
:
If A and B would not otherwise be sequenced then they are indeterminately sequenced.
end note
]
Several contexts in C++ cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit.
[Example
:
Evaluation of a new-expression invokes one or more allocation and constructor functions; see [expr.new].
For another example, invocation of a conversion function ([class.conv.fct]) can arise in contexts in which no function call syntax appears.
end example
]
The sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.
If a signal handler is executed as a result of a call to the std​::​raise function, then the execution of the handler is sequenced after the invocation of the std​::​raise function and before its return.
[Note
:
When a signal is received for another reason, the execution of the signal handler is usually unsequenced with respect to the rest of the program.
end note
]
This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.
For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.
This documentation also includes conditionally-supported constructs and locale-specific behavior.
Overloaded operators are never assumed to be associative or commutative.
As specified in [class.temporary], after a full-expression is evaluated, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object.
In other words, function executions do not interleave with each other.

4.7 Multi-threaded executions and data races [intro.multithread]

A thread of execution (also known as a thread) is a single flow of control within a program, including the initial invocation of a specific top-level function, and recursively including every function invocation subsequently executed by the thread.
[Note
:
When one thread creates another, the initial call to the top-level function of the new thread is executed by the new thread, not by the creating thread.
end note
]
Every thread in a program can potentially access every object and function in a program.11
Under a hosted implementation, a C++ program can have more than one thread running concurrently.
The execution of each thread proceeds as defined by the remainder of this International Standard.
The execution of the entire program consists of an execution of all of its threads.
[Note
:
Usually the execution can be viewed as an interleaving of all its threads.
However, some kinds of atomic operations, for example, allow executions inconsistent with a simple interleaving, as described below.
end note
]
Under a freestanding implementation, it is implementation-defined whether a program can have more than one thread of execution.
For a signal handler that is not executed as a result of a call to the std​::​raise function, it is unspecified which thread of execution contains the signal handler invocation.
An object with automatic or thread storage duration ([basic.stc]) is associated with one specific thread, and can be accessed by a different thread only indirectly through a pointer or reference ([basic.compound]).

4.7.1 Data races [intro.races]

The value of an object visible to a thread T at a particular point is the initial value of the object, a value assigned to the object by T, or a value assigned to the object by another thread, according to the rules below.
[Note
:
In some cases, there may instead be undefined behavior.
Much of this section is motivated by the desire to support atomic operations with explicit and detailed visibility constraints.
However, it also implicitly supports a simpler view for more restricted programs.
end note
]
Two expression evaluations conflict if one of them modifies a memory location ([intro.memory]) and the other one reads or modifies the same memory location.
The library defines a number of atomic operations (Clause [atomics]) and operations on mutexes (Clause [thread]) that are specially identified as synchronization operations.
These operations play a special role in making assignments in one thread visible to another.
A synchronization operation on one or more memory locations is either a consume operation, an acquire operation, a release operation, or both an acquire and release operation.
A synchronization operation without an associated memory location is a fence and can be either an acquire fence, a release fence, or both an acquire and release fence.
In addition, there are relaxed atomic operations, which are not synchronization operations, and atomic read-modify-write operations, which have special characteristics.
[Note
:
For example, a call that acquires a mutex will perform an acquire operation on the locations comprising the mutex.
Correspondingly, a call that releases the same mutex will perform a release operation on those same locations.
Informally, performing a release operation on A forces prior side effects on other memory locations to become visible to other threads that later perform a consume or an acquire operation on A.
“Relaxed” atomic operations are not synchronization operations even though, like synchronization operations, they cannot contribute to data races.
end note
]
All modifications to a particular atomic object M occur in some particular total order, called the modification order of M.
[Note
:
There is a separate order for each atomic object.
There is no requirement that these can be combined into a single total order for all objects.
In general this will be impossible since different threads may observe modifications to different objects in inconsistent orders.
end note
]
A release sequence headed by a release operation A on an atomic object M is a maximal contiguous sub-sequence of side effects in the modification order of M, where the first operation is A, and every subsequent operation
  • is performed by the same thread that performed A, or
  • is an atomic read-modify-write operation.
Certain library calls synchronize with other library calls performed by another thread.
For example, an atomic store-release synchronizes with a load-acquire that takes its value from the store ([atomics.order]).
[Note
:
Except in the specified cases, reading a later value does not necessarily ensure visibility as described below.
Such a requirement would sometimes interfere with efficient implementation.
end note
]
[Note
:
The specifications of the synchronization operations define when one reads the value written by another.
For atomic objects, the definition is clear.
All operations on a given mutex occur in a single total order.
Each mutex acquisition “reads the value written” by the last mutex release.
end note
]
An evaluation A carries a dependency to an evaluation B if
  • the value of A is used as an operand of B, unless: or
  • A writes a scalar object or bit-field M, B reads the value written by A from M, and A is sequenced before B, or
  • for some evaluation X, A carries a dependency to X, and X carries a dependency to B.
[Note
:
“Carries a dependency to” is a subset of “is sequenced before”, and is similarly strictly intra-thread.
end note
]
An evaluation A is dependency-ordered before an evaluation B if
  • A performs a release operation on an atomic object M, and, in another thread, B performs a consume operation on M and reads a value written by any side effect in the release sequence headed by A, or
  • for some evaluation X, A is dependency-ordered before X and X carries a dependency to B.
[Note
:
The relation “is dependency-ordered before” is analogous to “synchronizes with”, but uses release/consume in place of release/acquire.
end note
]
An evaluation A inter-thread happens before an evaluation B if
  • A synchronizes with B, or
  • A is dependency-ordered before B, or
  • for some evaluation X
    • A synchronizes with X and X is sequenced before B, or
    • A is sequenced before X and X inter-thread happens before B, or
    • A inter-thread happens before X and X inter-thread happens before B.
[Note
:
The “inter-thread happens before” relation describes arbitrary concatenations of “sequenced before”, “synchronizes with” and “dependency-ordered before” relationships, with two exceptions.
The first exception is that a concatenation is not permitted to end with “dependency-ordered before” followed by “sequenced before”.
The reason for this limitation is that a consume operation participating in a “dependency-ordered before” relationship provides ordering only with respect to operations to which this consume operation actually carries a dependency.
The reason that this limitation applies only to the end of such a concatenation is that any subsequent release operation will provide the required ordering for a prior consume operation.
The second exception is that a concatenation is not permitted to consist entirely of “sequenced before”.
The reasons for this limitation are (1) to permit “inter-thread happens before” to be transitively closed and (2) the “happens before” relation, defined below, provides for relationships consisting entirely of “sequenced before”.
end note
]
An evaluation A happens before an evaluation B (or, equivalently, B happens after A) if:
  • A is sequenced before B, or
  • A inter-thread happens before B.
The implementation shall ensure that no program execution demonstrates a cycle in the “happens before” relation.
[Note
:
This cycle would otherwise be possible only through the use of consume operations.
end note
]
An evaluation A strongly happens before an evaluation B if either
  • A is sequenced before B, or
  • A synchronizes with B, or
  • A strongly happens before X and X strongly happens before B.
[Note
:
In the absence of consume operations, the happens before and strongly happens before relations are identical.
Strongly happens before essentially excludes consume operations.
end note
]
A visible side effect A on a scalar object or bit-field M with respect to a value computation B of M satisfies the conditions:
  • A happens before B and
  • there is no other side effect X to M such that A happens before X and X happens before B.
The value of a non-atomic scalar object or bit-field M, as determined by evaluation B, shall be the value stored by the visible side effect A.
[Note
:
If there is ambiguity about which side effect to a non-atomic object or bit-field is visible, then the behavior is either unspecified or undefined.
end note
]
[Note
:
This states that operations on ordinary objects are not visibly reordered.
This is not actually detectable without data races, but it is necessary to ensure that data races, as defined below, and with suitable restrictions on the use of atomics, correspond to data races in a simple interleaved (sequentially consistent) execution.
end note
]
The value of an atomic object M, as determined by evaluation B, shall be the value stored by some side effect A that modifies M, where B does not happen before A.
[Note
:
The set of such side effects is also restricted by the rest of the rules described here, and in particular, by the coherence requirements below.
end note
]
If an operation A that modifies an atomic object M happens before an operation B that modifies M, then A shall be earlier than B in the modification order of M.
[Note
:
This requirement is known as write-write coherence.
end note
]
If a value computation A of an atomic object M happens before a value computation B of M, and A takes its value from a side effect X on M, then the value computed by B shall either be the value stored by X or the value stored by a side effect Y on M, where Y follows X in the modification order of M.
[Note
:
This requirement is known as read-read coherence.
end note
]
If a value computation A of an atomic object M happens before an operation B that modifies M, then A shall take its value from a side effect X on M, where X precedes B in the modification order of M.
[Note
:
This requirement is known as read-write coherence.
end note
]
If a side effect X on an atomic object M happens before a value computation B of M, then the evaluation B shall take its value from X or from a side effect Y that follows X in the modification order of M.
[Note
:
This requirement is known as write-read coherence.
end note
]
[Note
:
The four preceding coherence requirements effectively disallow compiler reordering of atomic operations to a single object, even if both operations are relaxed loads.
This effectively makes the cache coherence guarantee provided by most hardware available to C++ atomic operations.
end note
]
[Note
:
The value observed by a load of an atomic depends on the “happens before” relation, which depends on the values observed by loads of atomics.
The intended reading is that there must exist an association of atomic loads with modifications they observe that, together with suitably chosen modification orders and the “happens before” relation derived as described above, satisfy the resulting constraints as imposed here.
end note
]
Two actions are potentially concurrent if
  • they are performed by different threads, or
  • they are unsequenced, at least one is performed by a signal handler, and they are not both performed by the same signal handler invocation.
The execution of a program contains a data race if it contains two potentially concurrent conflicting actions, at least one of which is not atomic, and neither happens before the other, except for the special case for signal handlers described below.
Any such data race results in undefined behavior.
[Note
:
It can be shown that programs that correctly use mutexes and memory_­order_­seq_­cst operations to prevent all data races and use no other synchronization operations behave as if the operations executed by their constituent threads were simply interleaved, with each value computation of an object being taken from the last side effect on that object in that interleaving.
This is normally referred to as “sequential consistency”.
However, this applies only to data-race-free programs, and data-race-free programs cannot observe most program transformations that do not change single-threaded program semantics.
In fact, most single-threaded program transformations continue to be allowed, since any program that behaves differently as a result must perform an undefined operation.
end note
]
Two accesses to the same object of type volatile std​::​sig_­atomic_­t do not result in a data race if both occur in the same thread, even if one or more occurs in a signal handler.
For each signal handler invocation, evaluations performed by the thread invoking a signal handler can be divided into two groups A and B, such that no evaluations in B happen before evaluations in A, and the evaluations of such volatile std​::​sig_­atomic_­t objects take values as though all evaluations in A happened before the execution of the signal handler and the execution of the signal handler happened before all evaluations in B.
[Note
:
Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this International Standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race.
This includes implementations of data member assignment that overwrite adjacent members in separate memory locations.
Reordering of atomic loads in cases in which the atomics in question may alias is also generally precluded, since this may violate the coherence rules.
end note
]
[Note
:
Transformations that introduce a speculative read of a potentially shared memory location may not preserve the semantics of the C++ program as defined in this International Standard, since they potentially introduce a data race.
However, they are typically valid in the context of an optimizing compiler that targets a specific machine with well-defined semantics for data races.
They would be invalid for a hypothetical machine that is not tolerant of races or provides hardware race detection.
end note
]

4.7.2 Forward progress [intro.progress]

The implementation may assume that any thread will eventually do one of the following:
  • terminate,
  • make a call to a library I/O function,
  • perform an access through a volatile glvalue, or
  • perform a synchronization operation or an atomic operation.
[Note
:
This is intended to allow compiler transformations such as removal of empty loops, even when termination cannot be proven.
end note
]
Executions of atomic functions that are either defined to be lock-free ([atomics.flag]) or indicated as lock-free ([atomics.lockfree]) are lock-free executions.
  • If there is only one thread that is not blocked ([defns.block]) in a standard library function, a lock-free execution in that thread shall complete.
    [Note
    :
    Concurrently executing threads may prevent progress of a lock-free execution.
    For example, this situation can occur with load-locked store-conditional implementations.
    This property is sometimes termed obstruction-free.
    end note
    ]
  • When one or more lock-free executions run concurrently, at least one should complete.
    [Note
    :
    It is difficult for some implementations to provide absolute guarantees to this effect, since repeated and particularly inopportune interference from other threads may prevent forward progress, e.g., by repeatedly stealing a cache line for unrelated purposes between load-locked and store-conditional instructions. Implementations should ensure that such effects cannot indefinitely delay progress under expected operating conditions, and that such anomalies can therefore safely be ignored by programmers. Outside this document, this property is sometimes termed lock-free.
    end note
    ]
During the execution of a thread of execution, each of the following is termed an execution step:
  • termination of the thread of execution,
  • performing an access through a volatile glvalue, or
  • completion of a call to a library I/O function, a synchronization operation, or an atomic operation.
An invocation of a standard library function that blocks ([defns.block]) is considered to continuously execute execution steps while waiting for the condition that it blocks on to be satisfied.
[Example
:
A library I/O function that blocks until the I/O operation is complete can be considered to continuously check whether the operation is complete.
Each such check might consist of one or more execution steps, for example using observable behavior of the abstract machine.
end example
]
[Note
:
Because of this and the preceding requirement regarding what threads of execution have to perform eventually, it follows that no thread of execution can execute forever without an execution step occurring.
end note
]
A thread of execution makes progress when an execution step occurs or a lock-free execution does not complete because there are other concurrent threads that are not blocked in a standard library function (see above).
For a thread of execution providing concurrent forward progress guarantees, the implementation ensures that the thread will eventually make progress for as long as it has not terminated.
[Note
:
This is required regardless of whether or not other threads of executions (if any) have been or are making progress.
To eventually fulfill this requirement means that this will happen in an unspecified but finite amount of time.
end note
]
It is implementation-defined whether the implementation-created thread of execution that executes main ([basic.start.main]) and the threads of execution created by std​::​thread ([thread.thread.class]) provide concurrent forward progress guarantees.
[Note
:
General-purpose implementations are encouraged to provide these guarantees.
end note
]
For a thread of execution providing parallel forward progress guarantees, the implementation is not required to ensure that the thread will eventually make progress if it has not yet executed any execution step; once this thread has executed a step, it provides concurrent forward progress guarantees.
[Note
:
This does not specify a requirement for when to start this thread of execution, which will typically be specified by the entity that creates this thread of execution.
For example, a thread of execution that provides concurrent forward progress guarantees and executes tasks from a set of tasks in an arbitrary order, one after the other, satisfies the requirements of parallel forward progress for these tasks.
end note
]
For a thread of execution providing weakly parallel forward progress guarantees, the implementation does not ensure that the thread will eventually make progress.
[Note
:
Threads of execution providing weakly parallel forward progress guarantees cannot be expected to make progress regardless of whether other threads make progress or not; however, blocking with forward progress guarantee delegation, as defined below, can be used to ensure that such threads of execution make progress eventually.
end note
]
Concurrent forward progress guarantees are stronger than parallel forward progress guarantees, which in turn are stronger than weakly parallel forward progress guarantees.
[Note
:
For example, some kinds of synchronization between threads of execution may only make progress if the respective threads of execution provide parallel forward progress guarantees, but will fail to make progress under weakly parallel guarantees.
end note
]
When a thread of execution P is specified to block with forward progress guarantee delegation on the completion of a set S of threads of execution, then throughout the whole time of P being blocked on S, the implementation shall ensure that the forward progress guarantees provided by at least one thread of execution in S is at least as strong as P's forward progress guarantees.
[Note
:
It is unspecified which thread or threads of execution in S are chosen and for which number of execution steps.
The strengthening is not permanent and not necessarily in place for the rest of the lifetime of the affected thread of execution.
As long as P is blocked, the implementation has to eventually select and potentially strengthen a thread of execution in S.
end note
]
Once a thread of execution in S terminates, it is removed from S.
Once S is empty, P is unblocked.
[Note
:
A thread of execution B thus can temporarily provide an effectively stronger forward progress guarantee for a certain amount of time, due to a second thread of execution A being blocked on it with forward progress guarantee delegation.
In turn, if B then blocks with forward progress guarantee delegation on C, this may also temporarily provide a stronger forward progress guarantee to C.
end note
]
[Note
:
If all threads of execution in S finish executing (e.g., they terminate and do not use blocking synchronization incorrectly), then P's execution of the operation that blocks with forward progress guarantee delegation will not result in P's progress guarantee being effectively weakened.
end note
]
[Note
:
This does not remove any constraints regarding blocking synchronization for threads of execution providing parallel or weakly parallel forward progress guarantees because the implementation is not required to strengthen a particular thread of execution whose too-weak progress guarantee is preventing overall progress.
end note
]
An implementation should ensure that the last value (in modification order) assigned by an atomic or synchronization operation will become visible to all other threads in a finite period of time.

4.8 Acknowledgments [intro.ack]

The C++ programming language as described in this document is based on the language as described in Chapter R (Reference Manual) of Stroustrup: The C++ Programming Language (second edition, Addison-Wesley Publishing Company, ISBN 0-201-53992-6, copyright ©1991 AT&T).
That, in turn, is based on the C programming language as described in Appendix A of Kernighan and Ritchie: The C Programming Language (Prentice-Hall, 1978, ISBN 0-13-110163-3, copyright ©1978 AT&T).
Portions of the library Clauses of this document are based on work by P.
J.
Plauger, which was published as The Draft Standard C++ Library (Prentice-Hall, ISBN 0-13-117003-1, copyright ©1995 P.
J.
Plauger).
POSIX® is a registered trademark of the Institute of Electrical and Electronic Engineers, Inc.
ECMAScript® is a registered trademark of Ecma International.
All rights in these originals are reserved.

5 Lexical conventions [lex]

5.1 Separate translation [lex.separate]

The text of the program is kept in units called source files in this International Standard.
A source file together with all the headers ([headers]) and source files included ([cpp.include]) via the preprocessing directive #include, less any source lines skipped by any of the conditional inclusion ([cpp.cond]) preprocessing directives, is called a translation unit.
[Note
:
A C++ program need not all be translated at the same time.
end note
]
[Note
:
Previously translated translation units and instantiation units can be preserved individually or in libraries.
The separate translation units of a program communicate ([basic.link]) by (for example) calls to functions whose identifiers have external linkage, manipulation of objects whose identifiers have external linkage, or manipulation of data files.
Translation units can be separately translated and then later linked to produce an executable program ([basic.link]).
end note
]

5.2 Phases of translation [lex.phases]

The precedence among the syntax rules of translation is specified by the following phases.12
  1. 1.
    Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set (introducing new-line characters for end-of-line indicators) if necessary.
    The set of physical source file characters accepted is implementation-defined.
    Any source file character not in the basic source character set ([lex.charset]) is replaced by the universal-character-name that designates that character.
    An implementation may use any internal encoding, so long as an actual extended character encountered in the source file, and the same extended character expressed in the source file as a universal-character-name (e.g., using the \uXXXX notation), are handled equivalently except where this replacement is reverted ([lex.pptoken]) in a raw string literal.
  2. 2.
    Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines.
    Only the last backslash on any physical source line shall be eligible for being part of such a splice.
    Except for splices reverted in a raw string literal, if a splice results in a character sequence that matches the syntax of a universal-character-name, the behavior is undefined.
    A source file that is not empty and that does not end in a new-line character, or that ends in a new-line character immediately preceded by a backslash character before any such splicing takes place, shall be processed as if an additional new-line character were appended to the file.
  3. 3.
    The source file is decomposed into preprocessing tokens ([lex.pptoken]) and sequences of white-space characters (including comments).
    A source file shall not end in a partial preprocessing token or in a partial comment.13
    Each comment is replaced by one space character.
    New-line characters are retained.
    Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is unspecified.
    The process of dividing a source file's characters into preprocessing tokens is context-dependent.
    [Example
    :
    see the handling of < within a #include preprocessing directive.
    end example
    ]
  4. 4.
    Preprocessing directives are executed, macro invocations are expanded, and _­Pragma unary operator expressions are executed.
    If a character sequence that matches the syntax of a universal-character-name is produced by token concatenation ([cpp.concat]), the behavior is undefined.
    A #include preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively.
    All preprocessing directives are then deleted.
  5. 5.
    Each source character set member in a character literal or a string literal, as well as each escape sequence and universal-character-name in a character literal or a non-raw string literal, is converted to the corresponding member of the execution character set ([lex.ccon], [lex.string]); if there is no corresponding member, it is converted to an implementation-defined member other than the null (wide) character.14
  6. 6.
    Adjacent string literal tokens are concatenated.
  7. 7.
    White-space characters separating tokens are no longer significant.
    Each preprocessing token is converted into a token ([lex.token]).
    The resulting tokens are syntactically and semantically analyzed and translated as a translation unit.
    [Note
    :
    The process of analyzing and translating the tokens may occasionally result in one token being replaced by a sequence of other tokens ([temp.names]).
    end note
    ]
    [Note
    :
    Source files, translation units and translated translation units need not necessarily be stored as files, nor need there be any one-to-one correspondence between these entities and any external representation.
    The description is conceptual only, and does not specify any particular implementation.
    end note
    ]
  8. 8.
    Translated translation units and instantiation units are combined as follows:
    [Note
    :
    Some or all of these may be supplied from a library.
    end note
    ]
    Each translated translation unit is examined to produce a list of required instantiations.
    [Note
    :
    This may include instantiations which have been explicitly requested ([temp.explicit]).
    end note
    ]
    The definitions of the required templates are located.
    It is implementation-defined whether the source of the translation units containing these definitions is required to be available.
    [Note
    :
    An implementation could encode sufficient information into the translated translation unit so as to ensure the source is not required here.
    end note
    ]
    All the required instantiations are performed to produce instantiation units.
    [Note
    :
    These are similar to translated translation units, but contain no references to uninstantiated templates and no template definitions.
    end note
    ]
    The program is ill-formed if any instantiation fails.
  9. 9.
    All external entity references are resolved.
    Library components are linked to satisfy external references to entities not defined in the current translation.
    All such translator output is collected into a program image which contains information needed for execution in its execution environment.
Implementations must behave as if these separate phases occur, although in practice different phases might be folded together.
A partial preprocessing token would arise from a source file ending in the first portion of a multi-character token that requires a terminating sequence of characters, such as a header-name that is missing the closing " or >.
A partial comment would arise from a source file ending with an unclosed /* comment.
An implementation need not convert all non-corresponding source characters to the same execution character.

5.3 Character sets [lex.charset]

The basic source character set consists of 96 characters: the space character, the control characters representing horizontal tab, vertical tab, form feed, and new-line, plus the following 91 graphical characters:15
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
The universal-character-name construct provides a way to name other characters.
hex-quad:
	hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
universal-character-name:
	\u hex-quad
	\U hex-quad hex-quad
The character designated by the universal-character-name \UNNNNNNNN is that character whose character short name in ISO/IEC 10646 is NNNNNNNN; the character designated by the universal-character-name \uNNNN is that character whose character short name in ISO/IEC 10646 is 0000NNNN.
If the hexadecimal value for a universal-character-name corresponds to a surrogate code point (in the range 0xD800–0xDFFF, inclusive), the program is ill-formed.
Additionally, if the hexadecimal value for a universal-character-name outside the c-char-sequence, s-char-sequence, or r-char-sequence of a character or string literal corresponds to a control character (in either of the ranges 0x00–0x1F or 0x7F–0x9F, both inclusive) or to a character in the basic source character set, the program is ill-formed.16
The basic execution character set and the basic execution wide-character set shall each contain all the members of the basic source character set, plus control characters representing alert, backspace, and carriage return, plus a null character (respectively, null wide character), whose value is 0.
For each basic execution character set, the values of the members shall be non-negative and distinct from one another.
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
The execution character set and the execution wide-character set are implementation-defined supersets of the basic execution character set and the basic execution wide-character set, respectively.
The values of the members of the execution character sets and the sets of additional members are locale-specific.
The glyphs for the members of the basic source character set are intended to identify characters from the subset of ISO/IEC 10646 which corresponds to the ASCII character set.
However, because the mapping from source file characters to the source character set (described in translation phase 1) is specified as implementation-defined, an implementation is required to document how the basic source characters are represented in source files.
A sequence of characters resembling a universal-character-name in an r-char-sequence does not form a universal-character-name.

5.4 Preprocessing tokens [lex.pptoken]

Each preprocessing token that is converted to a token ([lex.token]) shall have the lexical form of a keyword, an identifier, a literal, an operator, or a punctuator.
A preprocessing token is the minimal lexical element of the language in translation phases 3 through 6.
The categories of preprocessing token are: header names, identifiers, preprocessing numbers, character literals (including user-defined character literals), string literals (including user-defined string literals), preprocessing operators and punctuators, and single non-white-space characters that do not lexically match the other preprocessing token categories.
If a ' or a " character matches the last category, the behavior is undefined.
Preprocessing tokens can be separated by white space; this consists of comments ([lex.comment]), or white-space characters (space, horizontal tab, new-line, vertical tab, and form-feed), or both.
As described in Clause [cpp], in certain circumstances during translation phase 4, white space (or the absence thereof) serves as more than preprocessing token separation.
White space can appear within a preprocessing token only as part of a header name or between the quotation characters in a character literal or string literal.
If the input stream has been parsed into preprocessing tokens up to a given character:
  • If the next character begins a sequence of characters that could be the prefix and initial double quote of a raw string literal, such as R", the next preprocessing token shall be a raw string literal.
    Between the initial and final double quote characters of the raw string, any transformations performed in phases 1 and 2 (universal-character-names and line splicing) are reverted; this reversion shall apply before any d-char, r-char, or delimiting parenthesis is identified.
    The raw string literal is defined as the shortest sequence of characters that matches the raw-string pattern
  • Otherwise, if the next three characters are <​::​ and the subsequent character is neither : nor >, the < is treated as a preprocessing token by itself and not as the first character of the alternative token <:.
  • Otherwise, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail, except that a header-name is only formed within a #include directive ([cpp.include]).
[Example
:
#define R "x"
const char* s = R"y";           // ill-formed raw string, not "x" "y"
end example
]
[Example
:
The program fragment 0xe+foo is parsed as a preprocessing number token (one that is not a valid floating or integer literal token), even though a parse as three preprocessing tokens 0xe, +, and foo might produce a valid expression (for example, if foo were a macro defined as 1).
Similarly, the program fragment 1E1 is parsed as a preprocessing number (one that is a valid floating literal token), whether or not E is a macro name.
end example
]
[Example
:
The program fragment x+++++y is parsed as x ++ ++ + y, which, if x and y have integral types, violates a constraint on increment operators, even though the parse x ++ + ++ y might yield a correct expression.
end example
]

5.5 Alternative tokens [lex.digraph]

Alternative token representations are provided for some operators and punctuators.17
In all respects of the language, each alternative token behaves the same, respectively, as its primary token, except for its spelling.18
The set of alternative tokens is defined in Table 1.
Table 1 — Alternative tokens
Alternative
Primary
Alternative
Primary
Alternative
Primary
<%
{
and
&&
and_­eq
&=
%>
}
bitor
|
or_­eq
|=
<:
[
or
||
xor_­eq
^=
:>
]
xor
^
not
!
%:
#
compl
~
not_­eq
!=
%:%:
##
bitand
&
These include “digraphs” and additional reserved words.
The term “digraph” (token consisting of two characters) is not perfectly descriptive, since one of the alternative preprocessing-tokens is %:%: and of course several primary tokens contain two characters.
Nonetheless, those alternative tokens that aren't lexical keywords are colloquially known as “digraphs”.
Thus the “stringized” values ([cpp.stringize]) of [ and <: will be different, maintaining the source spelling, but the tokens can otherwise be freely interchanged.

5.6 Tokens [lex.token]

token:
	identifier
	keyword
	literal
	operator
	punctuator
There are five kinds of tokens: identifiers, keywords, literals,19 operators, and other separators.
Blanks, horizontal and vertical tabs, newlines, formfeeds, and comments (collectively, “white space”), as described below, are ignored except as they serve to separate tokens.
[Note
:
Some white space is required to separate otherwise adjacent identifiers, keywords, numeric literals, and alternative tokens containing alphabetic characters.
end note
]
Literals include strings and character and numeric literals.

5.7 Comments [lex.comment]

The characters /* start a comment, which terminates with the characters */.
These comments do not nest.
The characters // start a comment, which terminates immediately before the next new-line character.
If there is a form-feed or a vertical-tab character in such a comment, only white-space characters shall appear between it and the new-line that terminates the comment; no diagnostic is required.
[Note
:
The comment characters //, /*, and */ have no special meaning within a // comment and are treated just like other characters.
Similarly, the comment characters // and /* have no special meaning within a /* comment.
end note
]

5.8 Header names [lex.header]

header-name:
	< h-char-sequence >
	" q-char-sequence "
h-char-sequence:
	h-char
	h-char-sequence h-char
h-char:
	any member of the source character set except new-line and >
q-char-sequence:
	q-char
	q-char-sequence q-char
q-char:
	any member of the source character set except new-line and "
[Note
:
Header name preprocessing tokens only appear within a #include preprocessing directive (see [lex.pptoken]).
end note
]
The sequences in both forms of header-names are mapped in an implementation-defined manner to headers or to external source file names as specified in [cpp.include].
The appearance of either of the characters ' or \ or of either of the character sequences /* or // in a q-char-sequence or an h-char-sequence is conditionally-supported with implementation-defined semantics, as is the appearance of the character " in an h-char-sequence.20
Thus, a sequence of characters that resembles an escape sequence might result in an error, be interpreted as the character corresponding to the escape sequence, or have a completely different meaning, depending on the implementation.

5.9 Preprocessing numbers [lex.ppnumber]

Preprocessing number tokens lexically include all integer literal tokens ([lex.icon]) and all floating literal tokens ([lex.fcon]).
A preprocessing number does not have a type or a value; it acquires both after a successful conversion to an integer literal token or a floating literal token.

5.10 Identifiers [lex.name]

identifier:
	identifier-nondigit
	identifier identifier-nondigit
	identifier digit
identifier-nondigit:
	nondigit
	universal-character-name
nondigit: one of
	a b c d e f g h i j k l m
	n o p q r s t u v w x y z
	A B C D E F G H I J K L M
	N O P Q R S T U V W X Y Z _
digit: one of
	0 1 2 3 4 5 6 7 8 9
An identifier is an arbitrarily long sequence of letters and digits.
Each universal-character-name in an identifier shall designate a character whose encoding in ISO 10646 falls into one of the ranges specified in Table 2.
The initial element shall not be a universal-character-name designating a character whose encoding falls into one of the ranges specified in Table 3.
Upper- and lower-case letters are different.
All characters are significant.21
Table 2 — Ranges of characters allowed
00A8
00AA
00AD
00AF
00B2-00B5
00B7-00BA
00BC-00BE
00C0-00D6
00D8-00F6
00F8-00FF
0100-167F
1681-180D
180F-1FFF
200B-200D
202A-202E
203F-2040
2054
2060-206F
2070-218F
2460-24FF
2776-2793
2C00-2DFF
2E80-2FFF
3004-3007
3021-302F
3031-D7FF
F900-FD3D
FD40-FDCF
FDF0-FE44
FE47-FFFD
10000-1FFFD
20000-2FFFD
30000-3FFFD
40000-4FFFD
50000-5FFFD
60000-6FFFD
70000-7FFFD
80000-8FFFD
90000-9FFFD
A0000-AFFFD
B0000-BFFFD
C0000-CFFFD
D0000-DFFFD
E0000-EFFFD
Table 3 — Ranges of characters disallowed initially (combining characters)
0300-036F
1DC0-1DFF
20D0-20FF
FE20-FE2F
The identifiers in Table 4 have a special meaning when appearing in a certain context.
When referred to in the grammar, these identifiers are used explicitly rather than using the identifier grammar production.
Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier.
Table 4 — Identifiers with special meaning
override
final
In addition, some identifiers are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required.
  • Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
  • Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
On systems in which linkers cannot accept extended characters, an encoding of the universal-character-name may be used in forming valid external identifiers.
For example, some otherwise unused character or sequence of characters may be used to encode the \u in a universal-character-name.
Extended characters may produce a long external identifier, but C++ does not place a translation limit on significant characters for external identifiers.
In C++, upper- and lower-case letters are considered different for all identifiers, including external identifiers.

5.11 Keywords [lex.key]

The identifiers shown in Table 5 are reserved for use as keywords (that is, they are unconditionally treated as keywords in phase 7) except in an attribute-token:
Table 5 — Keywords
alignas
continue
friend
register
true
alignof
decltype
goto
reinterpret_­cast
try
asm
default
if
return
typedef
auto
delete
inline
short
typeid
bool
do
int
signed
typename
break
double
long
sizeof
union
case
dynamic_­cast
mutable
static
unsigned
catch
else
namespace
static_­assert
using
char
enum
new
static_­cast
virtual
char16_­t
explicit
noexcept
struct
void
char32_­t
export
nullptr
switch
volatile
class
extern
operator
template
wchar_­t
const
false
private
this
while
constexpr
float
protected
thread_­local
const_­cast
for
public
throw
[Note
:
The export and register keywords are unused but are reserved for future use.
end note
]
Furthermore, the alternative representations shown in Table 6 for certain operators and punctuators ([lex.digraph]) are reserved and shall not be used otherwise:
Table 6 — Alternative representations
and
and_­eq
bitand
bitor
compl
not
not_­eq
or
or_­eq
xor
xor_­eq

5.12 Operators and punctuators [lex.operators]

The lexical representation of C++ programs includes a number of preprocessing tokens which are used in the syntax of the preprocessor or are converted into tokens for operators and punctuators:
preprocessing-op-or-punc: one of
	{ 	} 	[ 	] 	# 	## 	( 	)
	<: 	:> 	<% 	%> 	%: 	%:%: 	; 	: 	...
	new 	delete 	? 	:: 	. 	.*
	+ 	- 	* 	/ 	% 	^	& 	| 	~
	! 	= 	< 	> 	+= 	-= 	*= 	/= 	%=
	^= 	&= 	|= 	<< 	>> 	>>= 	<<= 	== 	!=
	<= 	>= 	&& 	|| 	++ 	-- 	, 	->* 	->
	and 	and_eq 	bitand 	bitor 	compl 	not 	not_eq
	or 	or_eq 	xor 	xor_eq
Each preprocessing-op-or-punc is converted to a single token in translation phase 7 ([lex.phases]).

5.13 Literals [lex.literal]

5.13.1 Kinds of literals [lex.literal.kinds]

The term “literal” generally designates, in this International Standard, those tokens that are called “constants” in ISO C.

5.13.2 Integer literals [lex.icon]

An integer literal is a sequence of digits that has no period or exponent part, with optional separating single quotes that are ignored when determining its value.
An integer literal may have a prefix that specifies its base and a suffix that specifies its type.
The lexically first digit of the sequence of digits is the most significant.
A binary integer literal (base two) begins with 0b or 0B and consists of a sequence of binary digits.
An octal integer literal (base eight) begins with the digit 0 and consists of a sequence of octal digits.23
A decimal integer literal (base ten) begins with a digit other than 0 and consists of a sequence of decimal digits.
A hexadecimal integer literal (base sixteen) begins with 0x or 0X and consists of a sequence of hexadecimal digits, which include the decimal digits and the letters a through f and A through F with decimal values ten through fifteen.
[Example
:
The number twelve can be written 12, 014, 0XC, or 0b1100.
The integer literals 1048576, 1'048'576, 0X100000, 0x10'0000, and 0'004'000'000 all have the same value.
end example
]
The type of an integer literal is the first of the corresponding list in Table 7 in which its value can be represented.
Table 7 — Types of integer literals
Suffix
Decimal literal
Binary, octal, or hexadecimal literal
none
int
int
long int
unsigned int
long long int
long int
unsigned long int
long long int
unsigned long long int
u or U
unsigned int
unsigned int
unsigned long int
unsigned long int
unsigned long long int
unsigned long long int
l or L
long int
long int
long long int
unsigned long int
long long int
unsigned long long int
Both u or U
unsigned long int
unsigned long int
and l or L
unsigned long long int
unsigned long long int
ll or LL
long long int
long long int
unsigned long long int
Both u or U
unsigned long long int
unsigned long long int
and ll or LL
If an integer literal cannot be represented by any type in its list and an extended integer type ([basic.fundamental]) can represent its value, it may have that extended integer type.
If all of the types in the list for the integer literal are signed, the extended integer type shall be signed.
If all of the types in the list for the integer literal are unsigned, the extended integer type shall be unsigned.
If the list contains both signed and unsigned types, the extended integer type may be signed or unsigned.
A program is ill-formed if one of its translation units contains an integer literal that cannot be represented by any of the allowed types.
The digits 8 and 9 are not octal digits.

5.13.3 Character literals [lex.ccon]

A character literal is one or more characters enclosed in single quotes, as in 'x', optionally preceded by u8, u, U, or L, as in u8'w', u'x', U'y', or L'z', respectively.
A character literal that does not begin with u8, u, U, or L is an ordinary character literal.
An ordinary character literal that contains a single c-char representable in the execution character set has type char, with value equal to the numerical value of the encoding of the c-char in the execution character set.
An ordinary character literal that contains more than one c-char is a multicharacter literal.
A multicharacter literal, or an ordinary character literal containing a single c-char not representable in the execution character set, is conditionally-supported, has type int, and has an implementation-defined value.
A character literal that begins with u8, such as u8'w', is a character literal of type char, known as a UTF-8 character literal.
The value of a UTF-8 character literal is equal to its ISO 10646 code point value, provided that the code point value is representable with a single UTF-8 code unit (that is, provided it is in the C0 Controls and Basic Latin Unicode block).
If the value is not representable with a single UTF-8 code unit, the program is ill-formed.
A UTF-8 character literal containing multiple c-chars is ill-formed.
A character literal that begins with the letter u, such as u'x', is a character literal of type char16_­t.
The value of a char16_­t character literal containing a single c-char is equal to its ISO 10646 code point value, provided that the code point is representable with a single 16-bit code unit.
(That is, provided it is a basic multi-lingual plane code point.)
If the value is not representable within 16 bits, the program is ill-formed.
A char16_­t character literal containing multiple c-chars is ill-formed.
A character literal that begins with the letter U, such as U'y', is a character literal of type char32_­t.
The value of a char32_­t character literal containing a single c-char is equal to its ISO 10646 code point value.
A char32_­t character literal containing multiple c-chars is ill-formed.
A character literal that begins with the letter L, such as L'z', is a wide-character literal.
A wide-character literal has type wchar_­t.24
The value of a wide-character literal containing a single c-char has value equal to the numerical value of the encoding of the c-char in the execution wide-character set, unless the c-char has no representation in the execution wide-character set, in which case the value is implementation-defined.
[Note
:
The type wchar_­t is able to represent all members of the execution wide-character set (see [basic.fundamental]).
end note
]
The value of a wide-character literal containing multiple c-chars is implementation-defined.
Certain non-graphic characters, the single quote ', the double quote ", the question mark ?,25 and the backslash \, can be represented according to Table 8.
The double quote " and the question mark ?, can be represented as themselves or by the escape sequences \" and \? respectively, but the single quote ' and the backslash \ shall be represented by the escape sequences \' and \\ respectively.
Escape sequences in which the character following the backslash is not listed in Table 8 are conditionally-supported, with implementation-defined semantics.
An escape sequence specifies a single character.
Table 8 — Escape sequences
new-line
NL(LF)
\n
horizontal tab
HT
\t
vertical tab
VT
\v
backspace
BS
\b
carriage return
CR
\r
form feed
FF
\f
alert
BEL
\a
backslash
\
\\
question mark
?
\?
single quote
'
\'
double quote
"
\"
octal number
ooo
\ooo
hex number
hhh
\xhhh
The escape \ooo consists of the backslash followed by one, two, or three octal digits that are taken to specify the value of the desired character.
The escape \xhhh consists of the backslash followed by x followed by one or more hexadecimal digits that are taken to specify the value of the desired character.
There is no limit to the number of digits in a hexadecimal sequence.
A sequence of octal or hexadecimal digits is terminated by the first character that is not an octal digit or a hexadecimal digit, respectively.
The value of a character literal is implementation-defined if it falls outside of the implementation-defined range defined for char (for character literals with no prefix) or wchar_­t (for character literals prefixed by L).
[Note
:
If the value of a character literal prefixed by u, u8, or U is outside the range defined for its type, the program is ill-formed.
end note
]
A universal-character-name is translated to the encoding, in the appropriate execution character set, of the character named.
If there is no such encoding, the universal-character-name is translated to an implementation-defined encoding.
[Note
:
In translation phase 1, a universal-character-name is introduced whenever an actual extended character is encountered in the source text.
Therefore, all extended characters are described in terms of universal-character-names.
However, the actual compiler implementation may use its own native character set, so long as the same results are obtained.
end note
]
They are intended for character sets where a character does not fit into a single byte.
Using an escape sequence for a question mark is supported for compatibility with ISO C++ 2014 and ISO C.

5.13.4 Floating literals [lex.fcon]

A floating literal consists of an optional prefix specifying a base, an integer part, a radix point, a fraction part, an e, E, p or P, an optionally signed integer exponent, and an optional type suffix.
The integer and fraction parts both consist of a sequence of decimal (base ten) digits if there is no prefix, or hexadecimal (base sixteen) digits if the prefix is 0x or 0X.
The floating literal is a decimal floating literal in the former case and a hexadecimal floating literal in the latter case.
Optional separating single quotes in a digit-sequence or hexadecimal-digit-sequence are ignored when determining its value.
[Example
:
The floating literals 1.602'176'565e-19 and 1.602176565e-19 have the same value.
end example
]
Either the integer part or the fraction part (not both) can be omitted.
Either the radix point or the letter e or E and the exponent (not both) can be omitted from a decimal floating literal.
The radix point (but not the exponent) can be omitted from a hexadecimal floating literal.
The integer part, the optional radix point, and the optional fraction part, form the significand of the floating literal.
In a decimal floating literal, the exponent, if present, indicates the power of 10 by which the significand is to be scaled.
In a hexadecimal floating literal, the exponent indicates the power of 2 by which the significand is to be scaled.
[Example
:
The floating literals 49.625 and 0xC.68p+2 have the same value.
end example
]
If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner.
The type of a floating literal is double unless explicitly specified by a suffix.
The suffixes f and F specify float, the suffixes l and L specify long double.
If the scaled value is not in the range of representable values for its type, the program is ill-formed.

5.13.5 String literals [lex.string]

string-literal:
	encoding-prefix " s-char-sequence "
	encoding-prefix R raw-string
s-char-sequence:
	s-char
	s-char-sequence s-char
s-char:
	any member of the source character set except
		the double-quote ", backslash \, or new-line character
	escape-sequence
	universal-character-name
raw-string:
	" d-char-sequence ( r-char-sequence ) d-char-sequence "
r-char-sequence:
	r-char
	r-char-sequence r-char
r-char:
	any member of the source character set, except
		a right parenthesis ) followed by the initial d-char-sequence
		(which may be empty) followed by a double quote ".
d-char-sequence:
	d-char
	d-char-sequence d-char
d-char:
	any member of the basic source character set except:
		space, the left parenthesis (, the right parenthesis ), the backslash \,
		and the control characters representing horizontal tab,
		vertical tab, form feed, and newline.
A string-literal is a sequence of characters (as defined in [lex.ccon]) surrounded by double quotes, optionally prefixed by R, u8, u8R, u, uR, U, UR, L, or LR, as in "...", R"(...)", u8"...", u8R"**(...)**", u"...", uR"*~(...)*~", U"...", UR"zzz(...)zzz", L"...", or LR"(...)", respectively.
A string-literal that has an R in the prefix is a raw string literal.
The d-char-sequence serves as a delimiter.
The terminating d-char-sequence of a raw-string is the same sequence of characters as the initial d-char-sequence.
A d-char-sequence shall consist of at most 16 characters.
[Note
:
The characters '(' and ')' are permitted in a raw-string.
Thus, R"delimiter((a|b))delimiter" is equivalent to "(a|b)".
end note
]
[Note
:
A source-file new-line in a raw string literal results in a new-line in the resulting execution string literal.
Assuming no whitespace at the beginning of lines in the following example, the assert will succeed:
const char* p = R"(a\
b
c)";
assert(std::strcmp(p, "a\\\nb\nc") == 0);
end note
]
[Example
:
The raw string
R"a(
)\
a"
)a"
is equivalent to "\n)\\\na\"\n".
The raw string
R"(??)"
is equivalent to "\?\?".
The raw string
R"#(
)??="
)#"
is equivalent to "\n)\?\?=\"\n".
end example
]
After translation phase 6, a string-literal that does not begin with an encoding-prefix is an ordinary string literal, and is initialized with the given characters.
A string-literal that begins with u8, such as u8"asdf", is a UTF-8 string literal.
Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals.
A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration ([basic.stc]).
For a UTF-8 string literal, each successive element of the object representation ([basic.types]) has the value of the corresponding code unit of the UTF-8 encoding of the string.
A string-literal that begins with u, such as u"asdf", is a char16_­t string literal.
A char16_­t string literal has type “array of n const char16_­t”, where n is the size of the string as defined below; it is initialized with the given characters.
A single c-char may produce more than one char16_­t character in the form of surrogate pairs.
A string-literal that begins with U, such as U"asdf", is a char32_­t string literal.
A char32_­t string literal has type “array of n const char32_­t”, where n is the size of the string as defined below; it is initialized with the given characters.
A string-literal that begins with L, such as L"asdf", is a wide string literal.
A wide string literal has type “array of n const wchar_­t”, where n is the size of the string as defined below; it is initialized with the given characters.
In translation phase 6 ([lex.phases]), adjacent string-literals are concatenated.
If both string-literals have the same encoding-prefix, the resulting concatenated string literal has that encoding-prefix.
If one string-literal has no encoding-prefix, it is treated as a string-literal of the same encoding-prefix as the other operand.
If a UTF-8 string literal token is adjacent to a wide string literal token, the program is ill-formed.
Any other concatenations are conditionally-supported with implementation-defined behavior.
[Note
:
This concatenation is an interpretation, not a conversion.
Because the interpretation happens in translation phase 6 (after each character from a string literal has been translated into a value from the appropriate character set), a string-literal's initial rawness has no effect on the interpretation or well-formedness of the concatenation.
end note
]
Table 9 has some examples of valid concatenations.
Table 9 — String literal concatenations
Source
Means
Source
Means
Source
Means
u"a"
u"b"
u"ab"
U"a"
U"b"
U"ab"
L"a"
L"b"
L"ab"
u"a"
"b"
u"ab"
U"a"
"b"
U"ab"
L"a"
"b"
L"ab"
"a"
u"b"
u"ab"
"a"
U"b"
U"ab"
"a"
L"b"
L"ab"
Characters in concatenated strings are kept distinct.
[Example
:
"\xA" "B"
contains the two characters '\xA' and 'B' after concatenation (and not the single hexadecimal character '\xAB').
end example
]
After any necessary concatenation, in translation phase 7 ([lex.phases]), '\0' is appended to every string literal so that programs that scan a string can find its end.
Escape sequences and universal-character-names in non-raw string literals have the same meaning as in character literals ([lex.ccon]), except that the single quote ' is representable either by itself or by the escape sequence \', and the double quote " shall be preceded by a \, and except that a universal-character-name in a char16_­t string literal may yield a surrogate pair.
In a narrow string literal, a universal-character-name may map to more than one char element due to multibyte encoding.
The size of a char32_­t or wide string literal is the total number of escape sequences, universal-character-names, and other characters, plus one for the terminating U'\0' or L'\0'.
The size of a char16_­t string literal is the total number of escape sequences, universal-character-names, and other characters, plus one for each character requiring a surrogate pair, plus one for the terminating u'\0'.
[Note
:
The size of a char16_­t string literal is the number of code units, not the number of characters.
end note
]
Within char32_­t and char16_­t string literals, any universal-character-names shall be within the range 0x0 to 0x10FFFF.
The size of a narrow string literal is the total number of escape sequences and other characters, plus at least one for the multibyte encoding of each universal-character-name, plus one for the terminating '\0'.
Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above.
Whether all string literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.
[Note
:
The effect of attempting to modify a string literal is undefined.
end note
]

5.13.6 Boolean literals [lex.bool]

boolean-literal:
	false
	true
The Boolean literals are the keywords false and true.
Such literals are prvalues and have type bool.

5.13.7 Pointer literals [lex.nullptr]

The pointer literal is the keyword nullptr.
It is a prvalue of type std​::​nullptr_­t.
[Note
:
std​::​nullptr_­t is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value.
end note
]

5.13.8 User-defined literals [lex.ext]

If a token matches both user-defined-literal and another literal kind, it is treated as the latter.
[Example
:
123_­km is a user-defined-literal, but 12LL is an integer-literal.
end example
]
The syntactic non-terminal preceding the ud-suffix in a user-defined-literal is taken to be the longest sequence of characters that could match that non-terminal.
A user-defined-literal is treated as a call to a literal operator or literal operator template ([over.literal]).
To determine the form of this call for a given user-defined-literal L with ud-suffix X, the literal-operator-id whose literal suffix identifier is X is looked up in the context of L using the rules for unqualified name lookup ([basic.lookup.unqual]).
Let S be the set of declarations found by this lookup.
S shall not be empty.
If L is a user-defined-integer-literal, let n be the literal without its ud-suffix.
If S contains a literal operator with parameter type unsigned long long, the literal L is treated as a call of the form
operator "" X(nULL)
Otherwise, S shall contain a raw literal operator or a literal operator template ([over.literal]) but not both.
If S contains a raw literal operator, the literal L is treated as a call of the form
operator "" X("n")
Otherwise (S contains a literal operator template), L is treated as a call of the form
operator "" X<'', '', ... ''>()
where n is the source character sequence .
[Note
:
The sequence can only contain characters from the basic source character set.
end note
]
If L is a user-defined-floating-literal, let f be the literal without its ud-suffix.
If S contains a literal operator with parameter type long double, the literal L is treated as a call of the form
operator "" X(fL)
Otherwise, S shall contain a raw literal operator or a literal operator template ([over.literal]) but not both.
If S contains a raw literal operator, the literal L is treated as a call of the form
operator "" X("f")
Otherwise (S contains a literal operator template), L is treated as a call of the form
operator "" X<'', '', ... ''>()
where f is the source character sequence .
[Note
:
The sequence can only contain characters from the basic source character set.
end note
]
If L is a user-defined-string-literal, let str be the literal without its ud-suffix and let len be the number of code units in str (i.e., its length excluding the terminating null character). The literal L is treated as a call of the form
operator "" X(str, len)
If L is a user-defined-character-literal, let ch be the literal without its ud-suffix.
S shall contain a literal operator ([over.literal]) whose only parameter has the type of ch and the literal L is treated as a call of the form
operator "" X(ch)
[Example
:
long double operator "" _w(long double);
std::string operator "" _w(const char16_t*, std::size_t);
unsigned operator "" _w(const char*);
int main() {
  1.2_w;      // calls operator "" _­w(1.2L)
  u"one"_w;   // calls operator "" _­w(u"one", 3)
  12_w;       // calls operator "" _­w("12")
  "two"_w;    // error: no applicable literal operator
}
end example
]
In translation phase 6 ([lex.phases]), adjacent string literals are concatenated and user-defined-string-literals are considered string literals for that purpose.
During concatenation, ud-suffixes are removed and ignored and the concatenation process occurs as described in [lex.string].
At the end of phase 6, if a string literal is the result of a concatenation involving at least one user-defined-string-literal, all the participating user-defined-string-literals shall have the same ud-suffix and that suffix is applied to the result of the concatenation.
[Example
:
int main() {
  L"A" "B" "C"_x; // OK: same as L"ABC"_­x
  "P"_x "Q" "R"_y;// error: two different ud-suffixes
}
end example
]

6 Basic concepts [basic]

[Note
:
This Clause presents the basic concepts of the C++ language.
It explains the difference between an object and a name and how they relate to the value categories for expressions.
It introduces the concepts of a declaration and a definition and presents C++'s notion of type, scope, linkage, and storage duration.
The mechanisms for starting and terminating a program are discussed.
Finally, this Clause presents the fundamental types of the language and lists the ways of constructing compound types from these.
end note
]
[Note
:
This Clause does not cover concepts that affect only a single part of the language.
Such concepts are discussed in the relevant Clauses.
end note
]
An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, or parameter pack.
Every name that denotes an entity is introduced by a declaration.
Every name that denotes a label is introduced either by a goto statement ([stmt.goto]) or a labeled-statement.
A variable is introduced by the declaration of a reference other than a non-static data member or of an object.
The variable's name, if any, denotes the reference or object.
Some names denote types or templates.
In general, whenever a name is encountered it is necessary to determine whether that name denotes one of these entities before continuing to parse the program that contains it.
The process that determines this is called name lookup ([basic.lookup]).
Two names are the same if
A name used in more than one translation unit can potentially refer to the same entity in these translation units depending on the linkage ([basic.link]) of the name specified in each translation unit.

6.1 Declarations and definitions [basic.def]

A declaration (Clause [dcl.dcl]) may introduce one or more names into a translation unit or redeclare names introduced by previous declarations.
If so, the declaration specifies the interpretation and attributes of these names.
A declaration may also have effects including:
A declaration is a definition unless
[Example
:
All but one of the following are definitions:
int a;                          // defines a
extern const int c = 1;         // defines c
int f(int x) { return x+a; }    // defines f and defines x
struct S { int a; int b; };     // defines S, S​::​a, and S​::​b
struct X {                      // defines X
  int x;                        // defines non-static data member x
  static int y;                 // declares static data member y
  X(): x(0) { }                 // defines a constructor of X
};
int X::y = 1;                   // defines X​::​y
enum { up, down };              // defines up and down
namespace N { int d; }          // defines N and N​::​d
namespace N1 = N;               // defines N1
X anX;                          // defines anX
whereas these are just declarations:
extern int a;                   // declares a
extern const int c;             // declares c
int f(int);                     // declares f
struct S;                       // declares S
typedef int Int;                // declares Int
extern X anotherX;              // declares anotherX
using N::d;                     // declares d
end example
]
[Note
:
In some circumstances, C++ implementations implicitly define the default constructor ([class.ctor]), copy constructor ([class.copy]), move constructor ([class.copy]), copy assignment operator ([class.copy]), move assignment operator ([class.copy]), or destructor ([class.dtor]) member functions.
end note
]
[Example
:
Given
#include <string>

struct C {
  std::string s;              // std​::​string is the standard library class (Clause [strings])
};

int main() {
  C a;
  C b = a;
  b = a;
}
the implementation will implicitly define functions to make the definition of C equivalent to
struct C {
  std::string s;
  C() : s() { }
  C(const C& x): s(x.s) { }
  C(C&& x): s(static_cast<std::string&&>(x.s)) { }
    // : s(std​::​move(x.s)) { }
  C& operator=(const C& x) { s = x.s; return *this; }
  C& operator=(C&& x) { s = static_cast<std::string&&>(x.s); return *this; }
    // { s = std​::​move(x.s); return *this; }
  ~C() { }
};
end example
]
[Note
:
A class name can also be implicitly declared by an elaborated-type-specifier ([dcl.type.elab]).
end note
]
A program is ill-formed if the definition of any object gives the object an incomplete type ([basic.types]).
Appearing inside the braced-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a definition.

6.2 One-definition rule [basic.def.odr]

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
An expression is potentially evaluated unless it is an unevaluated operand (Clause [expr]) or a subexpression thereof.
The set of potential results of an expression e is defined as follows:
  • If e is an id-expression, the set contains only e.
  • If e is a subscripting operation ([expr.sub]) with an array operand, the set contains the potential results of that operand.
  • If e is a class member access expression ([expr.ref]), the set contains the potential results of the object expression.
  • If e is a pointer-to-member expression ([expr.mptr.oper]) whose second operand is a constant expression, the set contains the potential results of the object expression.
  • If e has the form (e1), the set contains the potential results of e1.
  • If e is a glvalue conditional expression ([expr.cond]), the set is the union of the sets of potential results of the second and third operands.
  • If e is a comma expression ([expr.comma]), the set contains the potential results of the right operand.
  • Otherwise, the set is empty.
[Note
:
This set is a (possibly-empty) set of id-expressions, each of which is either e or a subexpression of e.
[Example
:
In the following example, the set of potential results of the initializer of n contains the first S​::​x subexpression, but not the second S​::​x subexpression.
struct S { static const int x = 0; };
const int &f(const int &r);
int n = b ? (1, S::x)  // S​::​x is not odr-used here
          : f(S::x);   // S​::​x is odr-used here, so a definition is required
end example
]
end note
]
A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion ([conv.lval]) to x yields a constant expression ([expr.const]) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion ([conv.lval]) is applied to e, or e is a discarded-value expression (Clause [expr]).
this is odr-used if it appears as a potentially-evaluated expression (including as the result of the implicit transformation in the body of a non-static member function ([class.mfct.non-static])).
A virtual member function is odr-used if it is not pure.
A function whose name appears as a potentially-evaluated expression is odr-used if it is the unique lookup result or the selected member of a set of overloaded functions ([basic.lookup], [over.match], [over.over]), unless it is a pure virtual function and either its name is not explicitly qualified or the expression forms a pointer to member ([expr.unary.op]).
[Note
:
This covers calls to named functions ([expr.call]), operator overloading (Clause [over]), user-defined conversions ([class.conv.fct]), allocation functions for placement new-expressions ([expr.new]), as well as non-default initialization ([dcl.init]).
A constructor selected to copy or move an object of class type is odr-used even if the call is actually elided by the implementation ([class.copy]).
end note
]
An allocation or deallocation function for a class is odr-used by a new-expression appearing in a potentially-evaluated expression as specified in [expr.new] and [class.free].
A deallocation function for a class is odr-used by a delete expression appearing in a potentially-evaluated expression as specified in [expr.delete] and [class.free].
A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class.
A non-placement deallocation function for a class is odr-used by the definition of the destructor of that class, or by being selected by the lookup at the point of definition of a virtual destructor ([class.dtor]).27
An assignment operator function in a class is odr-used by an implicitly-defined copy-assignment or move-assignment function for another class as specified in [class.copy].
A constructor for a class is odr-used as specified in [dcl.init].
A destructor for a class is odr-used if it is potentially invoked ([class.dtor]).
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement ([stmt.if]); no diagnostic required.
The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]).
An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.
Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class type to be complete.
[Example
:
The following complete translation unit is well-formed, even though it never defines X:
struct X;                       // declare X as a struct type
struct X* x1;                   // use X in pointer formation
X* x2;                          // use X in pointer formation
end example
]
[Note
:
The rules for declarations and expressions describe in which contexts complete class types are required.
A class type T must be complete if:
end note
]
There can be more than one definition of a class type (Clause [class]), enumeration type ([dcl.enum]), inline function with external linkage ([dcl.inline]), inline variable with external linkage ([dcl.inline]), class template (Clause [temp]), non-static function template ([temp.fct]), static data member of a class template ([temp.static]), member function of a class template ([temp.mem.func]), or template specialization for which some template parameters are not specified ([temp.spec], [temp.class.spec]) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.
Given such an entity named D defined in more than one translation unit, then
  • each definition of D shall consist of the same sequence of tokens; and
  • in each definition of D, corresponding names, looked up according to [basic.lookup], shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution ([over.match]) and after matching of partial template specialization ([temp.over]), except that a name can refer to
    • a non-volatile const object with internal or no linkage if the object or
    • a reference with internal or no linkage initialized with a constant expression such that the reference refers to the same entity in all definitions of D;
    and
  • in each definition of D, corresponding entities shall have the same language linkage; and
  • in each definition of D, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same function, or to a function defined within the definition of D; and
  • in each definition of D, a default argument used by an (implicit or explicit) function call is treated as if its token sequence were present in the definition of D; that is, the default argument is subject to the requirements described in this paragraph (and, if the default argument has subexpressions with default arguments, this requirement applies recursively).28
  • if D is a class with an implicitly-declared constructor ([class.ctor]), it is as if the constructor was implicitly defined in every translation unit where it is odr-used, and the implicit definition in every translation unit shall call the same constructor for a subobject of D.
    [Example
    :
    // translation unit 1:
    struct X {
      X(int, int);
      X(int, int, int);
    };
    X::X(int, int = 0) { }
    class D {
      X x = 0;
    };
    D d1;                           // X(int, int) called by D()
    
    // translation unit 2:
    struct X {
      X(int, int);
      X(int, int, int);
    };
    X::X(int, int = 0, int = 0) { }
    class D {
      X x = 0;
    };
    D d2;                           // X(int, int, int) called by D();
                                    // D()'s implicit definition violates the ODR
    
    end example
    ]
If D is a template and is defined in more than one translation unit, then the preceding requirements shall apply both to names from the template's enclosing scope used in the template definition ([temp.nondep]), and also to dependent names at the point of instantiation ([temp.dep]).
If the definitions of D satisfy all these requirements, then the behavior is as if there were a single definition of D.
If the definitions of D do not satisfy these requirements, then the behavior is undefined.
An implementation is not required to call allocation and deallocation functions from constructors or destructors; however, this is a permissible implementation technique.
[dcl.fct.default] describes how default argument names are looked up.

6.3 Scope [basic.scope]

6.3.1 Declarative regions and scopes [basic.scope.declarative]

Every name is introduced in some portion of program text called a declarative region, which is the largest part of the program in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the same entity.
In general, each particular name is valid only within some possibly discontiguous portion of program text called its scope.
To determine the scope of a declaration, it is sometimes convenient to refer to the potential scope of a declaration.
The scope of a declaration is the same as its potential scope unless the potential scope contains another declaration of the same name.
In that case, the potential scope of the declaration in the inner (contained) declarative region is excluded from the scope of the declaration in the outer (containing) declarative region.
[Example
:
In
int j = 24;
int main() {
  int i = j, j;
  j = 42;
}
the identifier j is declared twice as a name (and used twice).
The declarative region of the first j includes the entire example.
The potential scope of the first j begins immediately after that j and extends to the end of the program, but its (actual) scope excludes the text between the , and the }.
The declarative region of the second declaration of j (the j immediately before the semicolon) includes all the text between { and }, but its potential scope excludes the declaration of i.
The scope of the second declaration of j is the same as its potential scope.
end example
]
The names declared by a declaration are introduced into the scope in which the declaration occurs, except that the presence of a friend specifier ([class.friend]), certain uses of the elaborated-type-specifier, and using-directives alter this general behavior.
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name,
  • they shall all refer to the same entity, or all refer to functions and function templates; or
  • exactly one declaration shall declare a class name or enumeration name that is not a typedef name and the other declarations shall all refer to the same variable, non-static data member, or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is hidden ([basic.scope.hiding]).
    [Note
    :
    A namespace name or a class template name must be unique in its declarative region ([namespace.alias], Clause [temp]).
    end note
    ]
[Note
:
These restrictions apply to the declarative region into which a name is introduced, which is not necessarily the same as the region in which the declaration occurs.
In particular, elaborated-type-specifiers ([dcl.type.elab]) and friend declarations ([class.friend]) may introduce a (possibly not visible) name into an enclosing namespace; these restrictions apply to that region.
Local extern declarations ([basic.link]) may introduce a name into the declarative region where the declaration appears and also introduce a (possibly not visible) name into an enclosing namespace; these restrictions apply to both regions.
end note
]
[Note
:
The name lookup rules are summarized in [basic.lookup].
end note
]

6.3.2 Point of declaration [basic.scope.pdecl]

The point of declaration for a name is immediately after its complete declarator (Clause [dcl.decl]) and before its initializer (if any), except as noted below.
[Example
:
unsigned char x = 12;
{ unsigned char x = x; }
Here the second x is initialized with its own (indeterminate) value.
end example
]
[Note
:
a name from an outer scope remains visible up to the point of declaration of the name that hides it.
[Example
:
const int  i = 2;
{ int  i[i]; }
declares a block-scope array of two integers.
end example
]
end note
]
The point of declaration for a class or class template first declared by a class-specifier is immediately after the identifier or simple-template-id (if any) in its class-head.
The point of declaration for an enumeration is immediately after the identifier (if any) in either its enum-specifier or its first opaque-enum-declaration, whichever comes first.
The point of declaration of an alias or alias template immediately follows the type-id to which the alias refers.
The point of declaration of a using-declarator that does not name a constructor is immediately after the using-declarator.
The point of declaration for an enumerator is immediately after its enumerator-definition.
[Example
:
const int x = 12;
{ enum { x = x }; }
Here, the enumerator x is initialized with the value of the constant x, namely 12.
end example
]
After the point of declaration of a class member, the member name can be looked up in the scope of its class.
[Note
:
This is true even if the class is an incomplete class.
For example,
struct X {
  enum E { z = 16 };
  int b[X::z];      // OK
};
end note
]
The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
The point of declaration for an injected-class-name (Clause [class]) is immediately following the opening brace of the class definition.
The point of declaration for a function-local predefined variable ([dcl.fct.def]) is immediately before the function-body of a function definition.
The point of declaration for a template parameter is immediately after its complete template-parameter.
[Example
:
typedef unsigned char T;
template<class T
  = T     // lookup finds the typedef name of unsigned char
  , T     // lookup finds the template parameter
    N = 0> struct A { };
end example
]
[Note
:
Friend declarations refer to functions or classes that are members of the nearest enclosing namespace, but they do not introduce new names into that namespace ([namespace.memdef]).
Function declarations at block scope and variable declarations with the extern specifier at block scope refer to declarations that are members of an enclosing namespace, but they do not introduce new names into that scope.
end note
]
[Note
:
For point of instantiation of a template, see [temp.point].
end note
]

6.3.3 Block scope [basic.scope.block]

A name declared in a block ([stmt.block]) is local to that block; it has block scope.
Its potential scope begins at its point of declaration ([basic.scope.pdecl]) and ends at the end of its block.
A variable declared at block scope is a local variable.
The potential scope of a function parameter name (including one appearing in a lambda-declarator) or of a function-local predefined variable in a function definition ([dcl.fct.def]) begins at its point of declaration.
If the function has a function-try-block the potential scope of a parameter or of a function-local predefined variable ends at the end of the last associated handler, otherwise it ends at the end of the outermost block of the function definition.
A parameter name shall not be redeclared in the outermost block of the function definition nor in the outermost block of any handler associated with a function-try-block.
The name declared in an exception-declaration is local to the handler and shall not be redeclared in the outermost block of the handler.
Names declared in the init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement; see [stmt.select].

6.3.4 Function prototype scope [basic.scope.proto]

In a function declaration, or in any function declarator except the declarator of a function definition ([dcl.fct.def]), names of parameters (if supplied) have function prototype scope, which terminates at the end of the nearest enclosing function declarator.

6.3.5 Function scope [basic.funscope]

Labels ([stmt.label]) have function scope and may be used anywhere in the function in which they are declared.
Only labels have function scope.

6.3.6 Namespace scope [basic.scope.namespace]

The declarative region of a namespace-definition is its namespace-body.
Entities declared in a namespace-body are said to be members of the namespace, and names introduced by these declarations into the declarative region of the namespace are said to be member names of the namespace.
A namespace member name has namespace scope.
Its potential scope includes its namespace from the name's point of declaration ([basic.scope.pdecl]) onwards; and for each using-directive that nominates the member's namespace, the member's potential scope includes that portion of the potential scope of the using-directive that follows the member's point of declaration.
[Example
:
namespace N {
  int i;
  int g(int a) { return a; }
  int j();
  void q();
}
namespace { int l=1; }
// the potential scope of l is from its point of declaration to the end of the translation unit

namespace N {
  int g(char a) {   // overloads N​::​g(int)
    return l+a;     // l is from unnamed namespace
  }

  int i;            // error: duplicate definition
  int j();          // OK: duplicate function declaration

  int j() {         // OK: definition of N​::​j()
    return g(i);    // calls N​::​g(int)
  }
  int q();          // error: different return type
}
end example
]
A namespace member can also be referred to after the ​::​ scope resolution operator ([expr.prim]) applied to the name of its namespace or the name of a namespace which nominates the member's namespace in a using-directive; see [namespace.qual].
The outermost declarative region of a translation unit is also a namespace, called the global namespace.
A name declared in the global namespace has global namespace scope (also called global scope).
The potential scope of such a name begins at its point of declaration ([basic.scope.pdecl]) and ends at the end of the translation unit that is its declarative region.
A name with global namespace scope is said to be a global name.

6.3.7 Class scope [basic.scope.class]

The potential scope of a name declared in a class consists not only of the declarative region following the name's point of declaration, but also of all function bodies, default arguments, noexcept-specifiers, and brace-or-equal-initializers of non-static data members in that class (including such things in nested classes).
A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S.
No diagnostic is required for a violation of this rule.
A name declared within a member function hides a declaration of the same name whose scope extends to or past the end of the member function's class.
The potential scope of a declaration that extends to or past the end of a class definition also extends to the regions defined by its member definitions, even if the members are defined lexically outside the class (this includes static data member definitions, nested class definitions, and member function definitions, including the member function body and any portion of the declarator part of such definitions which follows the declarator-id, including a parameter-declaration-clause and any default arguments ([dcl.fct.default])).
[Example
:
typedef int  c;
enum { i = 1 };

class X {
  char  v[i];                       // error: i refers to ​::​i but when reevaluated is X​::​i
  int  f() { return sizeof(c); }    // OK: X​::​c
  char  c;
  enum { i = 2 };
};

typedef char*  T;
struct Y {
  T  a;                             // error: T refers to ​::​T but when reevaluated is Y​::​T
  typedef long  T;
  T  b;
};

typedef int I;
class D {
  typedef I I;                      // error, even though no reordering involved
};
end example
]
The name of a class member shall only be used as follows:
  • in the scope of its class (as described above) or a class derived (Clause [class.derived]) from its class,
  • after the . operator applied to an expression of the type of its class ([expr.ref]) or a class derived from its class,
  • after the -> operator applied to a pointer to an object of its class ([expr.ref]) or a class derived from its class,
  • after the ​::​ scope resolution operator ([expr.prim]) applied to the name of its class or a class derived from its class.

6.3.8 Enumeration scope [basic.scope.enum]

The name of a scoped enumerator ([dcl.enum]) has enumeration scope.
Its potential scope begins at its point of declaration and terminates at the end of the enum-specifier.

6.3.9 Template parameter scope [basic.scope.temp]

The declarative region of the name of a template parameter of a template template-parameter is the smallest template-parameter-list in which the name was introduced.
The declarative region of the name of a template parameter of a template is the smallest template-declaration in which the name was introduced.
Only template parameter names belong to this declarative region; any other kind of name introduced by the declaration of a template-declaration is instead introduced into the same declarative region where it would be introduced as a result of a non-template declaration of the same name.
[Example
:
namespace N {
  template<class T> struct A { };               // #1
  template<class U> void f(U) { }               // #2
  struct B {
    template<class V> friend int g(struct C*);  // #3
  };
}
The declarative regions of T, U and V are the template-declarations on lines #1, #2, and #3, respectively.
But the names A, f, g and C all belong to the same declarative region — namely, the namespace-body of N.
(g is still considered to belong to this declarative region in spite of its being hidden during qualified and unqualified name lookup.)
end example
]
The potential scope of a template parameter name begins at its point of declaration ([basic.scope.pdecl]) and ends at the end of its declarative region.
[Note
:
This implies that a template-parameter can be used in the declaration of subsequent template-parameters and their default arguments but cannot be used in preceding template-parameters or their default arguments.
For example,
template<class T, T* p, class U = T> class X { /* ... */ };
template<class T> void f(T* p = new T);
This also implies that a template-parameter can be used in the specification of base classes.
For example,
template<class T> class X : public Array<T> { /* ... */ };
template<class T> class Y : public T { /* ... */ };
The use of a template parameter as a base class implies that a class used as a template argument must be defined and not just declared when the class template is instantiated.
end note
]
The declarative region of the name of a template parameter is nested within the immediately-enclosing declarative region.
[Note
:
As a result, a template-parameter hides any entity with the same name in an enclosing scope ([basic.scope.hiding]).
[Example
:
typedef int N;
template<N X, typename N, template<N Y> class T> struct A;
Here, X is a non-type template parameter of type int and Y is a non-type template parameter of the same type as the second template parameter of A.
end example
]
end note
]
[Note
:
Because the name of a template parameter cannot be redeclared within its potential scope ([temp.local]), a template parameter's scope is often its potential scope.
However, it is still possible for a template parameter name to be hidden; see [temp.local].
end note
]

6.3.10 Name hiding [basic.scope.hiding]

A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class ([class.member.lookup]).
A class name ([class.name]) or enumeration name ([dcl.enum]) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope.
If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
In a member function definition, the declaration of a name at block scope hides the declaration of a member of the class with the same name; see [basic.scope.class].
The declaration of a member in a derived class (Clause [class.derived]) hides the declaration of a member of a base class of the same name; see [class.member.lookup].
During the lookup of a name qualified by a namespace name, declarations that would otherwise be made visible by a using-directive can be hidden by declarations with the same name in the namespace containing the using-directive; see [namespace.qual].
If a name is in scope and is not hidden it is said to be visible.

6.4 Name lookup [basic.lookup]

The name lookup rules apply uniformly to all names (including typedef-names, namespace-names ([basic.namespace]), and class-names ([class.name])) wherever the grammar allows such names in the context discussed by a particular rule.
Name lookup associates the use of a name with a set of declarations ([basic.def]) of that name.
The declarations found by name lookup shall either all declare the same entity or shall all declare functions; in the latter case, the declarations are said to form a set of overloaded functions ([over.load]).
Overload resolution ([over.match]) takes place after name lookup has succeeded.
The access rules (Clause [class.access]) are considered only once name lookup and function overload resolution (if applicable) have succeeded.
Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name's declaration used further in expression processing (Clause [expr]).
A name “looked up in the context of an expression” is looked up as an unqualified name in the scope where the expression is found.
The injected-class-name of a class (Clause [class]) is also considered to be a member of that class for the purposes of name hiding and lookup.
[Note
:
[basic.link] discusses linkage issues.
The notions of scope, point of declaration and name hiding are discussed in [basic.scope].
end note
]

6.4.1 Unqualified name lookup [basic.lookup.unqual]

In all the cases listed in [basic.lookup.unqual], the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name.
If no declaration is found, the program is ill-formed.
The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing the using-directive; see [namespace.udir].
For the purpose of the unqualified name lookup rules described in [basic.lookup.unqual], the declarations from the namespace nominated by the using-directive are considered members of that enclosing namespace.
The lookup for an unqualified name used as the postfix-expression of a function call is described in [basic.lookup.argdep].
[Note
:
For purposes of determining (during parsing) whether an expression is a postfix-expression for a function call, the usual name lookup rules apply.
The rules in [basic.lookup.argdep] have no effect on the syntactic interpretation of an expression.
For example,
typedef int f;
namespace N {
  struct A {
    friend void f(A &);
    operator int();
    void g(A a) {
      int i = f(a);  // f is the typedef, not the friend function: equivalent to int(a)
    }
  };
}
Because the expression is not a function call, the argument-dependent name lookup ([basic.lookup.argdep]) does not apply and the friend function f is not found.
end note
]
A name used in global scope, outside of any function, class or user-declared namespace, shall be declared before its use in global scope.
A name used in a user-declared namespace outside of the definition of any function or class shall be declared before its use in that namespace or before its use in a namespace enclosing its namespace.
In the definition of a function that is a member of namespace N, a name used after the function's declarator-id29 shall be declared before its use in the block in which it is used or in one of its enclosing blocks ([stmt.block]) or shall be declared before its use in namespace N or, if N is a nested namespace, shall be declared before its use in one of N's enclosing namespaces.
[Example
:
namespace A {
  namespace N {
    void f();
  }
}
void A::N::f() {
  i = 5;
  // The following scopes are searched for a declaration of i:
  // 1) outermost block scope of A​::​N​::​f, before the use of i
  // 2) scope of namespace N
  // 3) scope of namespace A
  // 4) global scope, before the definition of A​::​N​::​f
}
end example
]
A name used in the definition of a class X outside of a member function body, default argument, noexcept-specifier, brace-or-equal-initializer of a non-static data member, or nested class definition30 shall be declared in one of the following ways:
  • before its use in class X or be a member of a base class of X ([class.member.lookup]), or
  • if X is a nested class of class Y ([class.nest]), before the definition of X in Y, or shall be a member of a base class of Y (this lookup applies in turn to Y's enclosing classes, starting with the innermost enclosing class),31 or
  • if X is a local class ([class.local]) or is a nested class of a local class, before the definition of class X in a block enclosing the definition of class X, or
  • if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class or a nested class within a local class of a function that is a member of N, before the definition of class X in namespace N or in one of N's enclosing namespaces.
[Example
:
namespace M {
  class B { };
}
namespace N {
  class Y : public M::B {
    class X {
      int a[i];
    };
  };
}

// The following scopes are searched for a declaration of i:
// 1) scope of class N​::​Y​::​X, before the use of i
// 2) scope of class N​::​Y, before the definition of N​::​Y​::​X
// 3) scope of N​::​Y's base class M​::​B
// 4) scope of namespace N, before the definition of N​::​Y
// 5) global scope, before the definition of N
end example
]
[Note
:
When looking for a prior declaration of a class or function introduced by a friend declaration, scopes outside of the innermost enclosing namespace scope are not considered; see [namespace.memdef].
end note
]
[Note
:
[basic.scope.class] further describes the restrictions on the use of names in a class definition.
[class.nest] further describes the restrictions on the use of names in nested class definitions.
[class.local] further describes the restrictions on the use of names in local class definitions.
end note
]
For the members of a class X, a name used in a member function body, in a default argument, in a noexcept-specifier, in the brace-or-equal-initializer of a non-static data member ([class.mem]), or in the definition of a class member outside of the definition of X, following the member's declarator-id32, shall be declared in one of the following ways:
  • before its use in the block in which it is used or in an enclosing block ([stmt.block]), or
  • shall be a member of class X or be a member of a base class of X ([class.member.lookup]), or
  • if X is a nested class of class Y ([class.nest]), shall be a member of Y, or shall be a member of a base class of Y (this lookup applies in turn to Y's enclosing classes, starting with the innermost enclosing class),33 or
  • if X is a local class ([class.local]) or is a nested class of a local class, before the definition of class X in a block enclosing the definition of class X, or
  • if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class or a nested class within a local class of a function that is a member of N, before the use of the name, in namespace N or in one of N's enclosing namespaces.
[Example
:
class B { };
namespace M {
  namespace N {
    class X : public B {
      void f();
    };
  }
}
void M::N::X::f() {
  i = 16;
}

// The following scopes are searched for a declaration of i:
// 1) outermost block scope of M​::​N​::​X​::​f, before the use of i
// 2) scope of class M​::​N​::​X
// 3) scope of M​::​N​::​X's base class B
// 4) scope of namespace M​::​N
// 5) scope of namespace M
// 6) global scope, before the definition of M​::​N​::​X​::​f
end example
]
[Note
:
[class.mfct] and [class.static] further describe the restrictions on the use of names in member function definitions.
[class.nest] further describes the restrictions on the use of names in the scope of nested classes.
[class.local] further describes the restrictions on the use of names in local class definitions.
end note
]
Name lookup for a name used in the definition of a friend function ([class.friend]) defined inline in the class granting friendship shall proceed as described for lookup in member function definitions.
If the friend function is not defined in the class granting friendship, name lookup in the friend function definition shall proceed as described for lookup in namespace member function definitions.
In a friend declaration naming a member function, a name used in the function declarator and not part of a template-argument in the declarator-id is first looked up in the scope of the member function's class ([class.member.lookup]).
If it is not found, or if the name is part of a template-argument in the declarator-id, the look up is as described for unqualified names in the definition of the class granting friendship.
[Example
:
struct A {
  typedef int AT;
  void f1(AT);
  void f2(float);
  template <class T> void f3();
};
struct B {
  typedef char AT;
  typedef float BT;
  friend void A::f1(AT);      // parameter type is A​::​AT
  friend void A::f2(BT);      // parameter type is B​::​BT
  friend void A::f3<AT>();    // template argument is B​::​AT
};
end example
]
During the lookup for a name used as a default argument ([dcl.fct.default]) in a function parameter-declaration-clause or used in the expression of a mem-initializer for a constructor ([class.base.init]), the function parameter names are visible and hide the names of entities declared in the block, class or namespace scopes containing the function declaration.
[Note
:
[dcl.fct.default] further describes the restrictions on the use of names in default arguments.
[class.base.init] further describes the restrictions on the use of names in a ctor-initializer.
end note
]
During the lookup of a name used in the constant-expression of an enumerator-definition, previously declared enumerators of the enumeration are visible and hide the names of entities declared in the block, class, or namespace scopes containing the enum-specifier.
A name used in the definition of a static data member of class X ([class.static.data]) (after the qualified-id of the static member) is looked up as if the name was used in a member function of X.
[Note
:
[class.static.data] further describes the restrictions on the use of names in the definition of a static data member.
end note
]
If a variable member of a namespace is defined outside of the scope of its namespace then any name that appears in the definition of the member (after the declarator-id) is looked up as if the definition of the member occurred in its namespace.
[Example
:
namespace N {
  int i = 4;
  extern int j;
}

int i = 2;

int N::j = i;       // N​::​j == 4
end example
]
A name used in the handler for a function-try-block is looked up as if the name was used in the outermost block of the function definition.
In particular, the function parameter names shall not be redeclared in the exception-declaration nor in the outermost block of a handler for the function-try-block.
Names declared in the outermost block of the function definition are not found when looked up in the scope of a handler for the function-try-block.
[Note
:
But function parameter names are found.
end note
]
[Note
:
The rules for name lookup in template definitions are described in [temp.res].
end note
]
This refers to unqualified names that occur, for instance, in a type or default argument in the parameter-declaration-clause or used in the function body.
This refers to unqualified names following the class name; such a name may be used in the base-clause or may be used in the class definition.
This lookup applies whether the definition of X is nested within Y's definition or whether X's definition appears in a namespace scope enclosing Y's definition ([class.nest]).
That is, an unqualified name that occurs, for instance, in a type in the parameter-declaration-clause or in the noexcept-specifier.
This lookup applies whether the member function is defined within the definition of class X or whether the member function is defined in a namespace scope enclosing X's definition.

6.4.2 Argument-dependent name lookup [basic.lookup.argdep]

When the postfix-expression in a function call ([expr.call]) is an unqualified-id, other namespaces not considered during the usual unqualified lookup ([basic.lookup.unqual]) may be searched, and in those namespaces, namespace-scope friend function or function template declarations ([class.friend]) not otherwise visible may be found.
These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument).
[Example
:
namespace N {
  struct S { };
  void f(S);
}

void g() {
  N::S s;
  f(s);             // OK: calls N​::​f
  (f)(s);           // error: N​::​f not considered; parentheses prevent argument-dependent lookup
}
end example
]
For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered.
The sets of namespaces and classes are determined entirely by the types of the function arguments (and the namespace of any template template argument).
Typedef names and using-declarations used to specify the types do not contribute to this set.
The sets of namespaces and classes are determined in the following way:
  • If T is a fundamental type, its associated sets of namespaces and classes are both empty.
  • If T is a class type (including unions), its associated classes are: the class itself; the class of which it is a member, if any; and its direct and indirect base classes.
    Its associated namespaces are the innermost enclosing namespaces of its associated classes.
    Furthermore, if T is a class template specialization, its associated namespaces and classes also include: the namespaces and classes associated with the types of the template arguments provided for template type parameters (excluding template template parameters); the namespaces of which any template template arguments are members; and the classes of which any member templates used as template template arguments are members.
    [Note
    :
    Non-type template arguments do not contribute to the set of associated namespaces.
    end note
    ]
  • If T is an enumeration type, its associated namespace is the innermost enclosing namespace of its declaration.
    If it is a class member, its associated class is the member's class; else it has no associated class.
  • If T is a pointer to U or an array of U, its associated namespaces and classes are those associated with U.
  • If T is a function type, its associated namespaces and classes are those associated with the function parameter types and those associated with the return type.
  • If T is a pointer to a member function of a class X, its associated namespaces and classes are those associated with the function parameter types and return type, together with those associated with X.
  • If T is a pointer to a data member of class X, its associated namespaces and classes are those associated with the member type together with those associated with X.
If an associated namespace is an inline namespace ([namespace.def]), its enclosing namespace is also included in the set.
If an associated namespace directly contains inline namespaces, those inline namespaces are also included in the set.
In addition, if the argument is the name or address of a set of overloaded functions and/or function templates, its associated classes and namespaces are the union of those associated with each of the members of the set, i.e., the classes and namespaces associated with its parameter types and return type. Additionally, if the aforementioned set of overloaded functions is named with a template-id, its associated classes and namespaces also include those of its type template-arguments and its template template-arguments.
Let X be the lookup set produced by unqualified lookup ([basic.lookup.unqual]) and let Y be the lookup set produced by argument dependent lookup (defined as follows).
If X contains
  • a declaration of a class member, or
  • a block-scope function declaration that is not a using-declaration, or
  • a declaration that is neither a function nor a function template
then Y is empty.
Otherwise Y is the set of declarations found in the namespaces associated with the argument types as described below.
The set of declarations found by the lookup of the name is the union of X and Y.
[Note
:
The namespaces and classes associated with the argument types can include namespaces and classes already considered by the ordinary unqualified lookup.
end note
]
[Example
:
namespace NS {
  class T { };
  void f(T);
  void g(T, int);
}
NS::T parm;
void g(NS::T, float);
int main() {
  f(parm);                      // OK: calls NS​::​f
  extern void g(NS::T, float);
  g(parm, 1);                   // OK: calls g(NS​::​T, float)
}
end example
]
When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier ([namespace.qual]) except that:
  • Any using-directives in the associated namespace are ignored.
  • Any namespace-scope friend functions or friend function templates declared in associated classes are visible within their respective namespaces even if they are not visible during an ordinary lookup ([class.friend]).
  • All names except those of (possibly overloaded) functions and function templates are ignored.

6.4.3 Qualified name lookup [basic.lookup.qual]

The name of a class or namespace member or enumerator can be referred to after the ​::​ scope resolution operator ([expr.prim]) applied to a nested-name-specifier that denotes its class, namespace, or enumeration.
If a ​::​ scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that ​::​ considers only namespaces, types, and templates whose specializations are types.
If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.
[Example
:
class A {
public:
  static int n;
};
int main() {
  int A;
  A::n = 42;        // OK
  A b;              // ill-formed: A does not name a type
}
end example
]
[Note
:
Multiply qualified names, such as N1​::​N2​::​N3​::​n, can be used to refer to members of nested classes ([class.nest]) or members of nested namespaces.
end note
]
In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declared are looked up in the defining namespace scope; names following the qualified-id are looked up in the scope of the member's class or namespace.
[Example
:
class X { };
class C {
  class X { };
  static const int number = 50;
  static X arr[number];
};
X C::arr[number];   // ill-formed:
                    // equivalent to ​::​X C​::​arr[C​::​number];
                    // and not to C​::​X C​::​arr[C​::​number];
end example
]
A name prefixed by the unary scope operator ​::​ ([expr.prim]) is looked up in global scope, in the translation unit where it is used.
The name shall be declared in global namespace scope or shall be a name whose declaration is visible in global scope because of a using-directive ([namespace.qual]).
The use of ​::​ allows a global name to be referred to even if its identifier has been hidden ([basic.scope.hiding]).
A name prefixed by a nested-name-specifier that nominates an enumeration type shall represent an enumerator of that enumeration.
If a pseudo-destructor-name ([expr.pseudo]) contains a nested-name-specifier, the type-names are looked up as types in the scope designated by the nested-name-specifier.
Similarly, in a qualified-id of the form:
nested-name-specifier class-name :: ~ class-name
the second class-name is looked up in the same scope as the first.
[Example
:
struct C {
  typedef int I;
};
typedef int I1, I2;
extern int* p;
extern int* q;
p->C::I::~I();      // I is looked up in the scope of C
q->I1::~I2();       // I2 is looked up in the scope of the postfix-expression

struct A {
  ~A();
};
typedef A AB;
int main() {
  AB* p;
  p->AB::~AB();     // explicitly calls the destructor for A
}
end example
]
[Note
:
[basic.lookup.classref] describes how name lookup proceeds after the . and -> operators.
end note
]

6.4.3.1 Class members [class.qual]

If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-specifier is looked up in the scope of the class ([class.member.lookup]), except for the cases listed below.
The name shall represent one or more members of that class or of one of its base classes (Clause [class.derived]).
[Note
:
A class member can be referred to using a qualified-id at any point in its potential scope ([basic.scope.class]).
end note
]
The exceptions to the name lookup rule above are the following:
In a lookup in which function names are not ignored34 and the nested-name-specifier nominates a class C: the name is instead considered to name the constructor of class C.
[Note
:
For example, the constructor is not an acceptable lookup result in an elaborated-type-specifier so the constructor would not be used in place of the injected-class-name.
end note
]
Such a constructor name shall be used only in the declarator-id of a declaration that names a constructor or in a using-declaration.
[Example
:
struct A { A(); };
struct B: public A { B(); };

A::A() { }
B::B() { }

B::A ba;            // object of type A
A::A a;             // error, A​::​A is not a type name
struct A::A a2;     // object of type A
end example
]
A class member name hidden by a name in a nested declarative region or by the name of a derived class member can still be found if qualified by the name of its class followed by the ​::​ operator.
Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.

6.4.3.2 Namespace members [namespace.qual]

If the nested-name-specifier of a qualified-id nominates a namespace (including the case where the nested-name-specifier is ​::​, i.e., nominating the global namespace), the name specified after the nested-name-specifier is looked up in the scope of the namespace.
The names in a template-argument of a template-id are looked up in the context in which the entire postfix-expression occurs.
For a namespace X and name m, the namespace-qualified lookup set is defined as follows: Let be the set of all declarations of m in X and the inline namespace set of X ([namespace.def]).
If is not empty, is ; otherwise, is the union of for all namespaces nominated by using-directives in X and its inline namespace set.
Given X​::​m (where X is a user-declared namespace), or given ​::​m (where X is the global namespace), if is the empty set, the program is ill-formed.
Otherwise, if has exactly one member, or if the context of the reference is a using-declaration, is the required set of declarations of m.
Otherwise if the use of m is not one that allows a unique declaration to be chosen from , the program is ill-formed.
[Example
:
int x;
namespace Y {
  void f(float);
  void h(int);
}

namespace Z {
  void h(double);
}

namespace A {
  using namespace Y;
  void f(int);
  void g(int);
  int i;
}

namespace B {
  using namespace Z;
  void f(char);
  int i;
}

namespace AB {
  using namespace A;
  using namespace B;
  void g();
}

void h()
{
  AB::g();          // g is declared directly in AB, therefore S is { AB​::​g() } and AB​::​g() is chosen

  AB::f(1);         // f is not declared directly in AB so the rules are applied recursively to A and B;
                    // namespace Y is not searched and Y​::​f(float) is not considered;
                    // S is  and overload resolution chooses A​::​f(int)

  AB::f('c');       // as above but resolution chooses B​::​f(char)

  AB::x++;          // x is not declared directly in AB, and is not declared in A or B, so the rules
                    // are applied recursively to Y and Z, S is { } so the program is ill-formed

  AB::i++;          // i is not declared directly in AB so the rules are applied recursively to A and B,
                    // S is  so the use is ambiguous and the program is ill-formed

  AB::h(16.8);      // h is not declared directly in AB and not declared directly in A or B so the rules
                    // are applied recursively to Y and Z, S is  and
                    // overload resolution chooses Z​::​h(double)
}
end example
]
[Note
:
The same declaration found more than once is not an ambiguity (because it is still a unique declaration).
[Example
:
namespace A {
  int a;
}

namespace B {
  using namespace A;
}

namespace C {
  using namespace A;
}

namespace BC {
  using namespace B;
  using namespace C;
}

void f()
{
  BC::a++;          // OK: S is 
}

namespace D {
  using A::a;
}

namespace BD {
  using namespace B;
  using namespace D;
}

void g()
{
  BD::a++;          // OK: S is 
}
end example
]
end note
]
[Example
:
Because each referenced namespace is searched at most once, the following is well-defined:
namespace B {
  int b;
}

namespace A {
  using namespace B;
  int a;
}

namespace B {
  using namespace A;
}

void f()
{
  A::a++;           // OK: a declared directly in A, S is { A​::​a }
  B::a++;           // OK: both A and B searched (once), S is { A​::​a }
  A::b++;           // OK: both A and B searched (once), S is { B​::​b }
  B::b++;           // OK: b declared directly in B, S is { B​::​b }
}
end example
]
During the lookup of a qualified namespace member name, if the lookup finds more than one declaration of the member, and if one declaration introduces a class name or enumeration name and the other declarations either introduce the same variable, the same enumerator or a set of functions, the non-type name hides the class or enumeration name if and only if the declarations are from the same namespace; otherwise (the declarations are from different namespaces), the program is ill-formed.
[Example
:
namespace A {
  struct x { };
  int x;
  int y;
}

namespace B {
  struct y { };
}

namespace C {
  using namespace A;
  using namespace B;
  int i = C::x;     // OK, A​::​x (of type int)
  int j = C::y;     // ambiguous, A​::​y or B​::​y
}
end example
]
In a declaration for a namespace member in which the declarator-id is a qualified-id, given that the qualified-id for the namespace member has the form
nested-name-specifier unqualified-id
the unqualified-id shall name a member of the namespace designated by the nested-name-specifier or of an element of the inline namespace set ([namespace.def]) of that namespace.
[Example
:
namespace A {
  namespace B {
    void f1(int);
  }
  using namespace B;
}
void A::f1(int){ }  // ill-formed, f1 is not a member of A
end example
]
However, in such namespace member declarations, the nested-name-specifier may rely on using-directives to implicitly provide the initial part of the nested-name-specifier.
[Example
:
namespace A {
  namespace B {
    void f1(int);
  }
}

namespace C {
  namespace D {
    void f1(int);
  }
}

using namespace A;
using namespace C::D;
void B::f1(int){ }  // OK, defines A​::​B​::​f1(int)
end example
]

6.4.4 Elaborated type specifiers [basic.lookup.elab]

An elaborated-type-specifier may be used to refer to a previously declared class-name or enum-name even though the name has been hidden by a non-type declaration ([basic.scope.hiding]).
If the elaborated-type-specifier has no nested-name-specifier, and unless the elaborated-type-specifier appears in a declaration with the following form:
class-key attribute-specifier-seq identifier ;
the identifier is looked up according to [basic.lookup.unqual] but ignoring any non-type names that have been declared.
If the elaborated-type-specifier is introduced by the enum keyword and this lookup does not find a previously declared type-name, the elaborated-type-specifier is ill-formed.
If the elaborated-type-specifier is introduced by the class-key and this lookup does not find a previously declared type-name, or if the elaborated-type-specifier appears in a declaration with the form:
If the elaborated-type-specifier has a nested-name-specifier, qualified name lookup is performed, as described in [basic.lookup.qual], but ignoring any non-type names that have been declared.
If the name lookup does not find a previously declared type-name, the elaborated-type-specifier is ill-formed.
[Example
:
struct Node {
  struct Node* Next;            // OK: Refers to Node at global scope
  struct Data* Data;            // OK: Declares type Data
                                // at global scope and member Data
};

struct Data {
  struct Node* Node;            // OK: Refers to Node at global scope
  friend struct ::Glob;         // error: Glob is not declared, cannot introduce a qualified type ([dcl.type.elab])
  friend struct Glob;           // OK: Refers to (as yet) undeclared Glob at global scope.
  /* ... */
};

struct Base {
  struct Data;                  // OK: Declares nested Data
  struct ::Data*     thatData;  // OK: Refers to ​::​Data
  struct Base::Data* thisData;  // OK: Refers to nested Data
  friend class ::Data;          // OK: global Data is a friend
  friend class Data;            // OK: nested Data is a friend
  struct Data { /* ... */ };    // Defines nested Data
};

struct Data;                    // OK: Redeclares Data at global scope
struct ::Data;                  // error: cannot introduce a qualified type ([dcl.type.elab])
struct Base::Data;              // error: cannot introduce a qualified type ([dcl.type.elab])
struct Base::Datum;             // error: Datum undefined
struct Base::Data* pBase;       // OK: refers to nested Data
end example
]

6.4.5 Class member access [basic.lookup.classref]

In a class member access expression ([expr.ref]), if the . or -> token is immediately followed by an identifier followed by a <, the identifier must be looked up to determine whether the < is the beginning of a template argument list ([temp.names]) or a less-than operator.
The identifier is first looked up in the class of the object expression.
If the identifier is not found, it is then looked up in the context of the entire postfix-expression and shall name a class template.
If the id-expression in a class member access ([expr.ref]) is an unqualified-id, and the type of the object expression is of a class type C, the unqualified-id is looked up in the scope of class C.
For a pseudo-destructor call ([expr.pseudo]), the unqualified-id is looked up in the context of the complete postfix-expression.
If the unqualified-id is ~type-name, the type-name is looked up in the context of the entire postfix-expression.
If the type T of the object expression is of a class type C, the type-name is also looked up in the scope of class C.
At least one of the lookups shall find a name that refers to cv T.
[Example
:
struct A { };

struct B {
  struct A { };
  void f(::A* a);
};

void B::f(::A* a) {
  a->~A();                      // OK: lookup in *a finds the injected-class-name
}
end example
]
If the id-expression in a class member access is a qualified-id of the form
class-name-or-namespace-name::...
the class-name-or-namespace-name following the . or -> operator is first looked up in the class of the object expression and the name, if found, is used.
Otherwise it is looked up in the context of the entire postfix-expression.
[Note
:
See [basic.lookup.qual], which describes the lookup of a name before ​::​, which will only find a type or namespace name.
end note
]
If the qualified-id has the form
::class-name-or-namespace-name::...
the class-name-or-namespace-name is looked up in global scope as a class-name or namespace-name.
If the nested-name-specifier contains a simple-template-id, the names in its template-arguments are looked up in the context in which the entire postfix-expression occurs.
If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the object expression and the name, if found, is used.
Otherwise it is looked up in the context of the entire postfix-expression.
In each of these lookups, only names that denote types or templates whose specializations are types are considered.
[Example
:
struct A { };
namespace N {
  struct A {
    void g() { }
    template <class T> operator T();
  };
}

int main() {
  N::A a;
  a.operator A();               // calls N​::​A​::​operator N​::​A
}
end example
]

6.4.6 Using-directives and namespace aliases [basic.lookup.udir]

In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier only namespace names are considered.

6.6 Start and termination [basic.start]

6.6.1 main function [basic.start.main]

A program shall contain a global function called main.
Executing a program starts a main thread of execution ([intro.multithread], [thread.threads]) in which the main function is invoked, and in which variables of static storage duration might be initialized ([basic.start.static]) and destroyed ([basic.start.term]).
It is implementation-defined whether a program in a freestanding environment is required to define a main function.
[Note
:
In a freestanding environment, start-up and termination is implementation-defined; start-up contains the execution of constructors for objects of namespace scope with static storage duration; termination contains the execution of destructors for objects with static storage duration.
end note
]
An implementation shall not predefine the main function.
This function shall not be overloaded.
Its type shall have C++ language linkage and it shall have a declared return type of type int, but otherwise its type is implementation-defined.
An implementation shall allow both
  • a function of () returning int and
  • a function of (int, pointer to pointer to char) returning int
as the type of main ([dcl.fct]).
In the latter form, for purposes of exposition, the first function parameter is called argc and the second function parameter is called argv, where argc shall be the number of arguments passed to the program from the environment in which the program is run.
If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (ntmbs s) ([multibyte.strings]) and argv[0] shall be the pointer to the initial character of a ntmbs that represents the name used to invoke the program or "".
The value of argc shall be non-negative.
The value of argv[argc] shall be 0.
[Note
:
It is recommended that any further (optional) parameters be added after argv.
end note
]
The function main shall not be used within a program.
The linkage ([basic.link]) of main is implementation-defined.
A program that defines main as deleted or that declares main to be inline, static, or constexpr is ill-formed.
The main function shall not be declared with a linkage-specification.
A program that declares a variable main at global scope or that declares the name main with C language linkage (in any namespace) is ill-formed.
The name main is not otherwise reserved.
[Example
:
Member functions, classes, and enumerations can be called main, as can entities in other namespaces.
end example
]
Terminating the program without leaving the current block (e.g., by calling the function std​::​exit(int) ([support.start.term])) does not destroy any objects with automatic storage duration ([class.dtor]).
If std​::​exit is called to end a program during the destruction of an object with static or thread storage duration, the program has undefined behavior.
A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std​::​exit with the return value as the argument.
If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0 (see also [except.handle]).

6.6.2 Static initialization [basic.start.static]

Variables with static storage duration are initialized as a consequence of program initiation.
Variables with thread storage duration are initialized as a consequence of thread execution.
Within each of these phases of initiation, initialization occurs as follows.
A constant initializer for a variable or temporary object o is an initializer whose full-expression is a constant expression, except that if o is an object, such an initializer may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types.
[Note
:
Such a class may have a non-trivial destructor.
end note
]
Constant initialization is performed if a variable or temporary object with static or thread storage duration is initialized by a constant initializer for the entity.
If constant initialization is not performed, a variable with static storage duration ([basic.stc.static]) or thread storage duration ([basic.stc.thread]) is zero-initialized ([dcl.init]).
Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization.
All static initialization strongly happens before ([intro.races]) any dynamic initialization.
[Note
:
The dynamic initialization of non-local variables is described in [basic.start.dynamic]; that of local static variables is described in [stmt.dcl].
end note
]
An implementation is permitted to perform the initialization of a variable with static or thread storage duration as a static initialization even if such initialization is not required to be done statically, provided that
  • the dynamic version of the initialization does not change the value of any other object of static or thread storage duration prior to its initialization, and
  • the static version of the initialization produces the same value in the initialized variable as would be produced by the dynamic initialization if all variables not required to be initialized statically were initialized dynamically.
[Note
:
As a consequence, if the initialization of an object obj1 refers to an object obj2 of namespace scope potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value of obj2 used will be the value of the fully initialized obj2 (because obj2 was statically initialized) or will be the value of obj2 merely zero-initialized.
For example,
inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;     // unspecified:
                    // may be statically initialized to 0.0 or
                    // dynamically initialized to 0.0 if d1 is
                    // dynamically initialized, or 1.0 otherwise
double d1 = fd();   // may be initialized statically or dynamically to 1.0
end note
]

6.6.3 Dynamic initialization of non-local variables [basic.start.dynamic]

Dynamic initialization of a non-local variable with static storage duration is unordered if the variable is an implicitly or explicitly instantiated specialization, is partially-ordered if the variable is an inline variable that is not an implicitly or explicitly instantiated specialization, and otherwise is ordered.
[Note
:
An explicitly specialized non-inline static data member or variable template specialization has ordered initialization.
end note
]
Dynamic initialization of non-local variables V and W with static storage duration are ordered as follows:
  • If V and W have ordered initialization and V is defined before W within a single translation unit, the initialization of V is sequenced before the initialization of W.
  • If V has partially-ordered initialization, W does not have unordered initialization, and V is defined before W in every translation unit in which W is defined, then
    • if the program starts a thread ([intro.multithread]) other than the main thread ([basic.start.main]), the initialization of V strongly happens before the initialization of W;
    • otherwise, the initialization of V is sequenced before the initialization of W.
  • Otherwise, if the program starts a thread other than the main thread before either V or W is initialized, it is unspecified in which threads the initializations of V and W occur; the initializations are unsequenced if they occur in the same thread.
  • Otherwise, the initializations of V and W are indeterminately sequenced.
[Note
:
This definition permits initialization of a sequence of ordered variables concurrently with another sequence.
end note
]
A non-initialization odr-use is an odr-use ([basic.def.odr]) not caused directly or indirectly by the initialization of a non-local static or thread storage duration variable.
It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with static storage duration is sequenced before the first statement of main or is deferred.
If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized.36
It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.
[Note
:
Such points should be chosen in a way that allows the programmer to avoid deadlocks.
end note
]
[Example
:
// - File 1 -
#include "a.h"
#include "b.h"
B b;
A::A(){
  b.Use();
}

// - File 2 -
#include "a.h"
A a;

// - File 3 -
#include "a.h"
#include "b.h"
extern A a;
extern B b;

int main() {
  a.Use();
  b.Use();
}
It is implementation-defined whether either a or b is initialized before main is entered or whether the initializations are delayed until a is first odr-used in main.
In particular, if a is initialized before main is entered, it is not guaranteed that b will be initialized before it is odr-used by the initialization of a, that is, before A​::​A is called.
If, however, a is initialized at some point after the first statement of main, b will be initialized prior to its use in A​::​A.
end example
]
It is implementation-defined whether the dynamic initialization of a non-local inline variable with static storage duration is sequenced before the first statement of main or is deferred.
If it is deferred, it strongly happens before any non-initialization odr-use of that variable.
It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.
It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with thread storage duration is sequenced before the first statement of the initial function of a thread or is deferred.
If it is deferred, the initialization associated with the entity for thread t is sequenced before the first non-initialization odr-use by t of any non-inline variable with thread storage duration defined in the same translation unit as the variable to be initialized.
It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.
If the initialization of a non-local variable with static or thread storage duration exits via an exception, std​::​terminate is called ([except.terminate]).
A non-local variable with static storage duration having initialization with side effects is initialized in this case, even if it is not itself odr-used ([basic.def.odr], [basic.stc.static]).

6.6.4 Termination [basic.start.term]

Destructors ([class.dtor]) for initialized objects (that is, objects whose lifetime ([basic.life]) has begun) with static storage duration, and functions registered with std​::​atexit, are called as part of a call to std​::​exit ([support.start.term]).
The call to std​::​exit is sequenced before the invocations of the destructors and the registered functions.
[Note
:
Returning from main invokes std​::​exit ([basic.start.main]).
end note
]
Destructors for initialized objects with thread storage duration within a given thread are called as a result of returning from the initial function of that thread and as a result of that thread calling std​::​exit.
The completions of the destructors for all initialized objects with thread storage duration within that thread strongly happen before the initiation of the destructors of any object with static storage duration.
If the completion of the constructor or dynamic initialization of an object with static storage duration strongly happens before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.
If the completion of the constructor or dynamic initialization of an object with thread storage duration is sequenced before that of another, the completion of the destructor of the second is sequenced before the initiation of the destructor of the first.
If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized.
For an object of array or class type, all subobjects of that object are destroyed before any block-scope object with static storage duration initialized during the construction of the subobjects is destroyed.
If the destruction of an object with static or thread storage duration exits via an exception, std​::​terminate is called ([except.terminate]).
If a function contains a block-scope object of static or thread storage duration that has been destroyed and the function is called during the destruction of an object with static or thread storage duration, the program has undefined behavior if the flow of control passes through the definition of the previously destroyed block-scope object.
Likewise, the behavior is undefined if the block-scope object is used indirectly (i.e., through a pointer) after its destruction.
If the completion of the initialization of an object with static storage duration strongly happens before a call to std​::​atexit (see <cstdlib>, [support.start.term]), the call to the function passed to std​::​atexit is sequenced before the call to the destructor for the object.
If a call to std​::​atexit strongly happens before the completion of the initialization of an object with static storage duration, the call to the destructor for the object is sequenced before the call to the function passed to std​::​atexit.
If a call to std​::​atexit strongly happens before another call to std​::​atexit, the call to the function passed to the second std​::​atexit call is sequenced before the call to the function passed to the first std​::​atexit call.
If there is a use of a standard library object or function not permitted within signal handlers ([support.runtime]) that does not happen before ([intro.multithread]) completion of destruction of objects with static storage duration and execution of std​::​atexit registered functions ([support.start.term]), the program has undefined behavior.
[Note
:
If there is a use of an object with static storage duration that does not happen before the object's destruction, the program has undefined behavior.
Terminating every thread before a call to std​::​exit or the exit from main is sufficient, but not necessary, to satisfy these requirements.
These requirements permit thread managers as static-storage-duration objects.
end note
]
Calling the function std​::​abort() declared in <cstdlib> terminates the program without executing any destructors and without calling the functions passed to std​::​atexit() or std​::​at_­quick_­exit().

6.7 Storage duration [basic.stc]

The storage duration is the property of an object that defines the minimum potential lifetime of the storage containing the object.
The storage duration is determined by the construct used to create the object and is one of the following:
  • static storage duration
  • thread storage duration
  • automatic storage duration
  • dynamic storage duration
Static, thread, and automatic storage durations are associated with objects introduced by declarations ([basic.def]) and implicitly created by the implementation ([class.temporary]).
The dynamic storage duration is associated with objects created by a new-expression.
The storage duration categories apply to references as well.
When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values ([basic.compound]).
Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior.
Any other use of an invalid pointer value has implementation-defined behavior.37
Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault.

6.7.1 Static storage duration [basic.stc.static]

All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration.
The storage for these entities shall last for the duration of the program ([basic.start.static], [basic.start.term]).
If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in [class.copy].
The keyword static can be used to declare a local variable with static storage duration.
[Note
:
[stmt.dcl] describes the initialization of local static variables; [basic.start.term] describes the destruction of local static variables.
end note
]
The keyword static applied to a class data member in a class definition gives the data member static storage duration.

6.7.2 Thread storage duration [basic.stc.thread]

All variables declared with the thread_­local keyword have thread storage duration.
The storage for these entities shall last for the duration of the thread in which they are created.
There is a distinct object or reference per thread, and use of the declared name refers to the entity associated with the current thread.
A variable with thread storage duration shall be initialized before its first odr-use ([basic.def.odr]) and, if constructed, shall be destroyed on thread exit.

6.7.3 Automatic storage duration [basic.stc.auto]

Block-scope variables not explicitly declared static, thread_­local, or extern have automatic storage duration.
The storage for these entities lasts until the block in which they are created exits.
[Note
:
These variables are initialized and destroyed as described in [stmt.dcl].
end note
]
If a variable with automatic storage duration has initialization or a destructor with side effects, an implementation shall not destroy it before the end of its block nor eliminate it as an optimization, even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in [class.copy].

6.7.4 Dynamic storage duration [basic.stc.dynamic]

Objects can be created dynamically during program execution ([intro.execution]), using new-expressions, and destroyed using delete-expressions.
A C++ implementation provides access to, and management of, dynamic storage via the global allocation functions operator new and operator new[] and the global deallocation functions operator delete and operator delete[].
[Note
:
The non-allocating forms described in [new.delete.placement] do not perform allocation or deallocation.
end note
]
The library provides default definitions for the global allocation and deallocation functions.
Some global allocation and deallocation functions are replaceable ([new.delete]).
A C++ program shall provide at most one definition of a replaceable allocation or deallocation function.
Any such function definition replaces the default version provided in the library ([replacement.functions]).
The following allocation and deallocation functions ([support.dynamic]) are implicitly declared in global scope in each translation unit of a program.
void* operator new(std::size_t);
void* operator new(std::size_t, std::align_val_t);

void operator delete(void*) noexcept;
void operator delete(void*, std::size_t) noexcept;
void operator delete(void*, std::align_val_t) noexcept;
void operator delete(void*, std::size_t, std::align_val_t) noexcept;

void* operator new[](std::size_t);
void* operator new[](std::size_t, std::align_val_t);

void operator delete[](void*) noexcept;
void operator delete[](void*, std::size_t) noexcept;
void operator delete[](void*, std::align_val_t) noexcept;
void operator delete[](void*, std::size_t, std::align_val_t) noexcept;
These implicit declarations introduce only the function names operator new, operator new[], operator delete, and operator delete[].
[Note
:
The implicit declarations do not introduce the names std, std​::​size_­t, std​::​align_­val_­t, or any other names that the library uses to declare these names.
Thus, a new-expression, delete-expression or function call that refers to one of these functions without including the header <new> is well-formed.
However, referring to std or std​::​size_­t or std​::​align_­val_­t is ill-formed unless the name has been declared by including the appropriate header.
end note
]
Allocation and/or deallocation functions may also be declared and defined for any class ([class.free]).
Any allocation and/or deallocation functions defined in a C++ program, including the default versions in the library, shall conform to the semantics specified in [basic.stc.dynamic.allocation] and [basic.stc.dynamic.deallocation].

6.7.4.1 Allocation functions [basic.stc.dynamic.allocation]

An allocation function shall be a class member function or a global function; a program is ill-formed if an allocation function is declared in a namespace scope other than global scope or declared static in global scope.
The return type shall be void*.
The first parameter shall have type std​::​size_­t ([support.types]).
The first parameter shall not have an associated default argument ([dcl.fct.default]).
The value of the first parameter shall be interpreted as the requested size of the allocation.
An allocation function can be a function template.
Such a template shall declare its return type and first parameter as specified above (that is, template parameter types shall not be used in the return type and first parameter type).
Template allocation functions shall have two or more parameters.
The allocation function attempts to allocate the requested amount of storage.
If it is successful, it shall return the address of the start of a block of storage whose length in bytes shall be at least as large as the requested size.
There are no constraints on the contents of the allocated storage on return from the allocation function.
The order, contiguity, and initial value of storage allocated by successive calls to an allocation function are unspecified.
The pointer returned shall be suitably aligned so that it can be converted to a pointer to any suitable complete object type ([new.delete.single]) and then used to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to a corresponding deallocation function).
Even if the size of the space requested is zero, the request can fail.
If the request succeeds, the value returned shall be a non-null pointer value ([conv.ptr]) p0 different from any previously returned value p1, unless that value p1 was subsequently passed to an operator delete.
Furthermore, for the library allocation functions in [new.delete.single] and [new.delete.array], p0 shall represent the address of a block of storage disjoint from the storage for any other object accessible to the caller.
The effect of indirecting through a pointer returned as a request for zero size is undefined.38
An allocation function that fails to allocate storage can invoke the currently installed new-handler function ([new.handler]), if any.
[Note
:
A program-supplied allocation function can obtain the address of the currently installed new_­handler using the std​::​get_­new_­handler function ([set.new.handler]).
end note
]
If an allocation function that has a non-throwing exception specification ([except.spec]) fails to allocate storage, it shall return a null pointer.
Any other allocation function that fails to allocate storage shall indicate failure only by throwing an exception ([except.throw]) of a type that would match a handler ([except.handle]) of type std​::​bad_­alloc ([bad.alloc]).
A global allocation function is only called as the result of a new expression ([expr.new]), or called directly using the function call syntax ([expr.call]), or called indirectly through calls to the functions in the C++ standard library.
[Note
:
In particular, a global allocation function is not called to allocate storage for objects with static storage duration ([basic.stc.static]), for objects or references with thread storage duration ([basic.stc.thread]), for objects of type std​::​type_­info ([expr.typeid]), or for an exception object ([except.throw]).
end note
]
The intent is to have operator new() implementable by calling std​::​malloc() or std​::​calloc(), so the rules are substantially the same.
C++ differs from C in requiring a zero request to return a non-null pointer.

6.7.4.2 Deallocation functions [basic.stc.dynamic.deallocation]

Deallocation functions shall be class member functions or global functions; a program is ill-formed if deallocation functions are declared in a namespace scope other than global scope or declared static in global scope.
Each deallocation function shall return void and its first parameter shall be void*.
A deallocation function may have more than one parameter.
A usual deallocation function is a deallocation function that has:
  • exactly one parameter; or
  • exactly two parameters, the type of the second being either std​::​align_­val_­t or std​::​size_­t39; or
  • exactly three parameters, the type of the second being std​::​size_­t and the type of the third being std​::​align_­val_­t.
A deallocation function may be an instance of a function template.
Neither the first parameter nor the return type shall depend on a template parameter.
[Note
:
That is, a deallocation function template shall have a first parameter of type void* and a return type of void (as specified above).
end note
]
A deallocation function template shall have two or more function parameters.
A template instance is never a usual deallocation function, regardless of its signature.
If a deallocation function terminates by throwing an exception, the behavior is undefined.
The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect.
If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value ([conv.ptr]), the deallocation function shall deallocate the storage referenced by the pointer, ending the duration of the region of storage.
The global operator delete(void*, std​::​size_­t) precludes use of an allocation function void operator new(std​::​size_­t, std​::​size_­t) as a placement allocation function ([diff.cpp11.basic]).

6.7.4.3 Safely-derived pointers [basic.stc.dynamic.safety]

A traceable pointer object is
  • an object of an object pointer type ([basic.compound]), or
  • an object of an integral type that is at least as large as std​::​intptr_­t, or
  • a sequence of elements in an array of narrow character type ([basic.fundamental]), where the size and alignment of the sequence match those of some object pointer type.
A pointer value is a safely-derived pointer to a dynamic object only if it has an object pointer type and it is one of the following:
  • the value returned by a call to the C++ standard library implementation of ​::​operator new(std​::​​size_­t) or ​::​operator new(std​::​size_­t, std​::​align_­val_­t);40
  • the result of taking the address of an object (or one of its subobjects) designated by an lvalue resulting from indirection through a safely-derived pointer value;
  • the result of well-defined pointer arithmetic ([expr.add]) using a safely-derived pointer value;
  • the result of a well-defined pointer conversion ([conv.ptr], [expr.cast]) of a safely-derived pointer value;
  • the result of a reinterpret_­cast of a safely-derived pointer value;
  • the result of a reinterpret_­cast of an integer representation of a safely-derived pointer value;
  • the value of an object whose value was copied from a traceable pointer object, where at the time of the copy the source object contained a copy of a safely-derived pointer value.
An integer value is an integer representation of a safely-derived pointer only if its type is at least as large as std​::​intptr_­t and it is one of the following:
  • the result of a reinterpret_­cast of a safely-derived pointer value;
  • the result of a valid conversion of an integer representation of a safely-derived pointer value;
  • the value of an object whose value was copied from a traceable pointer object, where at the time of the copy the source object contained an integer representation of a safely-derived pointer value;
  • the result of an additive or bitwise operation, one of whose operands is an integer representation of a safely-derived pointer value P, if that result converted by reinterpret_­cast<void*> would compare equal to a safely-derived pointer computable from reinterpret_­cast<void*>(P).
An implementation may have relaxed pointer safety, in which case the validity of a pointer value does not depend on whether it is a safely-derived pointer value.
Alternatively, an implementation may have strict pointer safety, in which case a pointer value referring to an object with dynamic storage duration that is not a safely-derived pointer value is an invalid pointer value unless the referenced complete object has previously been declared reachable ([util.dynamic.safety]).
[Note
:
The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined, see [basic.stc.dynamic.deallocation].
This is true even if the unsafely-derived pointer value might compare equal to some safely-derived pointer value.
end note
]
It is implementation-defined whether an implementation has relaxed or strict pointer safety.
This section does not impose restrictions on indirection through pointers to memory not allocated by ​::​operator new.
This maintains the ability of many C++ implementations to use binary libraries and components written in other languages.
In particular, this applies to C binaries, because indirection through pointers to memory allocated by std​::​malloc is not restricted.

6.7.5 Duration of subobjects [basic.stc.inherit]

The storage duration of subobjects and reference members is that of their complete object ([intro.object]).

6.8 Object lifetime [basic.life]

The lifetime of an object or reference is a runtime property of the object or reference.
An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor.
[Note
:
Initialization by a trivial copy/move constructor is non-vacuous initialization.
end note
]
The lifetime of an object of type T begins when:
  • storage with the proper alignment and size for type T is obtained, and
  • if the object has non-vacuous initialization, its initialization is complete,
except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union ([dcl.init.aggr], [class.base.init]), or as described in [class.union].
The lifetime of an object o of type T ends when:
  • if T is a class type with a non-trivial destructor ([class.dtor]), the destructor call starts, or
  • the storage which the object occupies is released, or is reused by an object that is not nested within o ([intro.object]).
The lifetime of a reference begins when its initialization is complete.
The lifetime of a reference ends as if it were a scalar object.
[Note
:
[class.base.init] describes the lifetime of base and member subobjects.
end note
]
The properties ascribed to objects and references throughout this International Standard apply for a given object or reference only during its lifetime.
[Note
:
In particular, before the lifetime of an object starts and after its lifetime ends there are significant restrictions on the use of the object, as described below, in [class.base.init] and in [class.cdtor].
Also, the behavior of an object under construction and destruction might not be the same as the behavior of an object whose lifetime has started and not ended.
[class.base.init] and [class.cdtor] describe the behavior of objects during the construction and destruction phases.
end note
]
A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor.
For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.
Before the lifetime of an object has started but after the storage which the object will occupy has been allocated41 or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways.
For an object under construction or destruction, see [class.cdtor].
Otherwise, such a pointer refers to allocated storage ([basic.stc.dynamic.deallocation]), and using the pointer as if the pointer were of type void*, is well-defined.
Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below.
The program has undefined behavior if:
  • the object will be or was of a class type with a non-trivial destructor and the pointer is used as the operand of a delete-expression,
  • the pointer is used to access a non-static data member or call a non-static member function of the object, or
  • the pointer is implicitly converted ([conv.ptr]) to a pointer to a virtual base class, or
  • the pointer is used as the operand of a static_­cast ([expr.static.cast]), except when the conversion is to pointer to cv void, or to pointer to cv void and subsequently to pointer to cv char, cv unsigned char, or cv std​::​byte ([cstddef.syn]), or
  • the pointer is used as the operand of a dynamic_­cast ([expr.dynamic.cast]).
[Example
:
#include <cstdlib>

struct B {
  virtual void f();
  void mutate();
  virtual ~B();
};

struct D1 : B { void f(); };
struct D2 : B { void f(); };

void B::mutate() {
  new (this) D2;    // reuses storage — ends the lifetime of *this
  f();              // undefined behavior
  ... = this;       // OK, this points to valid memory
}

void g() {
  void* p = std::malloc(sizeof(D1) + sizeof(D2));
  B* pb = new (p) D1;
  pb->mutate();
  *pb;              // OK: pb points to valid memory
  void* q = pb;     // OK: pb points to valid memory
  pb->f();          // undefined behavior, lifetime of *pb has ended
}
end example
]
Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways.
For an object under construction or destruction, see [class.cdtor].
Otherwise, such a glvalue refers to allocated storage ([basic.stc.dynamic.deallocation]), and using the properties of the glvalue that do not depend on its value is well-defined.
The program has undefined behavior if:
  • the glvalue is used to access the object, or
  • the glvalue is used to call a non-static member function of the object, or
  • the glvalue is bound to a reference to a virtual base class ([dcl.init.ref]), or
  • the glvalue is used as the operand of a dynamic_­cast ([expr.dynamic.cast]) or as the operand of typeid.
If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:
  • the storage for the new object exactly overlays the storage location which the original object occupied, and
  • the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
  • the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
  • the original object was a most derived object ([intro.object]) of type T and the new object is a most derived object of type T (that is, they are not base class subobjects).
[Example
:
struct C {
  int i;
  void f();
  const C& operator=( const C& );
};

const C& C::operator=( const C& other) {
  if ( this != &other ) {
    this->~C();                 // lifetime of *this ends
    new (this) C(other);        // new object of type C created
    f();                        // well-defined
  }
  return *this;
}

C c1;
C c2;
c1 = c2;                        // well-defined
c1.f();                         // well-defined; c1 refers to a new object of type C
end example
]
[Note
:
If these conditions are not met, a pointer to the new object can be obtained from a pointer that represents the address of its storage by calling std​::​launder ([support.dynamic]).
end note
]
If a program ends the lifetime of an object of type T with static ([basic.stc.static]), thread ([basic.stc.thread]), or automatic ([basic.stc.auto]) storage duration and if T has a non-trivial destructor,42 the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined.
This is true even if the block is exited with an exception.
[Example
:
class T { };
struct B {
   ~B();
};

void h() {
   B b;
   new (&b) T;
}                               // undefined behavior at block exit
end example
]
Creating a new object within the storage that a const complete object with static, thread, or automatic storage duration occupies, or within the storage that such a const object used to occupy before its lifetime ended, results in undefined behavior.
[Example
:
struct B {
  B();
  ~B();
};

const B b;

void h() {
  b.~B();
  new (const_cast<B*>(&b)) const B;     // undefined behavior
}
end example
]
In this section, “before” and “after” refer to the “happens before” relation ([intro.multithread]).
[Note
:
Therefore, undefined behavior results if an object that is being constructed in one thread is referenced from another thread without adequate synchronization.
end note
]
For example, before the construction of a global object of non-POD class type ([class.cdtor]).
That is, an object for which a destructor will be called implicitly—upon exit from the block for an object with automatic storage duration, upon exit from the thread for an object with thread storage duration, or upon exit from the program for an object with static storage duration.

6.9 Types [basic.types]

[Note
:
[basic.types] and the subclauses thereof impose requirements on implementations regarding the representation of types.
There are two kinds of types: fundamental types and compound types.
Types describe objects ([intro.object]), references ([dcl.ref]), or functions ([dcl.fct]).
end note
]
For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes ([intro.memory]) making up the object can be copied into an array of char, unsigned char, or std​::​byte ([cstddef.syn]).43
If the content of that array is copied back into the object, the object shall subsequently hold its original value.
[Example
:
#define N sizeof(T)
char buf[N];
T obj;                          // obj initialized to its original value
std::memcpy(buf, &obj, N);      // between these two calls to std​::​memcpy, obj might be modified
std::memcpy(&obj, buf, N);      // at this point, each subobject of obj of scalar type holds its original value
end example
]
For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the underlying bytes ([intro.memory]) making up obj1 are copied into obj2,44 obj2 shall subsequently hold the same value as obj1.
[Example
:
T* t1p;
T* t2p;
    // provided that t2p points to an initialized object ...
std::memcpy(t1p, t2p, sizeof(T));
    // at this point, every subobject of trivially copyable type in *t1p contains
    // the same value as the corresponding subobject in *t2p
end example
]
The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T).
The value representation of an object is the set of bits that hold the value of type T.
For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values.45
A class that has been declared but not defined, an enumeration type in certain contexts ([dcl.enum]), or an array of unknown bound or of incomplete element type, is an incompletely-defined object type.46
Incompletely-defined object types and cv void are incomplete types ([basic.fundamental]).
Objects shall not be defined to have an incomplete type.
A class type (such as “class X”) might be incomplete at one point in a translation unit and complete later on; the type “class X” is the same type at both points.
The declared type of an array object might be an array of incomplete class type and therefore incomplete; if the class type is completed later on in the translation unit, the array type becomes complete; the array type at those two points is the same type.
The declared type of an array object might be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points (“array of unknown bound of T” and “array of N T”) are different types.
The type of a pointer to array of unknown bound, or of a type defined by a typedef declaration to be an array of unknown bound, cannot be completed.
[Example
:
class X;                        // X is an incomplete type
extern X* xp;                   // xp is a pointer to an incomplete type
extern int arr[];               // the type of arr is incomplete
typedef int UNKA[];             // UNKA is an incomplete type
UNKA* arrp;                     // arrp is a pointer to an incomplete type
UNKA** arrpp;

void foo() {
  xp++;                         // ill-formed: X is incomplete
  arrp++;                       // ill-formed: incomplete type
  arrpp++;                      // OK: sizeof UNKA* is known
}

struct X { int i; };            // now X is a complete type
int  arr[10];                   // now the type of arr is complete

X x;
void bar() {
  xp = &x;                      // OK; type is “pointer to X  arrp = &arr;                  // ill-formed: different types
  xp++;                         // OK:  X is complete
  arrp++;                       // ill-formed: UNKA can't be completed
}
end example
]
[Note
:
The rules for declarations and expressions describe in which contexts incomplete types are prohibited.
end note
]
An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not cv void.
Arithmetic types ([basic.fundamental]), enumeration types, pointer types, pointer to member types ([basic.compound]), std​::​nullptr_­t, and cv-qualified ([basic.type.qualifier]) versions of these types are collectively called scalar types.
Scalar types, POD classes (Clause [class]), arrays of such types and cv-qualified versions of these types are collectively called POD types.
Cv-unqualified scalar types, trivially copyable class types (Clause [class]), arrays of such types, and cv-qualified versions of these types are collectively called trivially copyable types.
Scalar types, trivial class types (Clause [class]), arrays of such types and cv-qualified versions of these types are collectively called trivial types.
Scalar types, standard-layout class types (Clause [class]), arrays of such types and cv-qualified versions of these types are collectively called standard-layout types.
A type is a literal type if it is:
  • possibly cv-qualified void; or
  • a scalar type; or
  • a reference type; or
  • an array of literal type; or
  • a possibly cv-qualified class type (Clause [class]) that has all of the following properties:
    • it has a trivial destructor,
    • it is either a closure type ([expr.prim.lambda.closure]), an aggregate type ([dcl.init.aggr]), or has at least one constexpr constructor or constructor template (possibly inherited ([namespace.udecl]) from a base class) that is not a copy or move constructor,
    • if it is a union, at least one of its non-static data members is of non-volatile literal type, and
    • if it is not a union, all of its non-static data members and base classes are of non-volatile literal types.
[Note
:
A literal type is one for which it might be possible to create an object within a constant expression.
It is not a guarantee that it is possible to create such an object, nor is it a guarantee that any object of that type will usable in a constant expression.
end note
]
Two types cv1 T1 and cv2 T2 are layout-compatible types if T1 and T2 are the same type, layout-compatible enumerations ([dcl.enum]), or layout-compatible standard-layout class types ([class.mem]).
By using, for example, the library functions ([headers]) std​::​memcpy or std​::​memmove.
By using, for example, the library functions ([headers]) std​::​memcpy or std​::​memmove.
The intent is that the memory model of C++ is compatible with that of ISO/IEC 9899 Programming Language C.
The size and layout of an instance of an incompletely-defined object type is unknown.

6.9.1 Fundamental types [basic.fundamental]

Objects declared as characters (char) shall be large enough to store any member of the implementation's basic character set.
If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character.
It is implementation-defined whether a char object can hold negative values.
Characters can be explicitly declared unsigned or signed.
Plain char, signed char, and unsigned char are three distinct types, collectively called narrow character types.
A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements ([basic.align]); that is, they have the same object representation.
For narrow character types, all bits of the object representation participate in the value representation.
[Note
:
A bit-field of narrow character type whose length is larger than the number of bits in the object representation of that type has padding bits; see [class.bit].
end note
]
For unsigned narrow character types, each possible bit pattern of the value representation represents a distinct number.
These requirements do not hold for other types.
In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.
For each value i of type unsigned char in the range 0 to 255 inclusive, there exists a value j of type char such that the result of an integral conversion ([conv.integral]) from i to char is j, and the result of an integral conversion from j to unsigned char is i.
There are five standard signed integer types : signed char”, “short int”, “int”, “long int”, and “long long int.
In this list, each type provides at least as much storage as those preceding it in the list.
There may also be implementation-defined extended signed integer types.
The standard and extended signed integer types are collectively called signed integer types.
Plain ints have the natural size suggested by the architecture of the execution environment47; the other signed integer types are provided to meet special needs.
For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”, and “unsigned long long int”, each of which occupies the same amount of storage and has the same alignment requirements ([basic.align]) as the corresponding signed integer type48; that is, each signed integer type has the same object representation as its corresponding unsigned integer type.
Likewise, for each of the extended signed integer types there exists a corresponding extended unsigned integer type with the same amount of storage and alignment requirements.
The standard and extended unsigned integer types are collectively called unsigned integer types.
The range of non-negative values of a signed integer type is a subrange of the corresponding unsigned integer type, the representation of the same value in each of the two types is the same, and the value representation of each corresponding signed/unsigned type shall be the same.
The standard signed integer types and standard unsigned integer types are collectively called the standard integer types, and the extended signed integer types and extended unsigned integer types are collectively called the extended integer types.
The signed and unsigned integer types shall satisfy the constraints given in the C standard, section 5.
2.
4.
2.
1.
Unsigned integers shall obey the laws of arithmetic modulo where n is the number of bits in the value representation of that particular size of integer.49
Type wchar_­t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales ([locale]).
Type wchar_­t shall have the same size, signedness, and alignment requirements ([basic.align]) as one of the other integral types, called its underlying type.
Types char16_­t and char32_­t denote distinct types with the same size, signedness, and alignment as uint_­least16_­t and uint_­least32_­t, respectively, in <cstdint>, called the underlying types.
Values of type bool are either true or false.50
[Note
:
There are no signed, unsigned, short, or long bool types or values.
end note
]
Values of type bool participate in integral promotions ([conv.prom]).
Types bool, char, char16_­t, char32_­t, wchar_­t, and the signed and unsigned integer types are collectively called integral types.51
A synonym for integral type is integer type.
The representations of integral types shall define values by use of a pure binary numeration system.52
[Example
:
This International Standard permits two's complement, ones' complement and signed magnitude representations for integral types.
end example
]
There are three floating-point types: float, double, and long double.
The type double provides at least as much precision as float, and the type long double provides at least as much precision as double.
The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double.
The value representation of floating-point types is implementation-defined.
[Note
:
This International Standard imposes no requirements on the accuracy of floating-point operations; see also [support.limits].
end note
]
Integral and floating types are collectively called arithmetic types.
Specializations of the standard library template std​::​numeric_­limits ([support.limits]) shall specify the maximum and minimum values of each arithmetic type for an implementation.
A type cv void is an incomplete type that cannot be completed; such a type has an empty set of values.
It is used as the return type for functions that do not return a value.
Any expression can be explicitly converted to type cv void ([expr.cast]).
An expression of type cv void shall be used only as an expression statement ([stmt.expr]), as an operand of a comma expression ([expr.comma]), as a second or third operand of ?: ([expr.cond]), as the operand of typeid, noexcept, or decltype, as the expression in a return statement ([stmt.return]) for a function with the return type cv void, or as the operand of an explicit conversion to type cv void.
A value of type std​::​nullptr_­t is a null pointer constant ([conv.ptr]).
Such values participate in the pointer and the pointer to member conversions ([conv.ptr], [conv.mem]).
sizeof(std​::​nullptr_­t) shall be equal to sizeof(void*).
[Note
:
Even if the implementation defines two or more basic types to have the same value representation, they are nevertheless different types.
end note
]
int must also be large enough to contain any value in the range [INT_­MIN, INT_­MAX], as defined in the header <climits>.
See [dcl.type.simple] regarding the correspondence between types and the sequences of type-specifiers that designate them.
This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.
Using a bool value in ways described by this International Standard as “undefined”, such as by examining the value of an uninitialized automatic object, might cause it to behave as if it is neither true nor false.
Therefore, enumerations ([dcl.enum]) are not integral; however, enumerations can be promoted to integral types as specified in [conv.prom].
A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position.
(Adapted from the American National Dictionary for Information Processing Systems.)

6.9.2 Compound types [basic.compound]

Compound types can be constructed in the following ways:
These methods of constructing types can be applied recursively; restrictions are mentioned in [dcl.ptr], [dcl.array], [dcl.fct], and [dcl.ref].
Constructing a type such that the number of bytes in its object representation exceeds the maximum value representable in the type std​::​size_­t ([support.types]) is ill-formed.
The type of a pointer to cv void or a pointer to an object type is called an object pointer type.
[Note
:
A pointer to void does not have a pointer-to-object type, however, because void is not an object type.
end note
]
The type of a pointer that can designate a function is called a function pointer type.
A pointer to objects of type T is referred to as a “pointer to T.
[Example
:
A pointer to an object of type int is referred to as “pointer to int” and a pointer to an object of class X is called a “pointer to X.
end example
]
Except for pointers to static members, text referring to “pointers” does not apply to pointers to members.
Pointers to incomplete types are allowed although there are restrictions on what can be done with them ([basic.align]).
Every value of pointer type is one of the following:
A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory ([intro.memory]) occupied by the object54 or the first byte in memory after the end of the storage occupied by the object, respectively.
[Note
:
A pointer past the end of an object ([expr.add]) is not considered to point to an unrelated object of the object's type that might be located at that address.
A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration; see [basic.stc].
end note
]
For purposes of pointer arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), a pointer past the end of the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical element x[n].
The value representation of pointer types is implementation-defined.
Pointers to layout-compatible types shall have the same value representation and alignment requirements ([basic.align]).
[Note
:
Pointers to over-aligned types ([basic.align]) have no special representation, but their range of valid values is restricted by the extended alignment requirement.
end note
]
Two objects a and b are pointer-interconvertible if:
  • they are the same object, or
  • one is a standard-layout union object and the other is a non-static data member of that object ([class.union]), or
  • one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, the first base class subobject of that object ([class.mem]), or
  • there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_­cast ([expr.reinterpret.cast]).
[Note
:
An array object and its first element are not pointer-interconvertible, even though they have the same address.
end note
]
A pointer to cv-qualified ([basic.type.qualifier]) or cv-unqualified void can be used to point to objects of unknown type.
Such a pointer shall be able to hold any object pointer.
An object of type cv void* shall have the same representation and alignment requirements as cv char*.
Static class members are objects or functions, and pointers to them are ordinary pointers to objects or functions.
For an object that is not within its lifetime, this is the first byte in memory that it will occupy or used to occupy.

6.9.3 CV-qualifiers [basic.type.qualifier]

Each type which is a cv-unqualified complete or incomplete object type or is void ([basic.types]) has three corresponding cv-qualified versions of its type: a const-qualified version, a volatile-qualified version, and a const-volatile-qualified version.
The type of an object ([intro.object]) includes the cv-qualifiers specified in the decl-specifier-seq, declarator, type-id, or new-type-id when the object is created.
  • A const object is an object of type const T or a non-mutable subobject of such an object.
  • A volatile object is an object of type volatile T, a subobject of such an object, or a mutable subobject of a const volatile object.
  • A const volatile object is an object of type const volatile T, a non-mutable subobject of such an object, a const subobject of a volatile object, or a non-mutable volatile subobject of a const object.
The cv-qualified or cv-unqualified versions of a type are distinct types; however, they shall have the same representation and alignment requirements ([basic.align]).55
A compound type ([basic.compound]) is not cv-qualified by the cv-qualifiers (if any) of the types from which it is compounded.
Any cv-qualifiers applied to an array type affect the array element type ([dcl.array]).
See [dcl.fct] and [class.this] regarding function types that have cv-qualifiers.
There is a partial ordering on cv-qualifiers, so that a type can be said to be more cv-qualified than another.
Table 10 shows the relations that constitute this ordering.
Table 10 — Relations on const and volatile
no cv-qualifier
<
const
no cv-qualifier
<
volatile
no cv-qualifier
<
const volatile
const
<
const volatile
volatile
<
const volatile
In this International Standard, the notation cv (or cv1, cv2, etc.)
, used in the description of types, represents an arbitrary set of cv-qualifiers, i.e., one of {const}, {volatile}, {const, volatile}, or the empty set.
For a type cv T, the top-level cv-qualifiers of that type are those denoted by cv.
[Example
:
The type corresponding to the type-id const int& has no top-level cv-qualifiers.
The type corresponding to the type-id volatile int * const has the top-level cv-qualifier const.
For a class type C, the type corresponding to the type-id void (C​::​* volatile)(int) const has the top-level cv-qualifier volatile.
end example
]
Cv-qualifiers applied to an array type attach to the underlying element type, so the notation “cv T”, where T is an array type, refers to an array whose elements are so-qualified.
An array type whose elements are cv-qualified is also considered to have the same cv-qualifications as its elements.
[Example
:
typedef char CA[5];
typedef const char CC;
CC arr1[5] = { 0 };
const CA arr2 = { 0 };
The type of both arr1 and arr2 is “array of 5 const char”, and the array type is considered to be const-qualified.
end example
]
The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and non-static data members of unions.

6.10 Lvalues and rvalues [basic.lval]

Expressions are categorized according to the taxonomy in Figure [fig:categories].
categories expression expression glvalue glvalue expression->glvalue rvalue rvalue expression->rvalue lvalue lvalue glvalue->lvalue xvalue xvalue glvalue->xvalue rvalue->xvalue prvalue prvalue rvalue->prvalue
Figure 1 — Expression category taxonomy
  • A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
  • A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
  • An xvalue is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime).
    [Example
    :
    Certain kinds of expressions involving rvalue references ([dcl.ref]) yield xvalues, such as a call to a function whose return type is an rvalue reference or a cast to an rvalue reference type.
    end example
    ]
  • An lvalue is a glvalue that is not an xvalue.
  • An rvalue is a prvalue or an xvalue.
[Note
:
Historically, lvalues and rvalues were so-called because they could appear on the left- and right-hand side of an assignment (although this is no longer generally true); glvalues are “generalized” lvalues, prvalues are “pure” rvalues, and xvalues are “eXpiring” lvalues.
Despite their names, these terms classify expressions, not values.
end note
]
Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue.
This property of an expression is called its value category.
[Note
:
The discussion of each built-in operator in Clause [expr] indicates the category of the value it yields and the value categories of the operands it expects.
For example, the built-in assignment operators expect that the left operand is an lvalue and that the right operand is a prvalue and yield an lvalue as the result.
User-defined operators are functions, and the categories of values they expect and yield are determined by their parameter and return types.
end note
]
The result of a prvalue is the value that the expression stores into its context.
A prvalue whose result is the value V is sometimes said to have or name the value V.
The result object of a prvalue is the object initialized by the prvalue; a prvalue that is used to compute the value of an operand of an operator or that has type cv void has no result object.
[Note
:
Except when the prvalue is the operand of a decltype-specifier, a prvalue of class or array type always has a result object.
For a discarded prvalue, a temporary object is materialized; see Clause [expr].
end note
]
The result of a glvalue is the entity denoted by the expression.
[Note
:
Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted to a prvalue; see [conv.lval], [conv.array], and [conv.func].
An attempt to bind an rvalue reference to an lvalue is not such a context; see [dcl.init.ref].
end note
]
[Note
:
There are no prvalue bit-fields; if a bit-field is converted to a prvalue ([conv.lval]), a prvalue of the type of the bit-field is created, which might then be promoted ([conv.prom]).
end note
]
[Note
:
Whenever a prvalue appears in a context where a glvalue is expected, the prvalue is converted to an xvalue; see [conv.rval].
end note
]
The discussion of reference initialization in [dcl.init.ref] and of temporaries in [class.temporary] indicates the behavior of lvalues and rvalues in other significant contexts.
Unless otherwise indicated ([expr.call]), a prvalue shall always have complete type or the void type.
A glvalue shall not have type cv void.
[Note
:
A glvalue may have complete or incomplete non-void type.
Class and array prvalues can have cv-qualified types; other prvalues always have cv-unqualified types.
See Clause [expr].
end note
]
An lvalue is modifiable unless its type is const-qualified or is a function type.
[Note
:
A program that attempts to modify an object through a nonmodifiable lvalue expression or through an rvalue expression is ill-formed ([expr.ass], [expr.post.incr], [expr.pre.incr]).
end note
]
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:56
  • the dynamic type of the object,
  • a cv-qualified version of the dynamic type of the object,
  • a type similar (as defined in [conv.qual]) to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
  • a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
  • a char, unsigned char, or std​::​byte type.
The intent of this list is to specify those circumstances in which an object may or may not be aliased.

6.11 Alignment [basic.align]

Object types have alignment requirements ([basic.fundamental], [basic.compound]) which place restrictions on the addresses at which an object of that type may be allocated.
An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated.
An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier ([dcl.align]).
A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to alignof(std​::​max_­align_­t) ([support.types]).
The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject.
[Example
:
struct B { long double d; };
struct D : virtual B { char c; };
When D is the type of a complete object, it will have a subobject of type B, so it must be aligned appropriately for a long double.
If D appears as a subobject of another object that also has B as a virtual base class, the B subobject might be part of a different subobject, reducing the alignment requirements on the D subobject.
end example
]
The result of the alignof operator reflects the alignment requirement of the type in the complete-object case.
An extended alignment is represented by an alignment greater than alignof(std​::​max_­align_­t).
It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported ([dcl.align]).
A type having an extended alignment requirement is an over-aligned type.
[Note
:
Every over-aligned type is or contains a class type to which extended alignment applies (possibly through a non-static data member).
end note
]
A new-extended alignment is represented by an alignment greater than __STDCPP_­DEFAULT_­NEW_­ALIGNMENT__ ([cpp.predefined]).
Alignments are represented as values of the type std​::​size_­t.
Valid alignments include only those values returned by an alignof expression for the fundamental types plus an additional implementation-defined set of values, which may be empty.
Every alignment value shall be a non-negative integral power of two.
Alignments have an order from weaker to stronger or stricter alignments.
Stricter alignments have larger alignment values.
An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.
The alignment requirement of a complete type can be queried using an alignof expression ([expr.alignof]).
Furthermore, the narrow character types ([basic.fundamental]) shall have the weakest alignment requirement.
[Note
:
This enables the narrow character types to be used as the underlying type for an aligned memory area ([dcl.align]).
end note
]
Comparing alignments is meaningful and provides the obvious results:
  • Two alignments are equal when their numeric values are equal.
  • Two alignments are different when their numeric values are not equal.
  • When an alignment is larger than another it represents a stricter alignment.
[Note
:
The runtime pointer alignment function ([ptr.align]) can be used to obtain an aligned pointer within a buffer; the aligned-storage templates in the library ([meta.trans.other]) can be used to obtain aligned storage.
end note
]
If a request for a specific extended alignment in a specific context is not supported by an implementation, the program is ill-formed.

7 Standard conversions [conv]

Standard conversions are implicit conversions with built-in meaning.
Clause [conv] enumerates the full set of such conversions.
A standard conversion sequence is a sequence of standard conversions in the following order:
  • Zero or one conversion from the following set: lvalue-to-rvalue conversion, array-to-pointer conversion, and function-to-pointer conversion.
  • Zero or one conversion from the following set: integral promotions, floating-point promotion, integral conversions, floating-point conversions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions.
  • Zero or one function pointer conversion.
  • Zero or one qualification conversion.
[Note
:
A standard conversion sequence can be empty, i.e., it can consist of no conversions.
end note
]
A standard conversion sequence will be applied to an expression if necessary to convert it to a required destination type.
[Note
:
Expressions with a given type will be implicitly converted to other types in several contexts:
  • When used as operands of operators.
    The operator's requirements for its operands dictate the destination type (Clause [expr]).
  • When used in the condition of an if statement or iteration statement ([stmt.select], [stmt.iter]).
    The destination type is bool.
  • When used in the expression of a switch statement.
    The destination type is integral ([stmt.select]).
  • When used as the source expression for an initialization (which includes use as an argument in a function call and use as the expression in a return statement).
    The type of the entity being initialized is (generally) the destination type.
end note
]
An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t ([dcl.init]).
Certain language constructs require that an expression be converted to a Boolean value.
An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t ([dcl.init]).
Certain language constructs require conversion to a value having one of a specified set of types appropriate to the construct.
An expression e of class type E appearing in such a context is said to be contextually implicitly converted to a specified type T and is well-formed if and only if e can be implicitly converted to a type T that is determined as follows: E is searched for non-explicit conversion functions whose return type is cv T or reference to cv T such that T is allowed by the context.
There shall be exactly one such T.
The effect of any implicit conversion is the same as performing the corresponding declaration and initialization and then using the temporary variable as the result of the conversion.
The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type ([dcl.ref]), an xvalue if T is an rvalue reference to object type, and a prvalue otherwise.
The expression e is used as a glvalue if and only if the initialization uses it as a glvalue.
[Note
:
For class types, user-defined conversions are considered as well; see [class.conv].
In general, an implicit conversion sequence ([over.best.ics]) consists of a standard conversion sequence followed by a user-defined conversion followed by another standard conversion sequence.
end note
]
[Note
:
There are some contexts where certain conversions are suppressed.
For example, the lvalue-to-rvalue conversion is not done on the operand of the unary & operator.
Specific exceptions are given in the descriptions of those operators and contexts.
end note
]

7.1 Lvalue-to-rvalue conversion [conv.lval]

A glvalue ([basic.lval]) of a non-function, non-array type T can be converted to a prvalue.57
If T is an incomplete type, a program that necessitates this conversion is ill-formed.
If T is a non-class type, the type of the prvalue is the cv-unqualified version of T.
Otherwise, the type of the prvalue is T.58
When an lvalue-to-rvalue conversion is applied to an expression e, and either
  • e is not potentially evaluated, or
  • the evaluation of e results in the evaluation of a member ex of the set of potential results of e, and ex names a variable x that is not odr-used by ex ([basic.def.odr]),
the value contained in the referenced object is not accessed.
[Example
:
struct S { int n; };
auto f() {
  S x { 1 };
  constexpr S y { 2 };
  return [&](bool b) { return (b ? y : x).n; };
}
auto g = f();
int m = g(false);   // undefined behavior due to access of x.n outside its lifetime
int n = g(true);    // OK, does not access y.n
end example
]
The result of the conversion is determined according to the following rules:
  • If T is cv std​::​nullptr_­t, the result is a null pointer constant ([conv.ptr]).
    [Note
    :
    Since no value is fetched from memory, there is no side effect for a volatile access ([intro.execution]), and an inactive member of a union ([class.union]) may be accessed.
    end note
    ]
  • Otherwise, if T has a class type, the conversion copy-initializes the result object from the glvalue.
  • Otherwise, if the object to which the glvalue refers contains an invalid pointer value ([basic.stc.dynamic.deallocation], [basic.stc.dynamic.safety]), the behavior is implementation-defined.
  • Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.
[Note
:
See also [basic.lval].
end note
]
For historical reasons, this conversion is called the “lvalue-to-rvalue” conversion, even though that name does not accurately reflect the taxonomy of expressions described in [basic.lval].
In C++ class and array prvalues can have cv-qualified types.
This differs from ISO C, in which non-lvalues never have cv-qualified types.

7.2 Array-to-pointer conversion [conv.array]

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T.
The temporary materialization conversion ([conv.rval]) is applied.
The result is a pointer to the first element of the array.

7.3 Function-to-pointer conversion [conv.func]

An lvalue of function type T can be converted to a prvalue of type “pointer to T.
The result is a pointer to the function.59
[Note
:
See [over.over] for additional rules for the case where the function is overloaded.
end note
]
This conversion never applies to non-static member functions because an lvalue that refers to a non-static member function cannot be obtained.

7.4 Temporary materialization conversion [conv.rval]

A prvalue of type T can be converted to an xvalue of type T.
This conversion initializes a temporary object ([class.temporary]) of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object.
T shall be a complete type.
[Note
:
If T is a class type (or array thereof), it must have an accessible and non-deleted destructor; see [class.dtor].
end note
]
[Example
:
struct X { int n; };
int k = X().n;      // OK, X() prvalue is converted to xvalue
end example
]

7.5 Qualification conversions [conv.qual]

A cv-decomposition of a type T is a sequence of and such that T is U” for , where each is a set of cv-qualifiers ([basic.type.qualifier]), and each is “pointer to” ([dcl.ptr]), “pointer to member of class of type” ([dcl.mptr]), “array of ”, or “array of unknown bound of” ([dcl.array]).
If designates an array, the cv-qualifiers on the element type are also taken as the cv-qualifiers of the array.
[Example
:
The type denoted by the type-id const int ** has two cv-decompositions, taking U as “int” and as “pointer to const int.
end example
]
The n-tuple of cv-qualifiers after the first one in the longest cv-decomposition of T, that is, , is called the cv-qualification signature of T.
Two types and are similar if they have cv-decompositions with the same n such that corresponding components are the same and the types denoted by U are the same.
A prvalue expression of type can be converted to type if the following conditions are satisfied, where denotes the cv-qualifiers in the cv-qualification signature of :60
  • and are similar.
  • For every , if const is in then const is in , and similarly for volatile.
  • If the and are different, then const is in every for .
[Note
:
If a program could assign a pointer of type T** to a pointer of type const T** (that is, if line #1 below were allowed), a program could inadvertently modify a const object (as it is done on line #2).
For example,
int main() {
  const char c = 'c';
  char* pc;
  const char** pcc = &pc;       // #1: not allowed
  *pcc = &c;
  *pc = 'C';                    // #2: modifies a const object
}
end note
]
[Note
:
A prvalue of type “pointer to cv1 T” can be converted to a prvalue of type “pointer to cv2 T” if “cv2 T” is more cv-qualified than “cv1 T.
A prvalue of type “pointer to member of X of type cv1 T” can be converted to a prvalue of type “pointer to member of X of type cv2 T” if “cv2 T” is more cv-qualified than “cv1 T.
end note
]
[Note
:
Function types (including those used in pointer to member function types) are never cv-qualified ([dcl.fct]).
end note
]
These rules ensure that const-safety is preserved by the conversion.

7.6 Integral promotions [conv.prom]

A prvalue of an integer type other than bool, char16_­t, char32_­t, or wchar_­t whose integer conversion rank ([conv.rank]) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.
A prvalue of type char16_­t, char32_­t, or wchar_­t ([basic.fundamental]) can be converted to a prvalue of the first of the following types that can represent all the values of its underlying type: int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int.
If none of the types in that list can represent all the values of its underlying type, a prvalue of type char16_­t, char32_­t, or wchar_­t can be converted to a prvalue of its underlying type.
A prvalue of an unscoped enumeration type whose underlying type is not fixed ([dcl.enum]) can be converted to a prvalue of the first of the following types that can represent all the values of the enumeration (i.e., the values in the range to as described in [dcl.enum]): int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int.
If none of the types in that list can represent all the values of the enumeration, a prvalue of an unscoped enumeration type can be converted to a prvalue of the extended integer type with lowest integer conversion rank ([conv.rank]) greater than the rank of long long in which all the values of the enumeration can be represented.
If there are two such extended types, the signed one is chosen.
A prvalue of an unscoped enumeration type whose underlying type is fixed ([dcl.enum]) can be converted to a prvalue of its underlying type.
Moreover, if integral promotion can be applied to its underlying type, a prvalue of an unscoped enumeration type whose underlying type is fixed can also be converted to a prvalue of the promoted underlying type.
A prvalue for an integral bit-field ([class.bit]) can be converted to a prvalue of type int if int can represent all the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can represent all the values of the bit-field.
If the bit-field is larger yet, no integral promotion applies to it.
If the bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes.
A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.
These conversions are called integral promotions.

7.7 Floating-point promotion [conv.fpprom]

A prvalue of type float can be converted to a prvalue of type double.
The value is unchanged.
This conversion is called floating-point promotion.

7.8 Integral conversions [conv.integral]

A prvalue of an integer type can be converted to a prvalue of another integer type.
A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.
If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo where n is the number of bits used to represent the unsigned type).
[Note
:
In a two's complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation).
end note
]
If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined.
If the destination type is bool, see [conv.bool].
If the source type is bool, the value false is converted to zero and the value true is converted to one.
The conversions allowed as integral promotions are excluded from the set of integral conversions.

7.9 Floating-point conversions [conv.double]

A prvalue of floating-point type can be converted to a prvalue of another floating-point type.
If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation.
If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values.
Otherwise, the behavior is undefined.
The conversions allowed as floating-point promotions are excluded from the set of floating-point conversions.

7.10 Floating-integral conversions [conv.fpint]

A prvalue of a floating-point type can be converted to a prvalue of an integer type.
The conversion truncates; that is, the fractional part is discarded.
The behavior is undefined if the truncated value cannot be represented in the destination type.
[Note
:
If the destination type is bool, see [conv.bool].
end note
]
A prvalue of an integer type or of an unscoped enumeration type can be converted to a prvalue of a floating-point type.
The result is exact if possible.
If the value being converted is in the range of values that can be represented but the value cannot be represented exactly, it is an implementation-defined choice of either the next lower or higher representable value.
[Note
:
Loss of precision occurs if the integral value cannot be represented exactly as a value of the floating type.
end note
]
If the value being converted is outside the range of values that can be represented, the behavior is undefined.
If the source type is bool, the value false is converted to zero and the value true is converted to one.

7.11 Pointer conversions [conv.ptr]

A null pointer constant is an integer literal ([lex.icon]) with value zero or a prvalue of type std​::​nullptr_­t.
A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type.
Such a conversion is called a null pointer conversion.
Two null pointer values of the same type shall compare equal.
The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion ([conv.qual]).
A null pointer constant of integral type can be converted to a prvalue of type std​::​nullptr_­t.
[Note
:
The resulting prvalue is not a null pointer value.
end note
]
A prvalue of type “pointer to cv T”, where T is an object type, can be converted to a prvalue of type “pointer to cv void.
The pointer value ([basic.compound]) is unchanged by this conversion.
A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause [class.derived]) of D.
If B is an inaccessible (Clause [class.access]) or ambiguous ([class.member.lookup]) base class of D, a program that necessitates this conversion is ill-formed.
The result of the conversion is a pointer to the base class subobject of the derived class object.
The null pointer value is converted to the null pointer value of the destination type.

7.12 Pointer to member conversions [conv.mem]

A null pointer constant ([conv.ptr]) can be converted to a pointer to member type; the result is the null member pointer value of that type and is distinguishable from any pointer to member not created from a null pointer constant.
Such a conversion is called a null member pointer conversion.
Two null member pointer values of the same type shall compare equal.
The conversion of a null pointer constant to a pointer to member of cv-qualified type is a single conversion, and not the sequence of a pointer to member conversion followed by a qualification conversion ([conv.qual]).
A prvalue of type “pointer to member of B of type cv T”, where B is a class type, can be converted to a prvalue of type “pointer to member of D of type cv T”, where D is a derived class (Clause [class.derived]) of B.
If B is an inaccessible (Clause [class.access]), ambiguous ([class.member.lookup]), or virtual ([class.mi]) base class of D, or a base class of a virtual base class of D, a program that necessitates this conversion is ill-formed.
The result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class.
The result refers to the member in D's instance of B.
Since the result has type “pointer to member of D of type cv T”, indirection through it with a D object is valid.
The result is the same as if indirecting through the pointer to member of B with the B subobject of D.
The null member pointer value is converted to the null member pointer value of the destination type.61
The rule for conversion of pointers to members (from pointer to member of base to pointer to member of derived) appears inverted compared to the rule for pointers to objects (from pointer to derived to pointer to base) ([conv.ptr], Clause [class.derived]).
This inversion is necessary to ensure type safety.
Note that a pointer to member is not an object pointer or a function pointer and the rules for conversions of such pointers do not apply to pointers to members.
In particular, a pointer to member cannot be converted to a void*.

7.13 Function pointer conversions [conv.fctptr]

A prvalue of type “pointer to noexcept function” can be converted to a prvalue of type “pointer to function”.
The result is a pointer to the function.
A prvalue of type “pointer to member of type noexcept function” can be converted to a prvalue of type “pointer to member of type function”.
The result points to the member function.
[Example
:
  void (*p)();
  void (**pp)() noexcept = &p;  // error: cannot convert to pointer to noexcept function

  struct S { typedef void (*p)(); operator p(); };
  void (*q)() noexcept = S();   // error: cannot convert to pointer to noexcept function
end example
]

7.14 Boolean conversions [conv.bool]

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool.
A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.
For direct-initialization ([dcl.init]), a prvalue of type std​::​nullptr_­t can be converted to a prvalue of type bool; the resulting value is false.

7.15 Integer conversion rank [conv.rank]

Every integer type has an integer conversion rank defined as follows:
  • No two signed integer types other than char and signed char (if char is signed) shall have the same rank, even if they have the same representation.
  • The rank of a signed integer type shall be greater than the rank of any signed integer type with a smaller size.
  • The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char.
  • The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.
  • The rank of any standard integer type shall be greater than the rank of any extended integer type with the same size.
  • The rank of char shall equal the rank of signed char and unsigned char.
  • The rank of bool shall be less than the rank of all other standard integer types.
  • The ranks of char16_­t, char32_­t, and wchar_­t shall equal the ranks of their underlying types ([basic.fundamental]).
  • The rank of any extended signed integer type relative to another extended signed integer type with the same size is implementation-defined, but still subject to the other rules for determining the integer conversion rank.
  • For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 shall have greater rank than T3.
[Note
:
The integer conversion rank is used in the definition of the integral promotions ([conv.prom]) and the usual arithmetic conversions (Clause [expr]).
end note
]

8 Expressions [expr]

[Note
:
Clause [expr] defines the syntax, order of evaluation, and meaning of expressions.62
An expression is a sequence of operators and operands that specifies a computation.
An expression can result in a value and can cause side effects.
end note
]
[Note
:
Operators can be overloaded, that is, given meaning when applied to expressions of class type (Clause [class]) or enumeration type ([dcl.enum]).
Uses of overloaded operators are transformed into function calls as described in [over.oper].
Overloaded operators obey the rules for syntax and evaluation order specified in Clause [expr], but the requirements of operand type and value category are replaced by the rules for function call.
Relations between operators, such as ++a meaning a+=1, are not guaranteed for overloaded operators ([over.oper]).
end note
]
Clause [expr] defines the effects of operators when applied to types for which they have not been overloaded.
Operator overloading shall not modify the rules for the built-in operators, that is, for operators applied to types for which they are defined by this Standard.
However, these built-in operators participate in overload resolution, and as part of that process user-defined conversions will be considered where necessary to convert the operands to types appropriate for the built-in operator.
If a built-in operator is selected, such conversions will be applied to the operands before the operation is considered further according to the rules in Clause [expr]; see [over.match.oper], [over.built].
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
[Note
:
Treatment of division by zero, forming a remainder using a zero divisor, and all floating-point exceptions vary among machines, and is sometimes adjustable by a library function.
end note
]
If an expression initially has the type “reference to T” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis.
The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
[Note
:
Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see [basic.life]).
end note
]
If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
[Note
:
An expression is an xvalue if it is:
  • the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type,
  • a cast to an rvalue reference to object type,
  • a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue, or
  • a .* pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.
In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues; rvalue references to functions are treated as lvalues whether named or not.
end note
]
[Example
:
struct A {
  int m;
};
A&& operator+(A, A);
A&& f();

A a;
A&& ar = static_cast<A&&>(a);
The expressions f(), f().m, static_­cast<A&&>(a), and a + a are xvalues.
The expression ar is an lvalue.
end example
]
An unevaluated operand is not evaluated.
[Note
:
In an unevaluated operand, a non-static class member may be named ([expr.prim]) and naming of objects or functions does not, by itself, require that a definition be provided ([basic.def.odr]).
An unevaluated operand is considered a full-expression ([intro.execution]).
end note
]
Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), or function-to-pointer ([conv.func]) standard conversions are applied to convert the expression to a prvalue.
[Note
:
Because cv-qualifiers are removed from the type of an expression of non-class type when the expression is converted to a prvalue, an lvalue expression of type const int can, for example, be used where a prvalue expression of type int is required.
end note
]
Whenever a prvalue expression appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion ([conv.rval]) is applied to convert the expression to an xvalue.
Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way.
The purpose is to yield a common type, which is also the type of the result.
This pattern is called the usual arithmetic conversions, which are defined as follows:
  • If either operand is of scoped enumeration type ([dcl.enum]), no conversions are performed; if the other operand does not have the same type, the expression is ill-formed.
  • If either operand is of type long double, the other shall be converted to long double.
  • Otherwise, if either operand is double, the other shall be converted to double.
  • Otherwise, if either operand is float, the other shall be converted to float.
  • Otherwise, the integral promotions ([conv.prom]) shall be performed on both operands.63
    Then the following rules shall be applied to the promoted operands:
    • If both operands have the same type, no further conversion is needed.
    • Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank shall be converted to the type of the operand with greater rank.
    • Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.
    • Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type.
    • Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
In some contexts, an expression only appears for its side effects.
Such an expression is called a discarded-value expression.
The array-to-pointer ([conv.array]) and function-to-pointer ([conv.func]) standard conversions are not applied.
The lvalue-to-rvalue conversion ([conv.lval]) is applied if and only if the expression is a glvalue of volatile-qualified type and it is one of the following:
[Note
:
Using an overloaded operator causes a function call; the above covers only operators with built-in meaning.
end note
]
If the expression is a prvalue after this optional conversion, the temporary materialization conversion ([conv.rval]) is applied.
[Note
:
If the expression is an lvalue of class type, it must have a volatile copy constructor to initialize the temporary that is the result object of the lvalue-to-rvalue conversion.
end note
]
The glvalue expression is evaluated and its value is discarded.
The values of the floating operands and the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.64
The cv-combined type of two types T1 and T2 is a type T3 similar to T1 whose cv-qualification signature ([conv.qual]) is:
  • for every , is the union of and ;
  • if the resulting is different from or , then const is added to every for .
[Note
:
Given similar types T1 and T2, this construction ensures that both can be converted to T3.
end note
]
The composite pointer type of two operands p1 and p2 having types T1 and T2, respectively, where at least one is a pointer or pointer to member type or std​::​nullptr_­t, is:
  • if both p1 and p2 are null pointer constants, std​::​nullptr_­t;
  • if either p1 or p2 is a null pointer constant, T2 or T1, respectively;
  • if T1 or T2 is “pointer to cv1 void” and the other type is “pointer to cv2 T”, where T is an object type or void, “pointer to cv12 void”, where cv12 is the union of cv1 and cv2;
  • if T1 or T2 is “pointer to noexcept function” and the other type is “pointer to function”, where the function types are otherwise the same, “pointer to function”;
  • if T1 is “pointer to cv1 C1” and T2 is “pointer to cv2 C2”, where C1 is reference-related to C2 or C2 is reference-related to C1 ([dcl.init.ref]), the cv-combined type of T1 and T2 or the cv-combined type of T2 and T1, respectively;
  • if T1 is “pointer to member of C1 of type cv1 U1” and T2 is “pointer to member of C2 of type cv2 U2” where C1 is reference-related to C2 or C2 is reference-related to C1 ([dcl.init.ref]), the cv-combined type of T2 and T1 or the cv-combined type of T1 and T2, respectively;
  • if T1 and T2 are similar types ([conv.qual]), the cv-combined type of T1 and T2;
  • otherwise, a program that necessitates the determination of a composite pointer type is ill-formed.
[Example
:
typedef void *p;
typedef const int *q;
typedef int **pi;
typedef const int **pci;
The composite pointer type of p and q is “pointer to const void”; the composite pointer type of pi and pci is “pointer to const pointer to const int.
end example
]
The precedence of operators is not directly specified, but it can be derived from the syntax.
As a consequence, operands of type bool, char16_­t, char32_­t, wchar_­t, or an enumerated type are converted to some integral type.
The cast and assignment operators must still perform their specific conversions as described in [expr.cast], [expr.static.cast] and [expr.ass].

8.1 Primary expressions [expr.prim]

8.1.1 Literals [expr.prim.literal]

A literal is a primary expression.
Its type depends on its form ([lex.literal]).
A string literal is an lvalue; all other literals are prvalues.

8.1.2 This [expr.prim.this]

The keyword this names a pointer to the object for which a non-static member function ([class.this]) is invoked or a non-static data member's initializer ([class.mem]) is evaluated.
If a declaration declares a member function or member function template of a class X, the expression this is a prvalue of type “pointer to cv-qualifier-seq X” between the optional cv-qualifier-seq and the end of the function-definition, member-declarator, or declarator.
It shall not appear before the optional cv-qualifier-seq and it shall not appear within the declaration of a static member function (although its type and value category are defined within a static member function as they are within a non-static member function).
[Note
:
This is because declaration matching does not occur until the complete declarator is known.
end note
]
Unlike the object expression in other contexts, *this is not required to be of complete type for purposes of class member access ([expr.ref]) outside the member function body.
[Note
:
Only class members declared prior to the declaration are visible.
end note
]
[Example
:
struct A {
  char g();
  template<class T> auto f(T t) -> decltype(t + g())
    { return t + g(); }
};
template auto A::f(int t) -> decltype(t + g());
end example
]
Otherwise, if a member-declarator declares a non-static data member ([class.mem]) of a class X, the expression this is a prvalue of type “pointer to X” within the optional default member initializer ([class.mem]).
It shall not appear elsewhere in the member-declarator.
The expression this shall not appear in any other context.
[Example
:
class Outer {
  int a[sizeof(*this)];               // error: not inside a member function
  unsigned int sz = sizeof(*this);    // OK: in default member initializer

  void f() {
    int b[sizeof(*this)];             // OK

    struct Inner {
      int c[sizeof(*this)];           // error: not inside a member function of Inner
    };
  }
};
end example
]

8.1.3 Parentheses [expr.prim.paren]

A parenthesized expression (E) is a primary expression whose type, value, and value category are identical to those of E.
The parenthesized expression can be used in exactly the same contexts as those where E can be used, and with the same meaning, except as otherwise indicated.

8.1.4 Names [expr.prim.id]

An id-expression is a restricted form of a primary-expression.
[Note
:
An id-expression can appear after . and -> operators ([expr.ref]).
end note
]
An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
  • as part of a class member access ([expr.ref]) in which the object expression refers to the member's class65 or a class derived from that class, or
  • to form a pointer to member ([expr.unary.op]), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.
    [Example
    :
    struct S {
      int m;
    };
    int i = sizeof(S::m);           // OK
    int j = sizeof(S::m + 42);      // OK
    
    end example
    ]
This also applies when the object expression is an implicit (*this) ([class.mfct.non-static]).

8.1.4.1 Unqualified names [expr.prim.id.unqual]

An identifier is an id-expression provided it has been suitably declared (Clause [dcl.dcl]).
[Note
:
For operator-function-ids, see [over.oper]; for conversion-function-ids, see [class.conv.fct]; for literal-operator-ids, see [over.literal]; for template-ids, see [temp.names].
A class-name or decltype-specifier prefixed by ~ denotes a destructor; see [class.dtor].
Within the definition of a non-static member function, an identifier that names a non-static member is transformed to a class member access expression ([class.mfct.non-static]).
end note
]
The type of the expression is the type of the identifier.
The result is the entity denoted by the identifier.
The expression is an lvalue if the entity is a function, variable, or data member and a prvalue otherwise; it is a bit-field if the identifier designates a bit-field ([dcl.struct.bind]).

8.1.4.2 Qualified names [expr.prim.id.qual]

The type denoted by a decltype-specifier in a nested-name-specifier shall be a class or enumeration type.
A nested-name-specifier that denotes a class, optionally followed by the keyword template ([temp.names]), and then followed by the name of a member of either that class ([class.mem]) or one of its base classes (Clause [class.derived]), is a qualified-id; [class.qual] describes name lookup for class members that appear in qualified-ids.
The result is the member.
The type of the result is the type of the member.
The result is an lvalue if the member is a static member function or a data member and a prvalue otherwise.
[Note
:
A class member can be referred to using a qualified-id at any point in its potential scope ([basic.scope.class]).
end note
]
Where class-name ​::​~ class-name is used, the two class-names shall refer to the same class; this notation names the destructor ([class.dtor]).
The form ~ decltype-specifier also denotes the destructor, but it shall not be used as the unqualified-id in a qualified-id.
[Note
:
A typedef-name that names a class is a class-name ([class.name]).
end note
]
The nested-name-specifier ​::​ names the global namespace.
A nested-name-specifier that names a namespace ([basic.namespace]), optionally followed by the keyword template ([temp.names]), and then followed by the name of a member of that namespace (or the name of a member of a namespace made visible by a using-directive), is a qualified-id; [namespace.qual] describes name lookup for namespace members that appear in qualified-ids.
The result is the member.
The type of the result is the type of the member.
The result is an lvalue if the member is a function or a variable and a prvalue otherwise.
A nested-name-specifier that denotes an enumeration ([dcl.enum]), followed by the name of an enumerator of that enumeration, is a qualified-id that refers to the enumerator.
The result is the enumerator.
The type of the result is the type of the enumeration.
The result is a prvalue.
In a qualified-id, if the unqualified-id is a conversion-function-id, its conversion-type-id shall denote the same type in both the context in which the entire qualified-id occurs and in the context of the class denoted by the nested-name-specifier.

8.1.5 Lambda expressions [expr.prim.lambda]

Lambda expressions provide a concise way to create simple function objects.
[Example
:
#include <algorithm>
#include <cmath>
void abssort(float* x, unsigned N) {
  std::sort(x, x + N, [](float a, float b) { return std::abs(a) < std::abs(b); });
}
end example
]
A lambda-expression is a prvalue whose result object is called the closure object.
A lambda-expression shall not appear in an unevaluated operand (Clause [expr]), in a template-argument, in an alias-declaration, in a typedef declaration, or in the declaration of a function or function template outside its function body and default arguments.
[Note
:
The intention is to prevent lambdas from appearing in a signature.
end note
]
[Note
:
A closure object behaves like a function object ([function.objects]).
end note
]
In the decl-specifier-seq of the lambda-declarator, each decl-specifier shall either be mutable or constexpr.
If a lambda-expression does not include a lambda-declarator, it is as if the lambda-declarator were ().
The lambda return type is auto, which is replaced by the type specified by the trailing-return-type if provided and/or deduced from return statements as described in [dcl.spec.auto].
[Example
:
auto x1 = [](int i){ return i; };     // OK: return type is int
auto x2 = []{ return { 1, 2 }; };     // error: deducing return type from braced-init-list
int j;
auto x3 = []()->auto&& { return j; }; // OK: return type is int&
end example
]

8.1.5.1 Closure types [expr.prim.lambda.closure]

The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below.
The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression.
[Note
:
This determines the set of namespaces and classes associated with the closure type ([basic.lookup.argdep]).
The parameter types of a lambda-declarator do not affect these associated namespaces and classes.
end note
]
The closure type is not an aggregate type ([dcl.init.aggr]).
An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:
  • the size and/or alignment of the closure type,
  • whether the closure type is trivially copyable (Clause [class]),
  • whether the closure type is a standard-layout class (Clause [class]), or
  • whether the closure type is a POD class (Clause [class]).
An implementation shall not add members of rvalue reference type to the closure type.
The closure type for a non-generic lambda-expression has a public inline function call operator ([over.call]) whose parameters and return type are described by the lambda-expression's parameter-declaration-clause and trailing-return-type respectively.
For a generic lambda, the closure type has a public inline function call operator member template ([temp.mem]) whose template-parameter-list consists of one invented type template-parameter for each occurrence of auto in the lambda's parameter-declaration-clause, in order of appearance.
The invented type template-parameter is a parameter pack if the corresponding parameter-declaration declares a function parameter pack ([dcl.fct]).
The return type and function parameters of the function call operator template are derived from the lambda-expression's trailing-return-type and parameter-declaration-clause by replacing each occurrence of auto in the decl-specifiers of the parameter-declaration-clause with the name of the corresponding invented template-parameter.
[Example
:
auto glambda = [](auto a, auto&& b) { return a < b; };
bool b = glambda(3, 3.14);                             // OK

auto vglambda = [](auto printer) {
  return [=](auto&& ... ts) {                          // OK: ts is a function parameter pack
    printer(std::forward<decltype(ts)>(ts)...);

    return [=]() {
      printer(ts ...);
    };
  };
};
auto p = vglambda( [](auto v1, auto v2, auto v3)
                   { std::cout << v1 << v2 << v3; } );
auto q = p(1, 'a', 3.14);                              // OK: outputs 1a3.14
q();                                                   // OK: outputs 1a3.14
end example
]
The function call operator or operator template is declared const ([class.mfct.non-static]) if and only if the lambda-expression's parameter-declaration-clause is not followed by mutable.
It is neither virtual nor declared volatile.
Any noexcept-specifier specified on a lambda-expression applies to the corresponding function call operator or operator template.
An attribute-specifier-seq in a lambda-declarator appertains to the type of the corresponding function call operator or operator template.
The function call operator or any given operator template specialization is a constexpr function if either the corresponding lambda-expression's parameter-declaration-clause is followed by constexpr, or it satisfies the requirements for a constexpr function ([dcl.constexpr]).
[Note
:
Names referenced in the lambda-declarator are looked up in the context in which the lambda-expression appears.
end note
]
[Example
:
auto ID = [](auto a) { return a; };
static_assert(ID(3) == 3); // OK

struct NonLiteral {
  NonLiteral(int n) : n(n) { }
  int n;
};
static_assert(ID(NonLiteral{3}).n == 3); // ill-formed
end example
]
[Example
:
auto monoid = [](auto v) { return [=] { return v; }; };
auto add = [](auto m1) constexpr {
  auto ret = m1();
  return [=](auto m2) mutable {
    auto m1val = m1();
    auto plus = [=](auto m2val) mutable constexpr
                   { return m1val += m2val; };
    ret = plus(m2());
    return monoid(ret);
  };
};
constexpr auto zero = monoid(0);
constexpr auto one = monoid(1);
static_assert(add(one)(zero)() == one()); // OK

// Since two below is not declared constexpr, an evaluation of its constexpr member function call operator
// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture)
// in a constant expression.
auto two = monoid(2);
assert(two() == 2); // OK, not a constant expression.
static_assert(add(one)(one)() == two()); // ill-formed: two() is not a constant expression
static_assert(add(one)(one)() == monoid(2)()); // OK
end example
]
The closure type for a non-generic lambda-expression with no lambda-capture has a conversion function to pointer to function with C++ language linkage ([dcl.link]) having the same parameter and return types as the closure type's function call operator.
The conversion is to “pointer to noexcept function” if the function call operator has a non-throwing exception specification.
The value returned by this conversion function is the address of a function F that, when invoked, has the same effect as invoking the closure type's function call operator.
F is a constexpr function if the function call operator is a constexpr function.
For a generic lambda with no lambda-capture, the closure type has a conversion function template to pointer to function.
The conversion function template has the same invented template-parameter-list, and the pointer to function has the same parameter types, as the function call operator template.
The return type of the pointer to function shall behave as if it were a decltype-specifier denoting the return type of the corresponding function call operator template specialization.
[Note
:
If the generic lambda has no trailing-return-type or the trailing-return-type contains a placeholder type, return type deduction of the corresponding function call operator template specialization has to be done.
The corresponding specialization is that instantiation of the function call operator template with the same template arguments as those deduced for the conversion function template.
Consider the following:
auto glambda = [](auto a) { return a; };
int (*fp)(int) = glambda;
The behavior of the conversion function of glambda above is like that of the following conversion function:
struct Closure {
  template<class T> auto operator()(T t) const { ... }
  template<class T> static auto lambda_call_operator_invoker(T a) {
    // forwards execution to operator()(a) and therefore has
    // the same return type deduced
    ...
  }
  template<class T> using fptr_t =
     decltype(lambda_call_operator_invoker(declval<T>())) (*)(T);

  template<class T> operator fptr_t<T>() const
    { return &lambda_call_operator_invoker; }
};
end note
]
[Example
:
void f1(int (*)(int))   { }
void f2(char (*)(int))  { }

void g(int (*)(int))    { }  // #1
void g(char (*)(char))  { }  // #2

void h(int (*)(int))    { }  // #3
void h(char (*)(int))   { }  // #4

auto glambda = [](auto a) { return a; };
f1(glambda);  // OK
f2(glambda);  // error: ID is not convertible
g(glambda);   // error: ambiguous
h(glambda);   // OK: calls #3 since it is convertible from ID
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
end example
]
The value returned by any given specialization of this conversion function template is the address of a function F that, when invoked, has the same effect as invoking the generic lambda's corresponding function call operator template specialization.
F is a constexpr function if the corresponding specialization is a constexpr function.
[Note
:
This will result in the implicit instantiation of the generic lambda's body.
The instantiated generic lambda's return type and parameter types shall match the return type and parameter types of the pointer to function.
end note
]
[Example
:
auto GL = [](auto a) { std::cout << a; return a; };
int (*GL_int)(int) = GL;  // OK: through conversion function template
GL_int(3);                // OK: same as GL(3)
end example
]
The conversion function or conversion function template is public, constexpr, non-virtual, non-explicit, const, and has a non-throwing exception specification ([except.spec]).
[Example
:
auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };
auto C = [](auto a) { return a; };

static_assert(Fwd(C,3) == 3); // OK

// No specialization of the function call operator template can be constexpr (due to the local static).
auto NC = [](auto a) { static int s; return a; };
static_assert(Fwd(NC,3) == 3); // ill-formed
end example
]
The lambda-expression's compound-statement yields the function-body ([dcl.fct.def]) of the function call operator, but for purposes of name lookup ([basic.lookup]), determining the type and value of this ([class.this]) and transforming id-expressions referring to non-static class members into class member access expressions using (*this) ([class.mfct.non-static]), the compound-statement is considered in the context of the lambda-expression.
[Example
:
struct S1 {
  int x, y;
  int operator()(int);
  void f() {
    [=]()->int {
      return operator()(this->x + y); // equivalent to S1​::​operator()(this->x + (*this).y)
                                      // this has type S1*
    };
  }
};
end example
]
Further, a variable _­_­func_­_­ is implicitly defined at the beginning of the compound-statement of the lambda-expression, with semantics as described in [dcl.fct.def.general].
The closure type associated with a lambda-expression has no default constructor and a deleted copy assignment operator.
It has a defaulted copy constructor and a defaulted move constructor ([class.copy]).
[Note
:
These special member functions are implicitly defined as usual, and might therefore be defined as deleted.
end note
]
The closure type associated with a lambda-expression has an implicitly-declared destructor ([class.dtor]).
A member of a closure type shall not be explicitly instantiated ([temp.explicit]), explicitly specialized ([temp.expl.spec]), or named in a friend declaration ([class.friend]).

8.1.5.2 Captures [expr.prim.lambda.capture]

The body of a lambda-expression may refer to variables with automatic storage duration and the *this object (if any) of enclosing block scopes by capturing those entities, as described below.
If a lambda-capture includes a capture-default that is &, no identifier in a simple-capture of that lambda-capture shall be preceded by &.
If a lambda-capture includes a capture-default that is =, each simple-capture of that lambda-capture shall be of the form “& identifier” or “* this.
[Note
:
The form [&,this] is redundant but accepted for compatibility with ISO C++ 2014.
end note
]
Ignoring appearances in initializers of init-captures, an identifier or this shall not appear more than once in a lambda-capture.
[Example
:
struct S2 { void f(int i); };
void S2::f(int i) {
  [&, i]{ };        // OK
  [&, &i]{ };       // error: i preceded by & when & is the default
  [=, *this]{ };    // OK
  [=, this]{ };     // error: this when = is the default
  [i, i]{ };        // error: i repeated
  [this, *this]{ }; // error: this appears twice
}
end example
]
A lambda-expression whose smallest enclosing scope is a block scope ([basic.scope.block]) is a local lambda expression; any other lambda-expression shall not have a capture-default or simple-capture in its lambda-introducer.
The reaching scope of a local lambda expression is the set of enclosing scopes up to and including the innermost enclosing function and its parameters.
[Note
:
This reaching scope includes any intervening lambda-expressions.
end note
]
The identifier in a simple-capture is looked up using the usual rules for unqualified name lookup ([basic.lookup.unqual]); each such lookup shall find an entity.
An entity that is designated by a simple-capture is said to be explicitly captured, and shall be *this (when the simple-capture is “this” or “* this”) or a variable with automatic storage duration declared in the reaching scope of the local lambda expression.
If an identifier in a simple-capture appears as the declarator-id of a parameter of the lambda-declarator's parameter-declaration-clause, the program is ill-formed.
[Example
:
void f() {
  int x = 0;
  auto g = [x](int x) { return 0; }    // error: parameter and simple-capture have the same name
}
end example
]
An init-capture behaves as if it declares and explicitly captures a variable of the form “auto init-capture ;” whose declarative region is the lambda-expression's compound-statement, except that:
  • if the capture is by copy (see below), the non-static data member declared for the capture and the variable are treated as two different ways of referring to the same object, which has the lifetime of the non-static data member, and no additional copy and destruction is performed, and
  • if the capture is by reference, the variable's lifetime ends when the closure object's lifetime ends.
[Note
:
This enables an init-capture like “x = std​::​move(x)”; the second “x” must bind to a declaration in the surrounding context.
end note
]
[Example
:
int x = 4;
auto y = [&r = x, x = x+1]()->int {
            r += 2;
            return x+2;
         }();  // Updates ​::​x to 6, and initializes y to 7.

auto z = [a = 42](int a) { return 1; } // error: parameter and local variable have the same name
end example
]
A lambda-expression with an associated capture-default that does not explicitly capture *this or a variable with automatic storage duration (this excludes any id-expression that has been found to refer to an init-capture's associated non-static data member), is said to implicitly capture the entity (i.e., *this or a variable) if the compound-statement:
[Example
:
void f(int, const int (&)[2] = {})    { }   // #1
void f(const int&, const int (&)[1])  { }   // #2
void test() {
  const int x = 17;
  auto g = [](auto a) {
    f(x);                       // OK: calls #1, does not capture x
  };

  auto g2 = [=](auto a) {
    int selector[sizeof(a) == 1 ? 1 : 2]{};
    f(x, selector);             // OK: is a dependent expression, so captures x
  };
}
end example
]
All such implicitly captured entities shall be declared within the reaching scope of the lambda expression.
[Note
:
The implicit capture of an entity by a nested lambda-expression can cause its implicit capture by the containing lambda-expression (see below).
Implicit odr-uses of this can result in implicit capture.
end note
]
An entity is captured if it is captured explicitly or implicitly.
An entity captured by a lambda-expression is odr-used ([basic.def.odr]) in the scope containing the lambda-expression.
If *this is captured by a local lambda expression, its nearest enclosing function shall be a non-static member function.
If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses ([basic.def.odr]) this or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.
If a lambda-expression captures an entity and that entity is not defined or captured in the immediately enclosing lambda expression or function, the program is ill-formed.
[Example
:
void f1(int i) {
  int const N = 20;
  auto m1 = [=]{
    int const M = 30;
    auto m2 = [i]{
      int x[N][M];              // OK: N and M are not odr-used
      x[0][0] = i;              // OK: i is explicitly captured by m2 and implicitly captured by m1
    };
  };
  struct s1 {
    int f;
    void work(int n) {
      int m = n*n;
      int j = 40;
      auto m3 = [this,m] {
        auto m4 = [&,j] {       // error: j not captured by m3
          int x = n;            // error: n implicitly captured by m4 but not captured by m3
          x += m;               // OK: m implicitly captured by m4 and explicitly captured by m3
          x += i;               // error: i is outside of the reaching scope
          x += f;               // OK: this captured implicitly by m4 and explicitly by m3
        };
      };
    }
  };
}

struct s2 {
  double ohseven = .007;
  auto f() {
    return [this] {
      return [*this] {
          return ohseven;       // OK
      }
    }();
  }
  auto g() {
    return [] {
      return [*this] { };       // error: *this not captured by outer lambda-expression
    }();
  }
};
end example
]
A lambda-expression appearing in a default argument shall not implicitly or explicitly capture any entity.
[Example
:
void f2() {
  int i = 1;
  void g1(int = ([i]{ return i; })());          // ill-formed
  void g2(int = ([i]{ return 0; })());          // ill-formed
  void g3(int = ([=]{ return i; })());          // ill-formed
  void g4(int = ([=]{ return 0; })());          // OK
  void g5(int = ([]{ return sizeof i; })());    // OK
}
end example
]
An entity is captured by copy if
For each entity captured by copy, an unnamed non-static data member is declared in the closure type.
The declaration order of these members is unspecified.
The type of such a data member is the referenced type if the entity is a reference to an object, an lvalue reference to the referenced function type if the entity is a reference to a function, or the type of the corresponding captured entity otherwise.
A member of an anonymous union shall not be captured by copy.
Every id-expression within the compound-statement of a lambda-expression that is an odr-use ([basic.def.odr]) of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type.
[Note
:
An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type.
Furthermore, such an id-expression does not cause the implicit capture of the entity.
end note
]
If *this is captured by copy, each odr-use of this is transformed into a pointer to the corresponding unnamed data member of the closure type, cast ([expr.cast]) to the type of this.
[Note
:
The cast ensures that the transformed expression is a prvalue.
end note
]
An id-expression within the compound-statement of a lambda-expression that is an odr-use of a reference captured by reference refers to the entity to which the captured reference is bound and not to the captured reference.
[Note
:
The validity of such captures is determined by the lifetime of the object to which the reference refers, not by the lifetime of the reference itself.
end note
]
[Example
:
void f(const int*);
void g() {
  const int N = 10;
  [=] {
    int arr[N];     // OK: not an odr-use, refers to automatic variable
    f(&N);          // OK: causes N to be captured; &N points to
                    // the corresponding member of the closure type
  };
}
auto h(int &r) {
  return [&] {
    ++r;            // Valid after h returns if the lifetime of the
                    // object to which r is bound has not ended
  };
}
end example
]
An entity is captured by reference if it is implicitly or explicitly captured but not captured by copy.
It is unspecified whether additional unnamed non-static data members are declared in the closure type for entities captured by reference.
If declared, such non-static data members shall be of literal type.
[Example
:
// The inner closure type must be a literal type regardless of how reference captures are represented.
static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
end example
]
A bit-field or a member of an anonymous union shall not be captured by reference.
If a lambda-expression m2 captures an entity and that entity is captured by an immediately enclosing lambda-expression m1, then m2's capture is transformed as follows:
  • if m1 captures the entity by copy, m2 captures the corresponding non-static data member of m1's closure type;
  • if m1 captures the entity by reference, m2 captures the same entity captured by m1.
[Example
:
The nested lambda expressions and invocations below will output 123234.
int a = 1, b = 1, c = 1;
auto m1 = [a, &b, &c]() mutable {
  auto m2 = [a, b, &c]() mutable {
    std::cout << a << b << c;
    a = 4; b = 4; c = 4;
  };
  a = 3; b = 3; c = 3;
  m2();
};
a = 2; b = 2; c = 2;
m1();
std::cout << a << b << c;
end example
]
Every occurrence of decltype((x)) where x is a possibly parenthesized id-expression that names an entity of automatic storage duration is treated as if x were transformed into an access to a corresponding data member of the closure type that would have been declared if x were an odr-use of the denoted entity.
[Example
:
void f3() {
  float x, &r = x;
  [=] {                     // x and r are not captured (appearance in a decltype operand is not an odr-use)
    decltype(x) y1;         // y1 has type float
    decltype((x)) y2 = y1;  // y2 has type float const& because this lambda is not mutable and x is an lvalue
    decltype(r) r1 = y1;    // r1 has type float& (transformation not considered)
    decltype((r)) r2 = y2;  // r2 has type float const&
  };
}
end example
]
When the lambda-expression is evaluated, the entities that are captured by copy are used to direct-initialize each corresponding non-static data member of the resulting closure object, and the non-static data members corresponding to the init-captures are initialized as indicated by the corresponding initializer (which may be copy- or direct-initialization).
(For array members, the array elements are direct-initialized in increasing subscript order.)
These initializations are performed in the (unspecified) order in which the non-static data members are declared.
[Note
:
This ensures that the destructions will occur in the reverse order of the constructions.
end note
]
[Note
:
If a non-reference entity is implicitly or explicitly captured by reference, invoking the function call operator of the corresponding lambda-expression after the lifetime of the entity has ended is likely to result in undefined behavior.
end note
]
A simple-capture followed by an ellipsis is a pack expansion ([temp.variadic]).
An init-capture followed by an ellipsis is ill-formed.
[Example
:
template<class... Args>
void f(Args... args) {
  auto lm = [&, args...] { return g(args...); };
  lm();
}
end example
]

8.1.6 Fold expressions [expr.prim.fold]

A fold expression performs a fold of a template parameter pack ([temp.variadic]) over a binary operator.
fold-expression:
	( cast-expression fold-operator ... )
	( ... fold-operator cast-expression )
	( cast-expression fold-operator ... fold-operator cast-expression )
fold-operator: one of
	+   -   *   /   %   ^   &   |   <<   >> 
	+=  -=  *=  /=  %=  ^=  &=  |=  <<=  >>=  =
	==  !=  <   >   <=  >=  &&  ||  ,    .*   ->*
An expression of the form (... op e) where op is a fold-operator is called a unary left fold.
An expression of the form (e op ...) where op is a fold-operator is called a unary right fold.
Unary left folds and unary right folds are collectively called unary folds.
In a unary fold, the cast-expression shall contain an unexpanded parameter pack ([temp.variadic]).
An expression of the form (e1 op1 ... op2 e2) where op1 and op2 are fold-operators is called a binary fold.
In a binary fold, op1 and op2 shall be the same fold-operator, and either e1 shall contain an unexpanded parameter pack or e2 shall contain an unexpanded parameter pack, but not both.
If e2 contains an unexpanded parameter pack, the expression is called a binary left fold.
If e1 contains an unexpanded parameter pack, the expression is called a binary right fold.
[Example
:
template<typename ...Args>
bool f(Args ...args) {
  return (true && ... && args); // OK
}

template<typename ...Args>
bool f(Args ...args) {
  return (args + ... + args);   // error: both operands contain unexpanded parameter packs
}
end example
]

8.2 Postfix expressions [expr.post]

[Note
:
The > token following the type-id in a dynamic_­cast, static_­cast, reinterpret_­cast, or const_­cast may be the product of replacing a >> token by two consecutive > tokens ([temp.names]).
end note
]

8.2.1 Subscripting [expr.sub]

A postfix expression followed by an expression in square brackets is a postfix expression.
One of the expressions shall be a glvalue of type “array of T” or a prvalue of type “pointer to T” and the other shall be a prvalue of unscoped enumeration or integral type.
The result is of type “T.
The type “T” shall be a completely-defined object type.66
The expression E1[E2] is identical (by definition) to *((E1)+(E2))
[Note
:
see [expr.unary] and [expr.add] for details of * and + and [dcl.array] for details of arrays.
end note
]
, except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.
The expression E1 is sequenced before the expression E2.
A braced-init-list shall not be used with the built-in subscript operator.
This is true even if the subscript operator is used in the following common idiom: &x[0].

8.2.2 Function call [expr.call]

A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses which constitute the arguments to the function.
The postfix expression shall have function type or function pointer type.
For a call to a non-member function or to a static member function, the postfix expression shall be either an lvalue that refers to a function (in which case the function-to-pointer standard conversion ([conv.func]) is suppressed on the postfix expression), or it shall have function pointer type.
Calling a function through an expression whose function type is different from the function type of the called function's definition results in undefined behavior ([dcl.link]).
For a call to a non-static member function, the postfix expression shall be an implicit ([class.mfct.non-static], [class.static]) or explicit class member access ([expr.ref]) whose id-expression is a function member name, or a pointer-to-member expression ([expr.mptr.oper]) selecting a function member; the call is as a member of the class object referred to by the object expression.
In the case of an implicit class member access, the implied object is the one pointed to by this.
[Note
:
A member function call of the form f() is interpreted as (*this).f() (see [class.mfct.non-static]).
end note
]
If a function or member function name is used, the name can be overloaded (Clause [over]), in which case the appropriate function shall be selected according to the rules in [over.match].
If the selected function is non-virtual, or if the id-expression in the class member access expression is a qualified-id, that function is called.
Otherwise, its final overrider ([class.virtual]) in the dynamic type of the object expression is called; such a call is referred to as a virtual function call.
[Note
:
The dynamic type is the type of the object referred to by the current value of the object expression.
[class.cdtor] describes the behavior of virtual function calls when the object expression refers to an object under construction or destruction.
end note
]
[Note
:
If a function or member function name is used, and name lookup ([basic.lookup]) does not find a declaration of that name, the program is ill-formed.
No function is implicitly declared by such a call.
end note
]
If the postfix-expression designates a destructor ([class.dtor]), the type of the function call expression is void; otherwise, the type of the function call expression is the return type of the statically chosen function (i.e., ignoring the virtual keyword), even if the type of the function actually called is different.
This return type shall be an object type, a reference type or cv void.
When a function is called, each parameter ([dcl.fct]) shall be initialized ([dcl.init], [class.copy], [class.ctor]) with its corresponding argument.
If the function is a non-static member function, the this parameter of the function ([class.this]) shall be initialized with a pointer to the object of the call, converted as if by an explicit type conversion ([expr.cast]).
[Note
:
There is no access or ambiguity checking on this conversion; the access checking and disambiguation are done as part of the (possibly implicit) class member access operator.
end note
]
When a function is called, the parameters that have object type shall have completely-defined object type.
[Note
:
this still allows a parameter to be a pointer or reference to an incomplete class type.
However, it prevents a passed-by-value parameter to have an incomplete class type.
end note
]
It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression.
The initialization and destruction of each parameter occurs within the context of the calling function.
[Example
:
The access of the constructor, conversion functions or destructor is checked at the point of call in the calling function.
If a constructor or destructor for a function parameter throws an exception, the search for a handler starts in the scope of the calling function; in particular, if the function called has a function-try-block (Clause [except]) with a handler that could handle the exception, this handler is not considered.
end example
]
The postfix-expression is sequenced before each expression in the expression-list and any default argument.
The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.
[Note
:
All side effects of argument evaluations are sequenced before the function is entered (see [intro.execution]).
end note
]
[Example
:
void f() {
  std::string s = "but I have heard it works even if you don't believe in it";
  s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, "");
  assert(s == "I have heard it works only if you believe in it"); // OK
}
end example
]
[Note
:
If an operator function is invoked using operator notation, argument evaluation is sequenced as specified for the built-in operator; see [over.match.oper].
end note
]
[Example
:
struct S {
  S(int);
};
int operator<<(S, int);
int i, j;
int x = S(i=1) << (i=2);
int y = operator<<(S(j=1), j=2);
After performing the initializations, the value of i is 2 (see [expr.shift]), but it is unspecified whether the value of j is 1 or 2.
end example
]
The result of a function call is the result of the operand of the evaluated return statement ([stmt.return]) in the called function (if any), except in a virtual function call if the return type of the final overrider is different from the return type of the statically chosen function, the value returned from the final overrider is converted to the return type of the statically chosen function.
[Note
:
A function can change the values of its non-const parameters, but these changes cannot affect the values of the arguments except where a parameter is of a reference type ([dcl.ref]); if the reference is to a const-qualified type, const_­cast is required to be used to cast away the constness in order to modify the argument's value.
Where a parameter is of const reference type a temporary object is introduced if needed ([dcl.type], [lex.literal], [lex.string], [dcl.array], [class.temporary]).
In addition, it is possible to modify the values of non-constant objects through pointer parameters.
end note
]
A function can be declared to accept fewer arguments (by declaring default arguments ([dcl.fct.default])) or more arguments (by using the ellipsis, ..., or a function parameter pack ([dcl.fct])) than the number of parameters in the function definition ([dcl.fct.def]).
[Note
:
This implies that, except where the ellipsis (...) or a function parameter pack is used, a parameter is available for each argument.
end note
]
When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the argument by invoking va_­arg ([support.runtime]).
[Note
:
This paragraph does not apply to arguments passed to a function parameter pack.
Function parameter packs are expanded during template instantiation ([temp.variadic]), thus each such argument has a corresponding parameter when a function template specialization is actually called.
end note
]
The lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions are performed on the argument expression.
An argument that has type cv std​::​nullptr_­t is converted to type void* ([conv.ptr]).
After these conversions, if the argument does not have arithmetic, enumeration, pointer, pointer to member, or class type, the program is ill-formed.
Passing a potentially-evaluated argument of class type (Clause [class]) having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.
If the argument has integral or enumeration type that is subject to the integral promotions ([conv.prom]), or a floating-point type that is subject to the floating-point promotion ([conv.fpprom]), the value of the argument is converted to the promoted type before the call.
These promotions are referred to as the default argument promotions.
Recursive calls are permitted, except to the main function ([basic.start.main]).
A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise.

8.2.3 Explicit type conversion (functional notation) [expr.type.conv]

A simple-type-specifier or typename-specifier followed by a parenthesized optional expression-list or by a braced-init-list (the initializer) constructs a value of the specified type given the initializer.
If the type is a placeholder for a deduced class type, it is replaced by the return type of the function selected by overload resolution for class template deduction ([over.match.class.deduct]) for the remainder of this section.
If the initializer is a parenthesized single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression ([expr.cast]).
If the type is cv void and the initializer is (), the expression is a prvalue of the specified type that performs no initialization.
Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized ([dcl.init]) with the initializer.
For an expression of the form T(), T shall not be an array type.

8.2.4 Pseudo destructor call [expr.pseudo]

The use of a pseudo-destructor-name after a dot . or arrow -> operator represents the destructor for the non-class type denoted by type-name or decltype-specifier.
The result shall only be used as the operand for the function call operator (), and the result of such a call has type void.
The only effect is the evaluation of the postfix-expression before the dot or arrow.
The left-hand side of the dot operator shall be of scalar type.
The left-hand side of the arrow operator shall be of pointer to scalar type.
This scalar type is the object type.
The cv-unqualified versions of the object type and of the type designated by the pseudo-destructor-name shall be the same type.
Furthermore, the two type-names in a pseudo-destructor-name of the form
nested-name-specifier type-name ::~ type-name
shall designate the same scalar type (ignoring cv-qualification).

8.2.5 Class member access [expr.ref]

A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template ([temp.names]), and then followed by an id-expression, is a postfix expression.
The postfix expression before the dot or arrow is evaluated;67 the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.
For the first option (dot) the first expression shall be a glvalue having complete class type.
For the second option (arrow) the first expression shall be a prvalue having pointer to complete class type.
The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of [expr.ref] will address only the first option (dot).68
In either case, the id-expression shall name a member of the class or of one of its base classes.
[Note
:
Because the name of a class is inserted in its class scope (Clause [class]), the name of a class is also considered a nested member of that class.
end note
]
[Note
:
[basic.lookup.classref] describes how names are looked up after the . and -> operators.
end note
]
Abbreviating postfix-expression.id-expression as E1.E2, E1 is called the object expression.
If E2 is a bit-field, E1.E2 is a bit-field.
The type and value category of E1.E2 are determined as follows.
In the remainder of [expr.ref], cq represents either const or the absence of const and vq represents either volatile or the absence of volatile.
cv represents an arbitrary set of cv-qualifiers, as defined in [basic.type.qualifier].
If E2 is declared to have type “reference to T”, then E1.E2 is an lvalue; the type of E1.E2 is T.
Otherwise, one of the following rules applies.
  • If E2 is a static data member and the type of E2 is T, then E1.E2 is an lvalue; the expression designates the named member of the class.
    The type of E1.E2 is T.
  • If E2 is a non-static data member and the type of E1 is “cq1 vq1 X”, and the type of E2 is “cq2 vq2 T”, the expression designates the named member of the object designated by the first expression.
    If E1 is an lvalue, then E1.E2 is an lvalue; otherwise E1.E2 is an xvalue.
    Let the notation vq12 stand for the “union” of vq1 and vq2; that is, if vq1 or vq2 is volatile, then vq12 is volatile.
    Similarly, let the notation cq12 stand for the “union” of cq1 and cq2; that is, if cq1 or cq2 is const, then cq12 is const.
    If E2 is declared to be a mutable member, then the type of E1.E2 is “vq12 T.
    If E2 is not declared to be a mutable member, then the type of E1.E2 is “cq12 vq12 T.
  • If E2 is a (possibly overloaded) member function, function overload resolution ([over.match]) is used to determine whether E1.E2 refers to a static or a non-static member function.
    • If it refers to a static member function and the type of E2 is “function of parameter-type-list returning T”, then E1.E2 is an lvalue; the expression designates the static member function.
      The type of E1.E2 is the same type as that of E2, namely “function of parameter-type-list returning T.
    • Otherwise, if E1.E2 refers to a non-static member function and the type of E2 is “function of parameter-type-list cv ref-qualifier returning T”, then E1.E2 is a prvalue.
      The expression designates a non-static member function.
      The expression can be used only as the left-hand operand of a member function call ([class.mfct]).
      [Note
      :
      Any redundant set of parentheses surrounding the expression is ignored ([expr.prim]).
      end note
      ]
      The type of E1.E2 is “function of parameter-type-list cv returning T.
  • If E2 is a nested type, the expression E1.E2 is ill-formed.
  • If E2 is a member enumerator and the type of E2 is T, the expression E1.E2 is a prvalue.
    The type of E1.E2 is T.
If E2 is a non-static data member or a non-static member function, the program is ill-formed if the class of which E2 is directly a member is an ambiguous base ([class.member.lookup]) of the naming class ([class.access.base]) of E2.
[Note
:
The program is also ill-formed if the naming class is an ambiguous base of the class type of the object expression; see [class.access.base].
end note
]
If the class member access expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.
Note that (*(E1)) is an lvalue.

8.2.6 Increment and decrement [expr.post.incr]

The value of a postfix ++ expression is the value of its operand.
[Note
:
The value obtained is a copy of the original value
end note
]
The operand shall be a modifiable lvalue.
The type of the operand shall be an arithmetic type other than cv bool, or a pointer to a complete object type.
The value of the operand object is modified by adding 1 to it.
The value computation of the ++ expression is sequenced before the modification of the operand object.
With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation.
[Note
:
Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single postfix ++ operator.
end note
]
The result is a prvalue.
The type of the result is the cv-unqualified version of the type of the operand.
If the operand is a bit-field that cannot represent the incremented value, the resulting value of the bit-field is implementation-defined.
See also [expr.add] and [expr.ass].
The operand of postfix -- is decremented analogously to the postfix ++ operator.
[Note
:
For prefix increment and decrement, see [expr.pre.incr].
end note
]

8.2.7 Dynamic cast [expr.dynamic.cast]

The result of the expression dynamic_­cast<T>(v) is the result of converting the expression v to type T.
T shall be a pointer or reference to a complete class type, or “pointer to cv void.
The dynamic_­cast operator shall not cast away constness ([expr.const.cast]).
If T is a pointer type, v shall be a prvalue of a pointer to complete class type, and the result is a prvalue of type T.
If T is an lvalue reference type, v shall be an lvalue of a complete class type, and the result is an lvalue of the type referred to by T.
If T is an rvalue reference type, v shall be a glvalue having a complete class type, and the result is an xvalue of the type referred to by T.
If the type of v is the same as T, or it is the same as T except that the class object type in T is more cv-qualified than the class object type in v, the result is v (converted if necessary).
If the value of v is a null pointer value in the pointer case, the result is the null pointer value of type T.
If T is “pointer to cv1 B” and v has type “pointer to cv2 D” such that B is a base class of D, the result is a pointer to the unique B subobject of the D object pointed to by v.
Similarly, if T is “reference to cv1 B” and v has type cv2 D such that B is a base class of D, the result is the unique B subobject of the D object referred to by v.69
In both the pointer and reference cases, the program is ill-formed if cv2 has greater cv-qualification than cv1 or if B is an inaccessible or ambiguous base class of D.
[Example
:
struct B { };
struct D : B { };
void foo(D* dp) {
  B*  bp = dynamic_cast<B*>(dp);    // equivalent to B* bp = dp;
}
end example
]
Otherwise, v shall be a pointer to or a glvalue of a polymorphic type ([class.virtual]).
If T is “pointer to cv void”, then the result is a pointer to the most derived object pointed to by v.
Otherwise, a runtime check is applied to see if the object pointed or referred to by v can be converted to the type pointed or referred to by T.
If C is the class type to which T points or refers, the runtime check logically executes as follows:
  • If, in the most derived object pointed (referred) to by v, v points (refers) to a public base class subobject of a C object, and if only one object of type C is derived from the subobject pointed (referred) to by v the result points (refers) to that C object.
  • Otherwise, if v points (refers) to a public base class subobject of the most derived object, and the type of the most derived object has a base class, of type C, that is unambiguous and public, the result points (refers) to the C subobject of the most derived object.
  • Otherwise, the runtime check fails.
The value of a failed cast to pointer type is the null pointer value of the required result type.
A failed cast to reference type throws an exception ([except.throw]) of a type that would match a handler ([except.handle]) of type std​::​bad_­cast ([bad.cast]).
[Example
:
class A { virtual void f(); };
class B { virtual void g(); };
class D : public virtual A, private B { };
void g() {
  D   d;
  B*  bp = (B*)&d;                  // cast needed to break protection
  A*  ap = &d;                      // public derivation, no cast needed
  D&  dr = dynamic_cast<D&>(*bp);   // fails
  ap = dynamic_cast<A*>(bp);        // fails
  bp = dynamic_cast<B*>(ap);        // fails
  ap = dynamic_cast<A*>(&d);        // succeeds
  bp = dynamic_cast<B*>(&d);        // ill-formed (not a runtime check)
}

class E : public D, public B { };
class F : public E, public D { };
void h() {
  F   f;
  A*  ap  = &f;                     // succeeds: finds unique A
  D*  dp  = dynamic_cast<D*>(ap);   // fails: yields null; f has two D subobjects
  E*  ep  = (E*)ap;                 // ill-formed: cast from virtual base
  E*  ep1 = dynamic_cast<E*>(ap);   // succeeds
}
end example
]
[Note
:
[class.cdtor] describes the behavior of a dynamic_­cast applied to an object under construction or destruction.
end note
]
The most derived object ([intro.object]) pointed or referred to by v can contain other B objects as base classes, but these are ignored.

8.2.8 Type identification [expr.typeid]

The result of a typeid expression is an lvalue of static type const std​::​type_­info ([type.info]) and dynamic type const std​::​type_­info or const name where name is an implementation-defined class publicly derived from std​::​type_­info which preserves the behavior described in [type.info].70
The lifetime of the object referred to by the lvalue extends to the end of the program.
Whether or not the destructor is called for the std​::​type_­info object at the end of the program is unspecified.
When typeid is applied to a glvalue expression whose type is a polymorphic class type ([class.virtual]), the result refers to a std​::​type_­info object representing the type of the most derived object ([intro.object]) (that is, the dynamic type) to which the glvalue refers.
If the glvalue expression is obtained by applying the unary * operator to a pointer71 and the pointer is a null pointer value ([conv.ptr]), the typeid expression throws an exception ([except.throw]) of a type that would match a handler of type std​::​bad_­typeid exception ([bad.typeid]).
When typeid is applied to an expression other than a glvalue of a polymorphic class type, the result refers to a std​::​type_­info object representing the static type of the expression.
Lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) conversions are not applied to the expression.
If the expression is a prvalue, the temporary materialization conversion ([conv.rval]) is applied.
The expression is an unevaluated operand (Clause [expr]).
When typeid is applied to a type-id, the result refers to a std​::​type_­info object representing the type of the type-id.
If the type of the type-id is a reference to a possibly cv-qualified type, the result of the typeid expression refers to a std​::​type_­info object representing the cv-unqualified referenced type.
If the type of the type-id is a class type or a reference to a class type, the class shall be completely-defined.
If the type of the expression or type-id is a cv-qualified type, the result of the typeid expression refers to a std​::​type_­info object representing the cv-unqualified type.
[Example
:
class D { /* ... */ };
D d1;
const D d2;

typeid(d1) == typeid(d2);       // yields true
typeid(D)  == typeid(const D);  // yields true
typeid(D)  == typeid(d2);       // yields true
typeid(D)  == typeid(const D&); // yields true
end example
]
If the header <typeinfo> ([type.info]) is not included prior to a use of typeid, the program is ill-formed.
[Note
:
[class.cdtor] describes the behavior of typeid applied to an object under construction or destruction.
end note
]
The recommended name for such a class is extended_­type_­info.
If p is an expression of pointer type, then *p, (*p), *(p), ((*p)), *((p)), and so on all meet this requirement.

8.2.9 Static cast [expr.static.cast]

The result of the expression static_­cast<T>(v) is the result of converting the expression v to type T.
If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue.
The static_­cast operator shall not cast away constness ([expr.const.cast]).
An lvalue of type “cv1 B”, where B is a class type, can be cast to type “reference to cv2 D”, where D is a class derived (Clause [class.derived]) from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1.
If B is a virtual base class of D or a base class of a virtual base class of D, or if no valid standard conversion from “pointer to D” to “pointer to B” exists ([conv.ptr]), the program is ill-formed.
An xvalue of type “cv1 B” can be cast to type “rvalue reference to cv2 D” with the same constraints as for an lvalue of type “cv1 B.
If the object of type “cv1 B” is actually a base class subobject of an object of type D, the result refers to the enclosing object of type D.
Otherwise, the behavior is undefined.
[Example
:
struct B { };
struct D : public B { };
D d;
B &br = d;

static_cast<D&>(br);            // produces lvalue to the original d object
end example
]
An lvalue of type “cv1 T1” can be cast to type “rvalue reference to cv2 T2” if “cv2 T2” is reference-compatible with “cv1 T1” ([dcl.init.ref]).
If the value is not a bit-field, the result refers to the object or the specified base class subobject thereof; otherwise, the lvalue-to-rvalue conversion ([conv.lval]) is applied to the bit-field and the resulting prvalue is used as the expression of the static_­cast for the remainder of this section.
If T2 is an inaccessible (Clause [class.access]) or ambiguous ([class.member.lookup]) base class of T1, a program that necessitates such a cast is ill-formed.
An expression e can be explicitly converted to a type T if there is an implicit conversion sequence ([over.best.ics]) from e to T, or if overload resolution for a direct-initialization ([dcl.init]) of an object or reference of type T from e would find at least one viable function ([over.match.viable]).
If T is a reference type, the effect is the same as performing the declaration and initialization
 T t(e);
for some invented temporary variable t ([dcl.init]) and then using the temporary variable as the result of the conversion.
Otherwise, the result object is direct-initialized from e.
[Note
:
The conversion is ill-formed when attempting to convert an expression of class type to an inaccessible or ambiguous base class.
end note
]
Otherwise, the static_­cast shall perform one of the conversions listed below.
No other conversion shall be performed explicitly using a static_­cast.
Any expression can be explicitly converted to type cv void, in which case it becomes a discarded-value expression (Clause [expr]).
[Note
:
However, if the value is in a temporary object ([class.temporary]), the destructor for that object is not executed until the usual time, and the value of the object is preserved for the purpose of executing the destructor.
end note
]
The inverse of any standard conversion sequence (Clause [conv]) not containing an lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), function-to-pointer ([conv.func]), null pointer ([conv.ptr]), null member pointer ([conv.mem]), boolean ([conv.bool]), or function pointer ([conv.fctptr]) conversion, can be performed explicitly using static_­cast.
A program is ill-formed if it uses static_­cast to perform the inverse of an ill-formed standard conversion sequence.
[Example
:
struct B { };
struct D : private B { };
void f() {
  static_cast<D*>((B*)0);               // error: B is a private base of D
  static_cast<int B::*>((int D::*)0);   // error: B is a private base of D
}
end example
]
The lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) conversions are applied to the operand.
Such a static_­cast is subject to the restriction that the explicit conversion does not cast away constness ([expr.const.cast]), and the following additional rules for specific cases:
A value of a scoped enumeration type ([dcl.enum]) can be explicitly converted to an integral type.
When that type is cv bool, the resulting value is false if the original value is zero and true for all other values.
For the remaining integral types, the value is unchanged if the original value can be represented by the specified type.
Otherwise, the resulting value is unspecified.
A value of a scoped enumeration type can also be explicitly converted to a floating-point type; the result is the same as that of converting from the original value to the floating-point type.
A value of integral or enumeration type can be explicitly converted to a complete enumeration type.
The value is unchanged if the original value is within the range of the enumeration values ([dcl.enum]).
Otherwise, the behavior is undefined.
A value of floating-point type can also be explicitly converted to an enumeration type.
The resulting value is the same as converting the original value to the underlying type of the enumeration ([conv.fpint]), and subsequently to the enumeration type.
A prvalue of type “pointer to cv1 B”, where B is a class type, can be converted to a prvalue of type “pointer to cv2 D”, where D is a class derived (Clause [class.derived]) from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1.
If B is a virtual base class of D or a base class of a virtual base class of D, or if no valid standard conversion from “pointer to D” to “pointer to B” exists ([conv.ptr]), the program is ill-formed.
The null pointer value ([conv.ptr]) is converted to the null pointer value of the destination type.
If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D.
Otherwise, the behavior is undefined.
A prvalue of type “pointer to member of D of type cv1 T” can be converted to a prvalue of type “pointer to member of B of type cv2 T”, where B is a base class (Clause [class.derived]) of D, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1.72
If no valid standard conversion from “pointer to member of B of type T” to “pointer to member of D of type T” exists ([conv.mem]), the program is ill-formed.
The null member pointer value ([conv.mem]) is converted to the null member pointer value of the destination type.
If class B contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member.
Otherwise, the behavior is undefined.
[Note
:
Although class B need not contain the original member, the dynamic type of the object with which indirection through the pointer to member is performed must contain the original member; see [expr.mptr.oper].
end note
]
A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1.
If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified.
Otherwise, if the original pointer value points to an object a, and there is an object b of type T (ignoring cv-qualification) that is pointer-interconvertible ([basic.compound]) with a, the result is a pointer to b.
Otherwise, the pointer value is unchanged by the conversion.
[Example
:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
bool b = p1 == p2;  // b will have the value true.
end example
]
Function types (including those used in pointer to member function types) are never cv-qualified; see [dcl.fct].

8.2.10 Reinterpret cast [expr.reinterpret.cast]

The result of the expression reinterpret_­cast<T>(v) is the result of converting the expression v to type T.
If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions are performed on the expression v.
Conversions that can be performed explicitly using reinterpret_­cast are listed below.
No other conversion can be performed explicitly using reinterpret_­cast.
The reinterpret_­cast operator shall not cast away constness ([expr.const.cast]).
An expression of integral, enumeration, pointer, or pointer-to-member type can be explicitly converted to its own type; such a cast yields the value of its operand.
[Note
:
The mapping performed by reinterpret_­cast might, or might not, produce a representation different from the original value.
end note
]
A pointer can be explicitly converted to any integral type large enough to hold it.
The mapping function is implementation-defined.
[Note
:
It is intended to be unsurprising to those who know the addressing structure of the underlying machine.
end note
]
A value of type std​::​nullptr_­t can be converted to an integral type; the conversion has the same meaning and validity as a conversion of (void*)0 to the integral type.
[Note
:
A reinterpret_­cast cannot be used to convert a value of any type to the type std​::​nullptr_­t.
end note
]
A value of integral type or enumeration type can be explicitly converted to a pointer.
A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined.
[Note
:
Except as described in [basic.stc.dynamic.safety], the result of such a conversion will not be a safely-derived pointer value.
end note
]
A function pointer can be explicitly converted to a function pointer of a different type.
[Note
:
The effect of calling a function through a pointer to a function type ([dcl.fct]) that is not the same as the type used in the definition of the function is undefined.
end note
]
Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.
[Note
:
See also [conv.ptr] for more details of pointer conversions.
end note
]
An object pointer can be explicitly converted to an object pointer of a different type.73
When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_­cast<cv T*>(static_­cast<cv void*>(v)).
[Note
:
Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value.
end note
]
Converting a function pointer to an object pointer type or vice versa is conditionally-supported.
The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the original pointer value.
The null pointer value ([conv.ptr]) is converted to the null pointer value of the destination type.
[Note
:
A null pointer constant of type std​::​nullptr_­t cannot be converted to a pointer type, and a null pointer constant of integral type is not necessarily converted to a null pointer value.
end note
]
A prvalue of type “pointer to member of X of type T1” can be explicitly converted to a prvalue of a different type “pointer to member of Y of type T2” if T1 and T2 are both function types or both object types.74
The null member pointer value ([conv.mem]) is converted to the null member pointer value of the destination type.
The result of this conversion is unspecified, except in the following cases:
  • converting a prvalue of type “pointer to member function” to a different pointer to member function type and back to its original type yields the original pointer to member value.
  • converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data member of Y of type T2” (where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer to member value.
A glvalue expression of type T1 can be cast to the type “reference to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_­cast.
The result refers to the same object as the source glvalue, but with the specified type.
[Note
:
That is, for lvalues, a reference cast reinterpret_­cast<T&>(x) has the same effect as the conversion *reinterpret_­cast<T*>(&x) with the built-in & and * operators (and similarly for reinterpret_­cast<T&&>(x)).
end note
]
No temporary is created, no copy is made, and constructors ([class.ctor]) or conversion functions ([class.conv]) are not called.75
The types may have different cv-qualifiers, subject to the overall restriction that a reinterpret_­cast cannot cast away constness.
T1 and T2 may have different cv-qualifiers, subject to the overall restriction that a reinterpret_­cast cannot cast away constness.
This is sometimes referred to as a type pun.

8.2.11 Const cast [expr.const.cast]

The result of the expression const_­cast<T>(v) is of type T.
If T is an lvalue reference to object type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions are performed on the expression v.
Conversions that can be performed explicitly using const_­cast are listed below.
No other conversion shall be performed explicitly using const_­cast.
[Note
:
Subject to the restrictions in this section, an expression may be cast to its own type using a const_­cast operator.
end note
]
For two similar types T1 and T2 ([conv.qual]), a prvalue of type T1 may be explicitly converted to the type T2 using a const_­cast.
The result of a const_­cast refers to the original entity.
[Example
:
typedef int *A[3];               // array of 3 pointer to int
typedef const int *const CA[3];  // array of 3 const pointer to const int

CA &&r = A{}; // OK, reference binds to temporary array object after qualification conversion to type CA
A &&r1 = const_cast<A>(CA{});    // error: temporary array decayed to pointer
A &&r2 = const_cast<A&&>(CA{});  // OK
end example
]
For two object types T1 and T2, if a pointer to T1 can be explicitly converted to the type “pointer to T2” using a const_­cast, then the following conversions can also be made:
  • an lvalue of type T1 can be explicitly converted to an lvalue of type T2 using the cast const_­cast<T2&>;
  • a glvalue of type T1 can be explicitly converted to an xvalue of type T2 using the cast const_­cast<T2&&>; and
  • if T1 is a class type, a prvalue of type T1 can be explicitly converted to an xvalue of type T2 using the cast const_­cast<T2&&>.
The result of a reference const_­cast refers to the original object if the operand is a glvalue and to the result of applying the temporary materialization conversion ([conv.rval]) otherwise.
A null pointer value ([conv.ptr]) is converted to the null pointer value of the destination type.
The null member pointer value ([conv.mem]) is converted to the null member pointer value of the destination type.
[Note
:
Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_­cast that casts away a const-qualifier76 may produce undefined behavior ([dcl.type.cv]).
end note
]
A conversion from a type T1 to a type T2 casts away constness if T1 and T2 are different, there is a cv-decomposition ([conv.qual]) of T1 yielding n such that T2 has a cv-decomposition of the form
, and there is no qualification conversion that converts T1 to
.
Casting from an lvalue of type T1 to an lvalue of type T2 using an lvalue reference cast or casting from an expression of type T1 to an xvalue of type T2 using an rvalue reference cast casts away constness if a cast from a prvalue of type “pointer to T1” to the type “pointer to T2” casts away constness.
[Note
:
Some conversions which involve only changes in cv-qualification cannot be done using const_­cast. For instance, conversions between pointers to functions are not covered because such conversions lead to values whose use causes undefined behavior.
For the same reasons, conversions between pointers to member functions, and in particular, the conversion from a pointer to a const member function to a pointer to a non-const member function, are not covered.
end note
]
const_­cast is not limited to conversions that cast away a const-qualifier.

8.3 Unary expressions [expr.unary]

Expressions with unary operators group right-to-left.

8.3.1 Unary operators [expr.unary.op]

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.
If the type of the expression is “pointer to T”, the type of the result is “T.
[Note
:
Indirection through a pointer to an incomplete type (other than cv void) is valid.
The lvalue thus obtained can be used in limited ways (to initialize a reference, for example); this lvalue must not be converted to a prvalue, see [conv.lval].
end note
]
The result of each of the following unary operators is a prvalue.
The result of the unary & operator is a pointer to its operand.
The operand shall be an lvalue or a qualified-id.
If the operand is a qualified-id naming a non-static or variant member m of some class C with type T, the result has type “pointer to member of class C of type T” and is a prvalue designating C​::​m.
Otherwise, if the type of the expression is T, the result has type “pointer to T” and is a prvalue that is the address of the designated object ([intro.memory]) or a pointer to the designated function.
[Note
:
In particular, the address of an object of type “cv T” is “pointer to cv T”, with the same cv-qualification.
end note
]
For purposes of pointer arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), an object that is not an array element whose address is taken in this way is considered to belong to an array with one element of type T.
[Example
:
struct A { int i; };
struct B : A { };
... &B::i ...       // has type int A​::​*
int a;
int* p1 = &a;
int* p2 = p1 + 1;   // defined behavior
bool b = p2 > p1;   // defined behavior, with value true
end example
]
[Note
:
A pointer to member formed from a mutable non-static data member ([dcl.stc]) does not reflect the mutable specifier associated with the non-static data member.
end note
]
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses.
[Note
:
That is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member”.
Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” ([conv.func]).
Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id's class.
end note
]
If & is applied to an lvalue of incomplete class type and the complete type declares operator&(), it is unspecified whether the operator has the built-in meaning or the operator function is called.
The operand of & shall not be a bit-field.
The address of an overloaded function (Clause [over]) can be taken only in a context that uniquely determines which version of the overloaded function is referred to (see [over.over]).
[Note
:
Since the context might determine whether the operand is a static or non-static member function, the context can also affect whether the expression has type “pointer to function” or “pointer to member function”.
end note
]
The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument.
Integral promotion is performed on integral or enumeration operands.
The type of the result is the type of the promoted operand.
The operand of the unary - operator shall have arithmetic or unscoped enumeration type and the result is the negation of its operand.
Integral promotion is performed on integral or enumeration operands.
The negative of an unsigned quantity is computed by subtracting its value from , where n is the number of bits in the promoted operand.
The type of the result is the type of the promoted operand.
The operand of the logical negation operator ! is contextually converted to bool (Clause [conv]); its value is true if the converted operand is false and false otherwise.
The type of the result is bool.
The operand of ~ shall have integral or unscoped enumeration type; the result is the ones' complement of its operand.
Integral promotions are performed.
The type of the result is the type of the promoted operand.
There is an ambiguity in the grammar when ~ is followed by a class-name or decltype-specifier.
The ambiguity is resolved by treating ~ as the unary complement operator rather than as the start of an unqualified-id naming a destructor.
[Note
:
Because the grammar does not permit an operator to follow the ., ->, or ​::​ tokens, a ~ followed by a class-name or decltype-specifier in a member access expression or qualified-id is unambiguously parsed as a destructor name.
end note
]

8.3.2 Increment and decrement [expr.pre.incr]

The operand of prefix ++ is modified by adding 1.
The operand shall be a modifiable lvalue.
The type of the operand shall be an arithmetic type other than cv bool, or a pointer to a completely-defined object type.
The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field.
The expression ++x is equivalent to x+=1.
[Note
:
See the discussions of addition ([expr.add]) and assignment operators ([expr.ass]) for information on conversions.
end note
]
The operand of prefix -- is modified by subtracting 1.
The requirements on the operand of prefix -- and the properties of its result are otherwise the same as those of prefix ++.
[Note
:
For postfix increment and decrement, see [expr.post.incr].
end note
]

8.3.3 Sizeof [expr.sizeof]

The sizeof operator yields the number of bytes in the object representation of its operand.
The operand is either an expression, which is an unevaluated operand (Clause [expr]), or a parenthesized type-id.
The sizeof operator shall not be applied to an expression that has function or incomplete type, to the parenthesized name of such types, or to a glvalue that designates a bit-field.
sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1.
The result of sizeof applied to any other fundamental type ([basic.fundamental]) is implementation-defined.
[Note
:
In particular, sizeof(bool), sizeof(char16_­t), sizeof(char32_­t), and sizeof(wchar_­t) are implementation-defined.77
end note
]
[Note
:
See [intro.memory] for the definition of byte and [basic.types] for the definition of object representation.
end note
]
When applied to a reference or a reference type, the result is the size of the referenced type.
When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array.
The size of a most derived class shall be greater than zero ([intro.object]).
The result of applying sizeof to a base class subobject is the size of the base class type.78
When applied to an array, the result is the total number of bytes in the array.
This implies that the size of an array of n elements is n times the size of an element.
The sizeof operator can be applied to a pointer to a function, but shall not be applied directly to a function.
The lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions are not applied to the operand of sizeof.
If the operand is a prvalue, the temporary materialization conversion ([conv.rval]) is applied.
The identifier in a sizeof... expression shall name a parameter pack.
The sizeof... operator yields the number of arguments provided for the parameter pack identifier.
A sizeof... expression is a pack expansion ([temp.variadic]).
[Example
:
template<class... Types>
struct count {
  static const std::size_t value = sizeof...(Types);
};
end example
]
The result of sizeof and sizeof... is a constant of type std​::​size_­t.
[Note
:
std​::​size_­t is defined in the standard header <cstddef> ([cstddef.syn], [support.types.layout]).
end note
]
sizeof(bool) is not required to be 1.
The actual size of a base class subobject may be less than the result of applying sizeof to the subobject, due to virtual base classes and less strict padding requirements on base class subobjects.

8.3.4 New [expr.new]

The new-expression attempts to create an object of the type-id or new-type-id to which it is applied.
The type of that object is the allocated type.
This type shall be a complete object type, but not an abstract class type or array thereof ([intro.object], [basic.types], [class.abstract]).
[Note
:
Because references are not objects, references cannot be created by new-expressions.
end note
]
[Note
:
The type-id may be a cv-qualified type, in which case the object created by the new-expression has a cv-qualified type.
end note
]
[Note
:
The lifetime of such an entity is not necessarily restricted to the scope in which it is created.
end note
]
If the entity is a non-array object, the new-expression returns a pointer to the object created.
If it is an array, the new-expression returns a pointer to the initial element of the array.
If a placeholder type ([dcl.spec.auto]) appears in the type-specifier-seq of a new-type-id or type-id of a new-expression, the allocated type is deduced as follows: Let init be the new-initializer, if any, and T be the new-type-id or type-id of the new-expression, then the allocated type is the type deduced for the variable x in the invented declaration ([dcl.spec.auto]):
T x init ;
[Example
:
new auto(1);                    // allocated type is int
auto x = new auto('a');         // allocated type is char, x is of type char*

template<class T> struct A { A(T, T); };
auto y = new A{1, 2};           // allocated type is A<int>
end example
]
The new-type-id in a new-expression is the longest possible sequence of new-declarators.
[Note
:
This prevents ambiguities between the declarator operators &, &&, *, and [] and their expression counterparts.
end note
]
[Example
:
new int * i;                    // syntax error: parsed as (new int*) i, not as (new int)*i
The * is the pointer declarator and not the multiplication operator.
end example
]
[Note
:
Parentheses in a new-type-id of a new-expression can have surprising effects.
[Example
:
new int(*[10])();               // error
is ill-formed because the binding is
(new int) (*[10])();            // error
Instead, the explicitly parenthesized version of the new operator can be used to create objects of compound types ([basic.compound]):
new (int (*[10])());
allocates an array of 10 pointers to functions (taking no argument and returning int).
end example
]
end note
]
When the allocated object is an array (that is, the noptr-new-declarator syntax is used or the new-type-id or type-id denotes an array type), the new-expression yields a pointer to the initial element (if any) of the array.
[Note
:
Both new int and new int[10] have type int* and the type of new int[i][10] is int (*)[10]
end note
]
The attribute-specifier-seq in a noptr-new-declarator appertains to the associated array type.
Every constant-expression in a noptr-new-declarator shall be a converted constant expression ([expr.const]) of type std​::​size_­t and shall evaluate to a strictly positive value.
The expression in a noptr-new-declarator is implicitly converted to std​::​size_­t.
[Example
:
Given the definition int n = 42, new float[n][5] is well-formed (because n is the expression of a noptr-new-declarator), but new float[5][n] is ill-formed (because n is not a constant expression).
end example
]
The expression in a noptr-new-declarator is erroneous if:
  • the expression is of non-class type and its value before converting to std​::​size_­t is less than zero;
  • the expression is of class type and its value before application of the second standard conversion ([over.ics.user])79 is less than zero;
  • its value is such that the size of the allocated object would exceed the implementation-defined limit (Annex [implimits]); or
  • the new-initializer is a braced-init-list and the number of array elements for which initializers are provided (including the terminating '\0' in a string literal ([lex.string])) exceeds the number of elements to initialize.
If the expression is erroneous after converting to std​::​size_­t:
  • if the expression is a core constant expression, the program is ill-formed;
  • otherwise, an allocation function is not called; instead
When the value of the expression is zero, the allocation function is called to allocate an array with no elements.
A new-expression may obtain storage for the object by calling an allocation function ([basic.stc.dynamic.allocation]).
If the new-expression terminates by throwing an exception, it may release storage by calling a deallocation function ([basic.stc.dynamic.deallocation]).
If the allocated type is a non-array type, the allocation function's name is operator new and the deallocation function's name is operator delete.
If the allocated type is an array type, the allocation function's name is operator new[] and the deallocation function's name is operator delete[].
[Note
:
An implementation shall provide default definitions for the global allocation functions ([basic.stc.dynamic], [new.delete.single], [new.delete.array]).
A C++ program can provide alternative definitions of these functions ([replacement.functions]) and/or class-specific versions ([class.free]).
The set of allocation and deallocation functions that may be called by a new-expression may include functions that do not perform allocation or deallocation; for example, see [new.delete.placement].
end note
]
If the new-expression begins with a unary ​::​ operator, the allocation function's name is looked up in the global scope.
Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T.
If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.
An implementation is allowed to omit a call to a replaceable global allocation function ([new.delete.single], [new.delete.array]).
When it does so, the storage is instead provided by the implementation or provided by extending the allocation of another new-expression.
The implementation may extend the allocation of a new-expression e1 to provide storage for a new-expression e2 if the following would be true were the allocation not extended:
  • the evaluation of e1 is sequenced before the evaluation of e2, and
  • e2 is evaluated whenever e1 obtains storage, and
  • both e1 and e2 invoke the same replaceable global allocation function, and
  • if the allocation function invoked by e1 and e2 is throwing, any exceptions thrown in the evaluation of either e1 or e2 would be first caught in the same handler, and
  • the pointer values produced by e1 and e2 are operands to evaluated delete-expressions, and
  • the evaluation of e2 is sequenced before the evaluation of the delete-expression whose operand is the pointer value produced by e1.
[Example
:
  void mergeable(int x) {
    // These allocations are safe for merging:
    std::unique_ptr<char[]> a{new (std::nothrow) char[8]};
    std::unique_ptr<char[]> b{new (std::nothrow) char[8]};
    std::unique_ptr<char[]> c{new (std::nothrow) char[x]};

    g(a.get(), b.get(), c.get());
  }

  void unmergeable(int x) {
    std::unique_ptr<char[]> a{new char[8]};
    try {
      // Merging this allocation would change its catch handler.
      std::unique_ptr<char[]> b{new char[x]};
    } catch (const std::bad_alloc& e) {
      std::cerr << "Allocation failed: " << e.what() << std::endl;
      throw;
    }
  }
end example
]
When a new-expression calls an allocation function and that allocation has not been extended, the new-expression passes the amount of space requested to the allocation function as the first argument of type std​::​size_­t.
That argument shall be no less than the size of the object being created; it may be greater than the size of the object being created only if the object is an array.
For arrays of char, unsigned char, and std​::​byte, the difference between the result of the new-expression and the address returned by the allocation function shall be an integral multiple of the strictest fundamental alignment requirement ([basic.align]) of any object type whose size is no greater than the size of the array being created.
[Note
:
Because allocation functions are assumed to return pointers to storage that is appropriately aligned for objects of any type with fundamental alignment, this constraint on array allocation overhead permits the common idiom of allocating character arrays into which objects of other types will later be placed.
end note
]
When a new-expression calls an allocation function and that allocation has been extended, the size argument to the allocation call shall be no greater than the sum of the sizes for the omitted calls as specified above, plus the size for the extended call had it not been extended, plus any padding necessary to align the allocated objects within the allocated memory.
The new-placement syntax is used to supply additional arguments to an allocation function; such an expression is called a placement new-expression.
Overload resolution is performed on a function call created by assembling an argument list.
The first argument is the amount of space requested, and has type std​::​size_­t.
If the type of the allocated object has new-extended alignment, the next argument is the type's alignment, and has type std​::​align_­val_­t.
If the new-placement syntax is used, the initializer-clauses in its expression-list are the succeeding arguments.
If no matching function is found and the allocated object type has new-extended alignment, the alignment argument is removed from the argument list, and overload resolution is performed again.
[Example
:
  • new T results in one of the following calls:
    operator new(sizeof(T))
    operator new(sizeof(T), std::align_val_t(alignof(T)))
  • new(2,f) T results in one of the following calls:
    operator new(sizeof(T), 2, f)
    operator new(sizeof(T), std::align_val_t(alignof(T)), 2, f)
  • new T[5] results in one of the following calls:
    operator new[](sizeof(T) * 5 + x)
    operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T)))
  • new(2,f) T[5] results in one of the following calls:
    operator new[](sizeof(T) * 5 + x, 2, f)
    operator new[](sizeof(T) * 5 + x, std::align_val_t(alignof(T)), 2, f)
Here, each instance of x is a non-negative unspecified value representing array allocation overhead; the result of the new-expression will be offset by this amount from the value returned by operator new[].
This overhead may be applied in all array new-expressions, including those referencing the library function operator new[](std​::​size_­t, void*) and other placement allocation functions.
The amount of overhead may vary from one invocation of new to another.
end example
]
[Note
:
Unless an allocation function has a non-throwing exception specification ([except.spec]), it indicates failure to allocate storage by throwing a std​::​bad_­alloc exception ([basic.stc.dynamic.allocation], Clause [except], [bad.alloc]); it returns a non-null pointer otherwise.
If the allocation function has a non-throwing exception specification, it returns null to indicate failure to allocate storage and a non-null pointer otherwise.
end note
]
If the allocation function is a non-allocating form ([new.delete.placement]) that returns null, the behavior is undefined.
Otherwise, if the allocation function returns null, initialization shall not be done, the deallocation function shall not be called, and the value of the new-expression shall be null.
[Note
:
When the allocation function returns a value other than null, it must be a pointer to a block of storage in which space for the object has been reserved.
The block of storage is assumed to be appropriately aligned and of the requested size.
The address of the created object will not necessarily be the same as that of the block if the object is an array.
end note
]
A new-expression that creates an object of type T initializes that object as follows:
The invocation of the allocation function is sequenced before the evaluations of expressions in the new-initializer.
Initialization of the allocated object is sequenced before the value computation of the new-expression.
If the new-expression creates an object or an array of objects of class type, access and ambiguity control are done for the allocation function, the deallocation function ([class.free]), and the constructor ([class.ctor]).
If the new-expression creates an array of objects of class type, the destructor is potentially invoked ([class.dtor]).
If any part of the object initialization described above80 terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed, after which the exception continues to propagate in the context of the new-expression.
If no unambiguous matching deallocation function can be found, propagating the exception does not cause the object's memory to be freed.
[Note
:
This is appropriate when the called allocation function does not allocate memory; otherwise, it is likely to result in a memory leak.
end note
]
If the new-expression begins with a unary ​::​ operator, the deallocation function's name is looked up in the global scope.
Otherwise, if the allocated type is a class type T or an array thereof, the deallocation function's name is looked up in the scope of T.
If this lookup fails to find the name, or if the allocated type is not a class type or array thereof, the deallocation function's name is looked up in the global scope.
A declaration of a placement deallocation function matches the declaration of a placement allocation function if it has the same number of parameters and, after parameter transformations ([dcl.fct]), all parameter types except the first are identical.
If the lookup finds a single matching deallocation function, that function will be called; otherwise, no deallocation function will be called.
If the lookup finds a usual deallocation function with a parameter of type std​::​size_­t ([basic.stc.dynamic.deallocation]) and that function, considered as a placement deallocation function, would have been selected as a match for the allocation function, the program is ill-formed.
For a non-placement allocation function, the normal deallocation function lookup is used to find the matching deallocation function ([expr.delete])
[Example
:
struct S {
  // Placement allocation function:
  static void* operator new(std::size_t, std::size_t);

  // Usual (non-placement) deallocation function:
  static void operator delete(void*, std::size_t);
};

S* p = new (0) S;   // ill-formed: non-placement deallocation function matches
                    // placement allocation function
end example
]
If a new-expression calls a deallocation function, it passes the value returned from the allocation function call as the first argument of type void*.
If a placement deallocation function is called, it is passed the same additional arguments as were passed to the placement allocation function, that is, the same arguments as those specified with the new-placement syntax.
If the implementation is allowed to make a copy of any argument as part of the call to the allocation function, it is allowed to make a copy (of the same original value) as part of the call to the deallocation function or to reuse the copy made as part of the call to the allocation function.
If the copy is elided in one place, it need not be elided in the other.
If the conversion function returns a signed integer type, the second standard conversion converts to the unsigned type std​::​size_­t and thus thwarts any attempt to detect a negative value afterwards.
This may include evaluating a new-initializer and/or calling a constructor.

8.3.5 Delete [expr.delete]

The delete-expression operator destroys a most derived object ([intro.object]) or array created by a new-expression.
delete-expression:
	:: delete cast-expression
	:: delete [ ] cast-expression
The first alternative is for non-array objects, and the second is for arrays.
Whenever the delete keyword is immediately followed by empty square brackets, it shall be interpreted as the second alternative.81
The operand shall be of pointer to object type or of class type.
If of class type, the operand is contextually implicitly converted (Clause [conv]) to a pointer to object type.82
The delete-expression's result has type void.
If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section.
In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject ([intro.object]) representing a base class of such an object (Clause [class.derived]).
If not, the behavior is undefined.
In the second alternative (delete array), the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression.83
If not, the behavior is undefined.
[Note
:
This means that the syntax of the delete-expression must match the type of the object allocated by new, not the syntax of the new-expression.
end note
]
[Note
:
A pointer to a const type can be the operand of a delete-expression; it is not necessary to cast away the constness ([expr.const.cast]) of the pointer expression before it is used as the operand of the delete-expression.
end note
]
In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.
In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
The cast-expression in a delete-expression shall be evaluated exactly once.
If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.
If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted.
In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see [class.base.init]).
If the value of the operand of the delete-expression is not a null pointer value, then:
[Note
:
The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception.
end note
]
If the value of the operand of the delete-expression is a null pointer value, it is unspecified whether a deallocation function will be called as described above.
[Note
:
An implementation provides default definitions of the global deallocation functions operator delete for non-arrays ([new.delete.single]) and operator delete[] for arrays ([new.delete.array]).
A C++ program can provide alternative definitions of these functions ([replacement.functions]), and/or class-specific versions ([class.free]).
end note
]
When the keyword delete in a delete-expression is preceded by the unary ​::​ operator, the deallocation function's name is looked up in global scope.
Otherwise, the lookup considers class-specific deallocation functions ([class.free]).
If no class-specific deallocation function is found, the deallocation function's name is looked up in global scope.
If deallocation function lookup finds more than one usual deallocation function, the function to be called is selected as follows:
  • If the type has new-extended alignment, a function with a parameter of type std​::​align_­val_­t is preferred; otherwise a function without such a parameter is preferred.
    If exactly one preferred function is found, that function is selected and the selection process terminates.
    If more than one preferred function is found, all non-preferred functions are eliminated from further consideration.
  • If the deallocation functions have class scope, the one without a parameter of type std​::​size_­t is selected.
  • If the type is complete and if, for the second alternative (delete array) only, the operand is a pointer to a class type with a non-trivial destructor or a (possibly multi-dimensional) array thereof, the function with a parameter of type std​::​size_­t is selected.
  • Otherwise, it is unspecified whether a deallocation function with a parameter of type std​::​size_­t is selected.
When a delete-expression is executed, the selected deallocation function shall be called with the address of the most-derived object in the delete object case, or the address of the object suitably adjusted for the array allocation overhead ([expr.new]) in the delete array case, as its first argument.
If a deallocation function with a parameter of type std​::​align_­val_­t is used, the alignment of the type of the object to be deleted is passed as the corresponding argument.
If a deallocation function with a parameter of type std​::​size_­t is used, the size of the most-derived type, or of the array plus allocation overhead, respectively, is passed as the corresponding argument.84
[Note
:
If this results in a call to a usual deallocation function, and either the first argument was not the result of a prior call to a usual allocation function or the second argument was not the corresponding argument in said call, the behavior is undefined ([new.delete.single], [new.delete.array]).
end note
]
Access and ambiguity control are done for both the deallocation function and the destructor ([class.dtor], [class.free]).
A lambda expression with a lambda-introducer that consists of empty square brackets can follow the delete keyword if the lambda expression is enclosed in parentheses.
This implies that an object cannot be deleted using a pointer of type void* because void is not an object type.
For nonzero-length arrays, this is the same as a pointer to the first element of the array created by that new-expression.
Zero-length arrays do not have a first element.
If the static type of the object to be deleted is complete and is different from the dynamic type, and the destructor is not virtual, the size might be incorrect, but that case is already undefined, as stated above.

8.3.6 Alignof [expr.alignof]

An alignof expression yields the alignment requirement of its operand type.
The operand shall be a type-id representing a complete object type, or an array thereof, or a reference to one of those types.
The result is an integral constant of type std​::​size_­t.
When alignof is applied to a reference type, the result is the alignment of the referenced type.
When alignof is applied to an array type, the result is the alignment of the element type.

8.3.7 noexcept operator [expr.unary.noexcept]

The noexcept operator determines whether the evaluation of its operand, which is an unevaluated operand (Clause [expr]), can throw an exception ([except.throw]).
The result of the noexcept operator is a constant of type bool and is a prvalue.
The result of the noexcept operator is true unless the expression is potentially-throwing ([except.spec]).

8.4 Explicit type conversion (cast notation) [expr.cast]

The result of the expression (T) cast-expression is of type T.
The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue.
[Note
:
If T is a non-class type that is cv-qualified, the cv-qualifiers are discarded when determining the type of the resulting prvalue; see Clause [expr].
end note
]
An explicit type conversion can be expressed using functional notation ([expr.type.conv]), a type conversion operator (dynamic_­cast, static_­cast, reinterpret_­cast, const_­cast), or the cast notation.
Any type conversion not mentioned below and not explicitly defined by the user ([class.conv]) is ill-formed.
The conversions performed by
can be performed using the cast notation of explicit type conversion.
The same semantic restrictions and behaviors apply, with the exception that in performing a static_­cast in the following situations the conversion is valid even if the base class is inaccessible:
  • a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;
  • a pointer to member of derived class type may be explicitly converted to a pointer to member of an unambiguous non-virtual base class type;
  • a pointer to an object of an unambiguous non-virtual base class type, a glvalue of an unambiguous non-virtual base class type, or a pointer to member of an unambiguous non-virtual base class type may be explicitly converted to a pointer, a reference, or a pointer to member of a derived class type, respectively.
If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed.
If a conversion can be interpreted in more than one way as a static_­cast followed by a const_­cast, the conversion is ill-formed.
[Example
:
struct A { };
struct I1 : A { };
struct I2 : A { };
struct D : I1, I2 { };
A* foo( D* p ) {
  return (A*)( p );             // ill-formed static_­cast interpretation
}
end example
]
The operand of a cast using the cast notation can be a prvalue of type “pointer to incomplete class type”.
The destination type of a cast using the cast notation can be “pointer to incomplete class type”.
If both the operand and destination types are class types and one or both are incomplete, it is unspecified whether the static_­cast or the reinterpret_­cast interpretation is used, even if there is an inheritance relationship between the two classes.
[Note
:
For example, if the classes were defined later in the translation unit, a multi-pass compiler would be permitted to interpret a cast between pointers to the classes as if the class types were complete at the point of the cast.
end note
]

8.5 Pointer-to-member operators [expr.mptr.oper]

The pointer-to-member operators ->* and .* group left-to-right.
The binary operator .* binds its second operand, which shall be of type “pointer to member of T” to its first operand, which shall be a glvalue of class T or of a class of which T is an unambiguous and accessible base class.
The result is an object or a function of the type specified by the second operand.
The binary operator ->* binds its second operand, which shall be of type “pointer to member of T” to its first operand, which shall be of type “pointer to U” where U is either T or a class of which T is an unambiguous and accessible base class.
The expression E1->*E2 is converted into the equivalent form (*(E1)).*E2.
Abbreviating pm-expression.*cast-expression as E1.*E2, E1 is called the object expression.
If the dynamic type of E1 does not contain the member to which E2 refers, the behavior is undefined.
Otherwise, the expression E1 is sequenced before the expression E2.
The restrictions on cv-qualification, and the manner in which the cv-qualifiers of the operands are combined to produce the cv-qualifiers of the result, are the same as the rules for E1.E2 given in [expr.ref].
[Note
:
It is not possible to use a pointer to member that refers to a mutable member to modify a const class object.
For example,
struct S {
  S() : i(0) { }
  mutable int i;
};
void f()
{
const S cs;
int S::* pm = &S::i;            // pm refers to mutable member S​::​i
cs.*pm = 88;                    // ill-formed: cs is a const object
}
end note
]
If the result of .* or ->* is a function, then that result can be used only as the operand for the function call operator ().
[Example
:
(ptr_to_obj->*ptr_to_mfct)(10);
calls the member function denoted by ptr_­to_­mfct for the object pointed to by ptr_­to_­obj.
end example
]
In a .* expression whose object expression is an rvalue, the program is ill-formed if the second operand is a pointer to member function with ref-qualifier &.
In a .* expression whose object expression is an lvalue, the program is ill-formed if the second operand is a pointer to member function with ref-qualifier &&.
The result of a .* expression whose second operand is a pointer to a data member is an lvalue if the first operand is an lvalue and an xvalue otherwise.
The result of a .* expression whose second operand is a pointer to a member function is a prvalue.
If the second operand is the null member pointer value ([conv.mem]), the behavior is undefined.

8.6 Multiplicative operators [expr.mul]

The operands of * and / shall have arithmetic or unscoped enumeration type; the operands of % shall have integral or unscoped enumeration type.
The usual arithmetic conversions are performed on the operands and determine the type of the result.
The binary * operator indicates multiplication.
The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second.
If the second operand of / or % is zero the behavior is undefined.
For integral operands the / operator yields the algebraic quotient with any fractional part discarded;85 if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a; otherwise, the behavior of both a/b and a%b is undefined.
This is often called truncation towards zero.

8.7 Additive operators [expr.add]

The additive operators + and - group left-to-right.
The usual arithmetic conversions are performed for operands of arithmetic or enumeration type.
additive-expression:
	multiplicative-expression
	additive-expression + multiplicative-expression
	additive-expression - multiplicative-expression
For addition, either both operands shall have arithmetic or unscoped enumeration type, or one operand shall be a pointer to a completely-defined object type and the other shall have integral or unscoped enumeration type.
For subtraction, one of the following shall hold:
  • both operands have arithmetic or unscoped enumeration type; or
  • both operands are pointers to cv-qualified or cv-unqualified versions of the same completely-defined object type; or
  • the left operand is a pointer to a completely-defined object type and the right operand has integral or unscoped enumeration type.
The result of the binary + operator is the sum of the operands.
The result of the binary - operator is the difference resulting from the subtraction of the second operand from the first.
When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand.
If the expression P points to element x[i] of an array object x with n elements,86 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element if ; otherwise, the behavior is undefined.
Likewise, the expression P - J points to the (possibly-hypothetical) element if ; otherwise, the behavior is undefined.
When two pointers to elements of the same array object are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std​::​ptrdiff_­t in the <cstddef> header ([support.types]).
If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value ; otherwise, the behavior is undefined.
[Note
:
If the value is not in the range of representable values of type std​::​ptrdiff_­t, the behavior is undefined.
end note
]
For addition or subtraction, if the expressions P or Q have type “pointer to cv T”, where T and the array element type are not similar ([conv.qual]), the behavior is undefined.
[Note
:
In particular, a pointer to a base class cannot be used for pointer arithmetic when the array contains objects of a derived class type.
end note
]
If the value 0 is added to or subtracted from a null pointer value, the result is a null pointer value.
If two null pointer values are subtracted, the result compares equal to the value 0 converted to the type std​::​ptrdiff_­t.
An object that is not an array element is considered to belong to a single-element array for this purpose; see [expr.unary.op].
A pointer past the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical element x[n] for this purpose; see [basic.compound].

8.8 Shift operators [expr.shift]

The shift operators << and >> group left-to-right.
shift-expression:
	additive-expression
	shift-expression << additive-expression
	shift-expression >> additive-expression
The operands shall be of integral or unscoped enumeration type and integral promotions are performed.
The type of the result is that of the promoted left operand.
The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled.
If E1 has an unsigned type, the value of the result is , reduced modulo one more than the maximum value representable in the result type.
Otherwise, if E1 has a signed type and non-negative value, and is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.
The value of E1 >> E2 is E1 right-shifted E2 bit positions.
If E1 has an unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the integral part of the quotient of .
If E1 has a signed type and a negative value, the resulting value is implementation-defined.
The expression E1 is sequenced before the expression E2.

8.9 Relational operators [expr.rel]

The relational operators group left-to-right.
[Example
:
a<b<c means (a<b)<c and not (a<b)&&(b<c).
end example
]
The operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) all yield false or true.
The type of the result is bool.
The usual arithmetic conversions are performed on operands of arithmetic or enumeration type.
If both operands are pointers, pointer conversions ([conv.ptr]) and qualification conversions ([conv.qual]) are performed to bring them to their composite pointer type (Clause [expr]).
After conversions, the operands shall have the same type.
Comparing unequal pointers to objects87 is defined as follows:
  • If two pointers point to different elements of the same array, or to subobjects thereof, the pointer to the element with the higher subscript compares greater.
  • If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member compares greater provided the two members have the same access control (Clause [class.access]) and provided their class is not a union.
  • Otherwise, neither pointer compares greater than the other.
If two operands p and q compare equal ([expr.eq]), p<=q and p>=q both yield true and p<q and p>q both yield false.
Otherwise, if a pointer p compares greater than a pointer q, p>=q, p>q, q<=p, and q<p all yield true and p<=q, p<q, q>=p, and q>p all yield false.
Otherwise, the result of each of the operators is unspecified.
If both operands (after conversions) are of arithmetic or enumeration type, each of the operators shall yield true if the specified relationship is true and false if it is false.
An object that is not an array element is considered to belong to a single-element array for this purpose; see [expr.unary.op].
A pointer past the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical element x[n] for this purpose; see [basic.compound].

8.10 Equality operators [expr.eq]

The == (equal to) and the != (not equal to) operators group left-to-right.
The operands shall have arithmetic, enumeration, pointer, or pointer to member type, or type std​::​nullptr_­t.
The operators == and != both yield true or false, i.e., a result of type bool.
In each case below, the operands shall have the same type after the specified conversions have been applied.
If at least one of the operands is a pointer, pointer conversions ([conv.ptr]), function pointer conversions ([conv.fctptr]), and qualification conversions ([conv.qual]) are performed on both operands to bring them to their composite pointer type (Clause [expr]).
Comparing pointers is defined as follows:
  • If one pointer represents the address of a complete object, and another pointer represents the address one past the last element of a different complete object,88 the result of the comparison is unspecified.
  • Otherwise, if the pointers are both null, both point to the same function, or both represent the same address ([basic.compound]), they compare equal.
  • Otherwise, the pointers compare unequal.
If at least one of the operands is a pointer to member, pointer to member conversions ([conv.mem]) and qualification conversions ([conv.qual]) are performed on both operands to bring them to their composite pointer type (Clause [expr]).
Comparing pointers to members is defined as follows:
  • If two pointers to members are both the null member pointer value, they compare equal.
  • If only one of two pointers to members is the null member pointer value, they compare unequal.
  • If either is a pointer to a virtual member function, the result is unspecified.
  • If one refers to a member of class C1 and the other refers to a member of a different class C2, where neither is a base class of the other, the result is unspecified.
    [Example
    :
    struct A {};
    struct B : A { int x; };
    struct C : A { int x; };
    
    int A::*bx = (int(A::*))&B::x;
    int A::*cx = (int(A::*))&C::x;
    
    bool b1 = (bx == cx);   // unspecified
    
    end example
    ]
  • If both refer to (possibly different) members of the same union ([class.union]), they compare equal.
  • Otherwise, two pointers to members compare equal if they would refer to the same member of the same most derived object ([intro.object]) or the same subobject if indirection with a hypothetical object of the associated class type were performed, otherwise they compare unequal.
    [Example
    :
    struct B {
      int f();
    };
    struct L : B { };
    struct R : B { };
    struct D : L, R { };
    
    int (B::*pb)() = &B::f;
    int (L::*pl)() = pb;
    int (R::*pr)() = pb;
    int (D::*pdl)() = pl;
    int (D::*pdr)() = pr;
    bool x = (pdl == pdr);          // false
    bool y = (pb == pl);            // true
    
    end example
    ]
Two operands of type std​::​nullptr_­t or one operand of type std​::​nullptr_­t and the other a null pointer constant compare equal.
If two operands compare equal, the result is true for the == operator and false for the != operator.
If two operands compare unequal, the result is false for the == operator and true for the != operator.
Otherwise, the result of each of the operators is unspecified.
If both operands are of arithmetic or enumeration type, the usual arithmetic conversions are performed on both operands; each of the operators shall yield true if the specified relationship is true and false if it is false.
An object that is not an array element is considered to belong to a single-element array for this purpose; see [expr.unary.op].

8.11 Bitwise AND operator [expr.bit.and]

The usual arithmetic conversions are performed; the result is the bitwise AND function of the operands.
The operator applies only to integral or unscoped enumeration operands.

8.12 Bitwise exclusive OR operator [expr.xor]

The usual arithmetic conversions are performed; the result is the bitwise exclusive OR function of the operands.
The operator applies only to integral or unscoped enumeration operands.

8.13 Bitwise inclusive OR operator [expr.or]

The usual arithmetic conversions are performed; the result is the bitwise inclusive OR function of its operands.
The operator applies only to integral or unscoped enumeration operands.

8.14 Logical AND operator [expr.log.and]

The && operator groups left-to-right.
The operands are both contextually converted to bool (Clause [conv]).
The result is true if both operands are true and false otherwise.
Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
The result is a bool.
If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression.

8.15 Logical OR operator [expr.log.or]

The || operator groups left-to-right.
The operands are both contextually converted to bool (Clause [conv]).
It returns true if either of its operands is true, and false otherwise.
Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.
The result is a bool.
If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression.

8.16 Conditional operator [expr.cond]

Conditional expressions group right-to-left.
The first expression is contextually converted to bool (Clause [conv]).
It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression.
Only one of the second and third expressions is evaluated.
Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.
If either the second or the third operand has type void, one of the following shall hold:
  • The second or the third operand (but not both) is a (possibly parenthesized) throw-expression; the result is of the type and value category of the other.
    The conditional-expression is a bit-field if that operand is a bit-field.
  • Both the second and the third operands have type void; the result is of type void and is a prvalue.
    [Note
    :
    This includes the case where both operands are throw-expressions.
    end note
    ]
Otherwise, if the second and third operand are glvalue bit-fields of the same value category and of types cv1 T and cv2 T, respectively, the operands are considered to be of type cv T for the remainder of this section, where cv is the union of cv1 and cv2.
Otherwise, if the second and third operand have different types and either has (possibly cv-qualified) class type, or if both are glvalues of the same value category and the same type except for cv-qualification, an attempt is made to form an implicit conversion sequence ([over.best.ics]) from each of those operands to the type of the other.
[Note
:
Properties such as access, whether an operand is a bit-field, or whether a conversion function is deleted are ignored for that determination.
end note
]
Attempts are made to form an implicit conversion sequence from an operand expression E1 of type T1 to a target type related to the type T2 of the operand expression E2 as follows:
  • If E2 is an lvalue, the target type is “lvalue reference to T2”, subject to the constraint that in the conversion the reference must bind directly ([dcl.init.ref]) to an lvalue.
  • If E2 is an xvalue, the target type is “rvalue reference to T2”, subject to the constraint that the reference must bind directly.
  • If E2 is a prvalue or if neither of the conversion sequences above can be formed and at least one of the operands has (possibly cv-qualified) class type:
    • if T1 and T2 are the same class type (ignoring cv-qualification), or one is a base class of the other, and T2 is at least as cv-qualified as T1, the target type is T2,
    • otherwise, the target type is the type that E2 would have after applying the lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions.
Using this process, it is determined whether an implicit conversion sequence can be formed from the second operand to the target type determined for the third operand, and vice versa.
If both sequences can be formed, or one can be formed but it is the ambiguous conversion sequence, the program is ill-formed.
If no conversion sequence can be formed, the operands are left unchanged and further checking is performed as described below.
Otherwise, if exactly one conversion sequence can be formed, that conversion is applied to the chosen operand and the converted operand is used in place of the original operand for the remainder of this section.
[Note
:
The conversion might be ill-formed even if an implicit conversion sequence could be formed.
end note
]
If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.
Otherwise, the result is a prvalue.
If the second and third operands do not have the same type, and either has (possibly cv-qualified) class type, overload resolution is used to determine the conversions (if any) to be applied to the operands ([over.match.oper], [over.built]).
If the overload resolution fails, the program is ill-formed.
Otherwise, the conversions thus determined are applied, and the converted operands are used in place of the original operands for the remainder of this section.
Lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions are performed on the second and third operands.
After those conversions, one of the following shall hold:
  • The second and third operands have the same type; the result is of that type and the result object is initialized using the selected operand.
  • The second and third operands have arithmetic or enumeration type; the usual arithmetic conversions are performed to bring them to a common type, and the result is of that type.
  • One or both of the second and third operands have pointer type; pointer conversions ([conv.ptr]), function pointer conversions ([conv.fctptr]), and qualification conversions ([conv.qual]) are performed to bring them to their composite pointer type (Clause [expr]).
    The result is of the composite pointer type.
  • One or both of the second and third operands have pointer to member type; pointer to member conversions ([conv.mem]) and qualification conversions ([conv.qual]) are performed to bring them to their composite pointer type (Clause [expr]).
    The result is of the composite pointer type.
  • Both the second and third operands have type std​::​nullptr_­t or one has that type and the other is a null pointer constant.
    The result is of type std​::​nullptr_­t.

8.17 Throwing an exception [expr.throw]

A throw-expression is of type void.
Evaluating a throw-expression with an operand throws an exception ([except.throw]); the type of the exception object is determined by removing any top-level cv-qualifiers from the static type of the operand and adjusting the type from “array of T” or function type T to “pointer to T.
A throw-expression with no operand rethrows the currently handled exception ([except.handle]).
The exception is reactivated with the existing exception object; no new exception object is created.
The exception is no longer considered to be caught.
[Example
:
Code that must be executed because of an exception, but cannot completely handle the exception itself, can be written like this:
try {
    // ...
} catch (...) {     // catch all exceptions
  // respond (partially) to exception
  throw;            // pass the exception to some other handler
}
end example
]
If no exception is presently being handled, evaluating a throw-expression with no operand calls std​::​​terminate() ([except.terminate]).

8.18 Assignment and compound assignment operators [expr.ass]

The assignment operator (=) and the compound assignment operators all group right-to-left.
All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.
The result in all cases is a bit-field if the left operand is a bit-field.
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
The right operand is sequenced before the left operand.
With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation.
[Note
:
Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single compound assignment operator.
end note
]
In simple assignment (=), the value of the expression replaces that of the object referred to by the left operand.
If the left operand is not of class type, the expression is implicitly converted (Clause [conv]) to the cv-unqualified type of the left operand.
If the left operand is of class type, the class shall be complete.
Assignment to objects of a class is defined by the copy/move assignment operator ([class.copy], [over.ass]).
[Note
:
For class objects, assignment is not in general the same as initialization ([dcl.init], [class.ctor], [class.init], [class.copy]).
end note
]
When the left operand of an assignment operator is a bit-field that cannot represent the value of the expression, the resulting value of the bit-field is implementation-defined.
The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.
In += and -=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type.
In all other cases, E1 shall have arithmetic type.
If the value being stored in an object is read via another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have the same type, otherwise the behavior is undefined.
[Note
:
This restriction applies to the relationship between the left and right sides of the assignment operation; it is not a statement about how the target of the assignment may be aliased in general.
end note
]
A braced-init-list may appear on the right-hand side of
  • an assignment to a scalar, in which case the initializer list shall have at most a single element.
    The meaning of x = {v}, where T is the scalar type of the expression x, is that of x = T{v}.
    The meaning of x = {} is x = T{}.
  • an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution ([over.ass], [over.match]).
[Example
:
complex<double> z;
z = { 1,2 };              // meaning z.operator=({1,2})
z += { 1, 2 };            // meaning z.operator+=({1,2})
int a, b;
a = b = { 1 };            // meaning a=b=1;
a = { 1 } = b;            // syntax error
end example
]

8.19 Comma operator [expr.comma]

The comma operator groups left-to-right.
expression:
	assignment-expression
	expression , assignment-expression
A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded-value expression (Clause [expr]).
Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression.
The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand, and is a bit-field if its right operand is a bit-field.
If the right operand is a temporary expression ([class.temporary]), the result is a temporary expression.
In contexts where comma is given a special meaning,
[Example
:
in lists of arguments to functions ([expr.call]) and lists of initializers ([dcl.init])
end example
]
the comma operator as described in Clause [expr] can appear only in parentheses.
[Example
:
f(a, (t=3, t+2), c);
has three arguments, the second of which has the value 5.
end example
]

8.20 Constant expressions [expr.const]

Certain contexts require expressions that satisfy additional requirements as detailed in this subclause; other contexts have different semantics depending on whether or not an expression satisfies these requirements.
Expressions that satisfy these requirements, assuming that copy elision is performed, are called constant expressions.
[Note
:
Constant expressions can be evaluated during translation.
end note
]
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following expressions:
  • this ([expr.prim.this]), except in a constexpr function or a constexpr constructor that is being evaluated as part of e;
  • an invocation of a function other than a constexpr constructor for a literal class, a constexpr function, or an implicit invocation of a trivial destructor ([class.dtor])
    [Note
    :
    Overload resolution ([over.match]) is applied as usual
    end note
    ]
    ;
  • an invocation of an undefined constexpr function or an undefined constexpr constructor;
  • an invocation of an instantiated constexpr function or constexpr constructor that fails to satisfy the requirements for a constexpr function or constexpr constructor ([dcl.constexpr]);
  • an expression that would exceed the implementation-defined limits (see Annex [implimits]);
  • an operation that would have undefined behavior as specified in Clauses [intro] through [cpp] of this International Standard
    [Note
    :
    including, for example, signed integer overflow (Clause [expr]), certain pointer arithmetic ([expr.add]), division by zero ([expr.mul]), or certain shift operations ([expr.shift])
    end note
    ]
    ;
  • an lvalue-to-rvalue conversion ([conv.lval]) unless it is applied to
    • a non-volatile glvalue of integral or enumeration type that refers to a complete non-volatile const object with a preceding initialization, initialized with a constant expression, or
    • a non-volatile glvalue that refers to a subobject of a string literal ([lex.string]), or
    • a non-volatile glvalue that refers to a non-volatile object defined with constexpr, or that refers to a non-mutable subobject of such an object, or
    • a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;
  • an lvalue-to-rvalue conversion ([conv.lval]) that is applied to a glvalue that refers to a non-active member of a union or a subobject thereof;
  • an invocation of an implicitly-defined copy/move constructor or copy/move assignment operator for a union whose active member (if any) is mutable, unless the lifetime of the union object began within the evaluation of e;
  • an assignment expression ([expr.ass]) or invocation of an assignment operator ([class.copy]) that would change the active member of a union;
  • an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either
    • it is initialized with a constant expression or
    • its lifetime began within the evaluation of e;
  • in a lambda-expression, a reference to this or to a variable with automatic storage duration defined outside that lambda-expression, where the reference would be an odr-use ([basic.def.odr], [expr.prim.lambda]);
    [Example
    :
    void g() {
      const int n = 0;
      [=] {
        constexpr int i = n;   // OK, n is not odr-used and not captured here
        constexpr int j = *&n; // ill-formed, &n would be an odr-use of n
      };
    }
    end example
    ]
    [Note
    :
    If the odr-use occurs in an invocation of a function call operator of a closure type, it no longer refers to this or to an enclosing automatic variable due to the transformation ([expr.prim.lambda.capture]) of the id-expression into an access of the corresponding data member.
    [Example
    :
    auto monad = [](auto v) { return [=] { return v; }; };
    auto bind = [](auto m) {
      return [=](auto fvm) { return fvm(m()); };
    };
    
    // OK to have captures to automatic objects created during constant expression evaluation.
    static_assert(bind(monad(2))(monad)() == monad(2)());
    end example
    ]
    end note
    ]
  • a conversion from type cv void* to a pointer-to-object type;
  • a dynamic cast ([expr.dynamic.cast]);
  • a reinterpret_­cast ([expr.reinterpret.cast]);
  • a pseudo-destructor call ([expr.pseudo]);
  • modification of an object ([expr.ass], [expr.post.incr], [expr.pre.incr]) unless it is applied to a non-volatile lvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;
  • a typeid expression ([expr.typeid]) whose operand is a glvalue of a polymorphic class type;
  • a relational ([expr.rel]) or equality ([expr.eq]) operator where the result is unspecified; or
If e satisfies the constraints of a core constant expression, but evaluation of e would evaluate an operation that has undefined behavior as specified in Clauses [library] through [thread] of this International Standard, it is unspecified whether e is a core constant expression.
[Example
:
int x;                              // not constant
struct A {
  constexpr A(bool b) : m(b?42:x) { }
  int m;
};
constexpr int v = A(true).m;        // OK: constructor call initializes m with the value 42

constexpr int w = A(false).m;       // error: initializer for m is x, which is non-constant

constexpr int f1(int k) {
  constexpr int x = k;              // error: x is not initialized by a constant expression
                                    // because lifetime of k began outside the initializer of x
  return x;
}
constexpr int f2(int k) {
  int x = k;                        // OK: not required to be a constant expression
                                    // because x is not constexpr
  return x;
}

constexpr int incr(int &n) {
  return ++n;
}
constexpr int g(int k) {
  constexpr int x = incr(k);        // error: incr(k) is not a core constant expression
                                    // because lifetime of k began outside the expression incr(k)
  return x;
}
constexpr int h(int k) {
  int x = incr(k);                  // OK: incr(k) is not required to be a core constant expression
  return x;
}
constexpr int y = h(1);             // OK: initializes y with the value 2
                                    // h(1) is a core constant expression because
                                    // the lifetime of k begins inside h(1)
end example
]
An integral constant expression is an expression of integral or unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression.
[Note
:
Such expressions may be used as bit-field lengths ([class.bit]), as enumerator initializers if the underlying type is not fixed ([dcl.enum]), and as alignments ([dcl.align]).
end note
]
A converted constant expression of type T is an expression, implicitly converted to type T, where the converted expression is a constant expression and the implicit conversion sequence contains only
and where the reference binding (if any) binds directly.
[Note
:
Such expressions may be used in new expressions ([expr.new]), as case expressions ([stmt.switch]), as enumerator initializers if the underlying type is fixed ([dcl.enum]), as array bounds ([dcl.array]), and as non-type template arguments ([temp.arg]).
end note
]
A contextually converted constant expression of type bool is an expression, contextually converted to bool (Clause[conv]), where the converted expression is a constant expression and the conversion sequence contains only the conversions above.
A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints:
  • if the value is an object of class type, each non-static data member of reference type refers to an entity that is a permitted result of a constant expression,
  • if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object ([expr.add]), the address of a function, or a null pointer value, and
  • if the value is an object of class or array type, each subobject satisfies these constraints for the value.
An entity is a permitted result of a constant expression if it is an object with static storage duration that is either not a temporary object or is a temporary object whose value satisfies the above constraints, or it is a function.
[Note
:
Since this International Standard imposes no restrictions on the accuracy of floating-point operations, it is unspecified whether the evaluation of a floating-point expression during translation yields the same result as the evaluation of the same expression (or the same operations on the same values) during program execution.89
[Example
:
bool f() {
    char array[1 + int(1 + 0.2 - 0.1 - 0.1)];  // Must be evaluated during translation
    int size = 1 + int(1 + 0.2 - 0.1 - 0.1);   // May be evaluated at runtime
    return sizeof(array) == size;
}
It is unspecified whether the value of f() will be true or false.
end example
]
end note
]
If an expression of literal class type is used in a context where an integral constant expression is required, then that expression is contextually implicitly converted (Clause [conv]) to an integral or unscoped enumeration type and the selected conversion function shall be constexpr.
[Example
:
struct A {
  constexpr A(int i) : val(i) { }
  constexpr operator int() const { return val; }
  constexpr operator long() const { return 43; }
private:
  int val;
};
template<int> struct X { };
constexpr A a = 42;
X<a> x;             // OK: unique conversion to int
int ary[a];         // error: ambiguous conversion
end example
]
Nonetheless, implementations are encouraged to provide consistent results, irrespective of whether the evaluation was performed during translation and/or during program execution.

9 Statements [stmt.stmt]

The rules for conditions apply both to selection-statements and to the for and while statements ([stmt.iter]).
The declarator shall not specify a function or an array.
The decl-specifier-seq shall not define a class or enumeration.
If the auto type-specifier appears in the decl-specifier-seq, the type of the identifier being declared is deduced from the initializer as described in [dcl.spec.auto].
A name introduced by a declaration in a condition (either introduced by the decl-specifier-seq or the declarator of the condition) is in scope from its point of declaration until the end of the substatements controlled by the condition.
If the name is redeclared in the outermost block of a substatement controlled by the condition, the declaration that redeclares the name is ill-formed.
[Example
:
if (int x = f()) {
  int x;            // ill-formed, redeclaration of x
}
else {
  int x;            // ill-formed, redeclaration of x
}
end example
]
The value of a condition that is an initialized declaration in a statement other than a switch statement is the value of the declared variable contextually converted to bool (Clause [conv]).
If that conversion is ill-formed, the program is ill-formed.
The value of a condition that is an initialized declaration in a switch statement is the value of the declared variable if it has integral or enumeration type, or of that variable implicitly converted to integral or enumeration type otherwise.
The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch; if that conversion is ill-formed, the program is ill-formed.
The value of the condition will be referred to as simply “the condition” where the usage is unambiguous.
If a condition can be syntactically resolved as either an expression or the declaration of a block-scope name, it is interpreted as a declaration.
In the decl-specifier-seq of a condition, each decl-specifier shall be either a type-specifier or constexpr.

9.1 Labeled statement [stmt.label]

A statement can be labeled.
An identifier label declares the identifier.
The only use of an identifier label is as the target of a goto.
The scope of a label is the function in which it appears.
Labels shall not be redeclared within a function.
A label can be used in a goto statement before its declaration.
Labels have their own name space and do not interfere with other identifiers.
[Note
:
A label may have the same name as another declaration in the same scope or a template-parameter from an enclosing scope.
Unqualified name lookup ([basic.lookup.unqual]) ignores labels.
end note
]
Case labels and default labels shall occur only in switch statements.

9.2 Expression statement [stmt.expr]

Expression statements have the form
expression-statement:
	expression ;
The expression is a discarded-value expression (Clause [expr]).
All side effects from an expression statement are completed before the next statement is executed.
An expression statement with the expression missing is called a null statement.
[Note
:
Most statements are expression statements — usually assignments or function calls.
A null statement is useful to carry a label just before the } of a compound statement and to supply a null body to an iteration statement such as a while statement ([stmt.while]).
end note
]

9.3 Compound statement or block [stmt.block]

So that several statements can be used where one is expected, the compound statement (also, and equivalently, called “block”) is provided.
[Note
:
A declaration is a statement ([stmt.dcl]).
end note
]

9.4 Selection statements [stmt.select]

Selection statements choose one of several flows of control.
[Note
:
An init-statement ends with a semicolon.
end note
]
In Clause [stmt.stmt], the term substatement refers to the contained statement or statements that appear in the syntax notation.
The substatement in a selection-statement (each substatement, in the else form of the if statement) implicitly defines a block scope ([basic.scope]).
If the substatement in a selection-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original substatement.
[Example
:
if (x)
  int i;
can be equivalently rewritten as
if (x) {
  int i;
}
Thus after the if statement, i is no longer in scope.
end example
]

9.4.1 The if statement [stmt.if]

If the condition ([stmt.select]) yields true the first substatement is executed.
If the else part of the selection statement is present and the condition yields false, the second substatement is executed.
If the first substatement is reached via a label, the condition is not evaluated and the second substatement is not executed.
In the second form of if statement (the one including else), if the first substatement is also an if statement then that inner if statement shall contain an else part.90
If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool ([expr.const]); this form is called a constexpr if statement.
If the value of the converted condition is false, the first substatement is a discarded statement, otherwise the second substatement, if present, is a discarded statement.
During the instantation of an enclosing templated entity (Clause [temp]), if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
[Note
:
Odr-uses ([basic.def.odr]) in a discarded statement do not require an entity to be defined.
end note
]
A case or default label appearing within such an if statement shall be associated with a switch statement ([stmt.switch]) within the same if statement.
A label ([stmt.label]) declared in a substatement of a constexpr if statement shall only be referred to by a statement ([stmt.goto]) in the same substatement.
[Example
:
template<typename T, typename ... Rest> void g(T&& p, Rest&& ...rs) {
  // ... handle p

  if constexpr (sizeof...(rs) > 0)
    g(rs...);       // never instantiated with an empty argument list
}

extern int x;       // no definition of x required

int f() {
  if constexpr (true)
    return 0;
  else if (x)
    return x;
  else
    return -x;
}
end example
]
An if statement of the form
if constexpr ( init-statement condition ) statement
is equivalent to
{
	init-statement
	if constexpr ( condition ) statement
}
and an if statement of the form
if constexpr ( init-statement condition ) statement else statement
is equivalent to
{
	init-statement
	if constexpr ( condition ) statement else statement
}
except that names declared in the init-statement are in the same declarative region as those declared in the condition.
In other words, the else is associated with the nearest un-elsed if.

9.4.2 The switch statement [stmt.switch]

The switch statement causes control to be transferred to one of several statements depending on the value of a condition.
The condition shall be of integral type, enumeration type, or class type.
If of class type, the condition is contextually implicitly converted (Clause [conv]) to an integral or enumeration type.
If the (possibly converted) type is subject to integral promotions ([conv.prom]), the condition is converted to the promoted type.
Any statement within the switch statement can be labeled with one or more case labels as follows:
case constant-expression :
where the constant-expression shall be a converted constant expression ([expr.const]) of the adjusted type of the switch condition.
No two of the case constants in the same switch shall have the same value after conversion.
There shall be at most one label of the form
default :
within a switch statement.
Switch statements can be nested; a case or default label is associated with the smallest switch enclosing it.
When the switch statement is executed, its condition is evaluated and compared with each case constant.
If one of the case constants is equal to the value of the condition, control is passed to the statement following the matched case label.
If no case constant matches the condition, and if there is a default label, control passes to the statement labeled by the default label.
If no case matches and if there is no default then none of the statements in the switch is executed.
case and default labels in themselves do not alter the flow of control, which continues unimpeded across such labels.
To exit from a switch, see break, [stmt.break].
[Note
:
Usually, the substatement that is the subject of a switch is compound and case and default labels appear on the top-level statements contained within the (compound) substatement, but this is not required.
Declarations can appear in the substatement of a switch statement.
end note
]
A switch statement of the form
switch ( init-statement condition ) statement
is equivalent to
{
	init-statement
	switch ( condition ) statement
}
except that names declared in the init-statement are in the same declarative region as those declared in the condition.

9.5 Iteration statements [stmt.iter]

The substatement in an iteration-statement implicitly defines a block scope ([basic.scope]) which is entered and exited each time through the loop.
If the substatement in an iteration-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original statement.
[Example
:
while (--x >= 0)
  int i;
can be equivalently rewritten as
while (--x >= 0) {
  int i;
}
Thus after the while statement, i is no longer in scope.
end example
]
If a name introduced in an init-statement or for-range-declaration is redeclared in the outermost block of the substatement, the program is ill-formed.
[Example
:
void f() {
  for (int i = 0; i < 10; ++i)
    int i = 0;          // error: redeclaration
  for (int i : { 1, 2, 3 })
    int i = 1;          // error: redeclaration
}
end example
]

9.5.1 The while statement [stmt.while]

In the while statement the substatement is executed repeatedly until the value of the condition ([stmt.select]) becomes false.
The test takes place before each execution of the substatement.
When the condition of a while statement is a declaration, the scope of the variable that is declared extends from its point of declaration ([basic.scope.pdecl]) to the end of the while statement.
A while statement of the form
while (T t = x) statement
is equivalent to
label:
{                   // start of condition scope
  T t = x;
  if (t) {
    statement
    goto label;
  }
}                   // end of condition scope
The variable created in a condition is destroyed and created with each iteration of the loop.
[Example
:
struct A {
  int val;
  A(int i) : val(i) { }
  ~A() { }
  operator bool() { return val != 0; }
};
int i = 1;
while (A a = i) {
  // ...
  i = 0;
}
In the while-loop, the constructor and destructor are each called twice, once for the condition that succeeds and once for the condition that fails.
end example
]

9.5.2 The do statement [stmt.do]

The expression is contextually converted to bool (Clause [conv]); if that conversion is ill-formed, the program is ill-formed.
In the do statement the substatement is executed repeatedly until the value of the expression becomes false.
The test takes place after each execution of the statement.

9.5.3 The for statement [stmt.for]

The for statement
for ( init-statement condition ; expression ) statement
is equivalent to
{
	init-statement
	while ( condition ) {
		statement
		expression ;
	}
}
except that names declared in the init-statement are in the same declarative region as those declared in the condition, and except that a continue in statement (not enclosed in another iteration statement) will execute expression before re-evaluating condition.
[Note
:
Thus the first statement specifies initialization for the loop; the condition ([stmt.select]) specifies a test, sequenced before each iteration, such that the loop is exited when the condition becomes false; the expression often specifies incrementing that is sequenced after each iteration.
end note
]
Either or both of the condition and the expression can be omitted.
A missing condition makes the implied while clause equivalent to while(true).
If the init-statement is a declaration, the scope of the name(s) declared extends to the end of the for statement.
[Example
:
int i = 42;
int a[10];

for (int i = 0; i < 10; i++)
  a[i] = i;

int j = i;          // j = 42
end example
]

9.5.4 The range-based for statement [stmt.ranged]

The range-based for statement
for ( for-range-declaration : for-range-initializer ) statement
is equivalent to
{
	auto &&__range = for-range-initializer ;
	auto __begin = begin-expr ;
	auto __end = end-expr ;
	for ( ; __begin != __end; ++__begin ) {
		for-range-declaration = *__begin;
		statement
	}
}
where
  • if the for-range-initializer is an expression, it is regarded as if it were surrounded by parentheses (so that a comma operator cannot be reinterpreted as delimiting two init-declarators);
  • _­_­range, _­_­begin, and _­_­end are variables defined for exposition only; and
  • begin-expr and end-expr are determined as follows:
    • if the for-range-initializer is an expression of array type R, begin-expr and end-expr are _­_­range and _­_­range + _­_­bound, respectively, where _­_­bound is the array bound.
      If R is an array of unknown bound or an array of incomplete type, the program is ill-formed;
    • if the for-range-initializer is an expression of class type C, the unqualified-ids begin and end are looked up in the scope of C as if by class member access lookup ([basic.lookup.classref]), and if either (or both) finds at least one declaration, begin-expr and end-expr are _­_­range.begin() and _­_­range.end(), respectively;
    • otherwise, begin-expr and end-expr are begin(_­_­range) and end(_­_­range), respectively, where begin and end are looked up in the associated namespaces ([basic.lookup.argdep]).
      [Note
      :
      Ordinary unqualified lookup ([basic.lookup.unqual]) is not performed.
      end note
      ]
[Example
:
int array[5] = { 1, 2, 3, 4, 5 };
for (int& x : array)
  x *= 2;
end example
]
In the decl-specifier-seq of a for-range-declaration, each decl-specifier shall be either a type-specifier or constexpr.
The decl-specifier-seq shall not define a class or enumeration.

9.6 Jump statements [stmt.jump]

Jump statements unconditionally transfer control.
jump-statement:
	break ;
	continue ;
	return expr-or-braced-init-list ;
	goto identifier ;
On exit from a scope (however accomplished), objects with automatic storage duration ([basic.stc.auto]) that have been constructed in that scope are destroyed in the reverse order of their construction.
[Note
:
For temporaries, see [class.temporary].
end note
]
Transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction of objects with automatic storage duration that are in scope at the point transferred from but not at the point transferred to.
(See [stmt.dcl] for transfers into blocks).
[Note
:
However, the program can be terminated (by calling std​::​exit() or std​::​abort() ([support.start.term]), for example) without destroying class objects with automatic storage duration.
end note
]

9.6.1 The break statement [stmt.break]

The break statement shall occur only in an iteration-statement or a switch statement and causes termination of the smallest enclosing iteration-statement or switch statement; control passes to the statement following the terminated statement, if any.

9.6.2 The continue statement [stmt.cont]

The continue statement shall occur only in an iteration-statement and causes control to pass to the loop-continuation portion of the smallest enclosing iteration-statement, that is, to the end of the loop.
More precisely, in each of the statements
while (foo) {
  {
    // ...
  }
contin: ;
}
do {
  {
    // ...
  }
contin: ;
} while (foo);
for (;;) {
  {
    // ...
  }
contin: ;
}
a continue not contained in an enclosed iteration statement is equivalent to goto contin.

9.6.3 The return statement [stmt.return]

A function returns to its caller by the return statement.
The expr-or-braced-init-list of a return statement is called its operand.
A return statement with no operand shall be used only in a function whose return type is cv void, a constructor ([class.ctor]), or a destructor ([class.dtor]).
A return statement with an operand of type void shall be used only in a function whose return type is cv void.
A return statement with any other operand shall be used only in a function whose return type is not cv void; the return statement initializes the glvalue result or prvalue result object of the (explicit or implicit) function call by copy-initialization ([dcl.init]) from the operand.
[Note
:
A return statement can involve an invocation of a constructor to perform a copy or move of the operand if it is not a prvalue or if its type differs from the return type of the function.
A copy operation associated with a return statement may be elided or converted to a move operation if an automatic storage duration variable is returned ([class.copy]).
end note
]
[Example
:
std::pair<std::string,int> f(const char* p, int x) {
  return {p,x};
}
end example
]
Flowing off the end of a constructor, a destructor, or a function with a cv void return type is equivalent to a return with no operand.
Otherwise, flowing off the end of a function other than main ([basic.start.main]) results in undefined behavior.
The copy-initialization of the result of the call is sequenced before the destruction of temporaries at the end of the full-expression established by the operand of the return statement, which, in turn, is sequenced before the destruction of local variables ([stmt.jump]) of the block enclosing the return statement.

9.6.4 The goto statement [stmt.goto]

The goto statement unconditionally transfers control to the statement labeled by the identifier.
The identifier shall be a label ([stmt.label]) located in the current function.

9.7 Declaration statement [stmt.dcl]

A declaration statement introduces one or more new identifiers into a block; it has the form
declaration-statement:
	block-declaration
If an identifier introduced by a declaration was previously declared in an outer block, the outer declaration is hidden for the remainder of the block, after which it resumes its force.
Variables with automatic storage duration ([basic.stc.auto]) are initialized each time their declaration-statement is executed.
Variables with automatic storage duration declared in the block are destroyed on exit from the block ([stmt.jump]).
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization.
A program that jumps91 from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer.
[Example
:
void f() {
  // ...
  goto lx;          // ill-formed: jump into scope of a
  // ...
ly:
  X a = 1;
  // ...
lx:
  goto ly;          // OK, jump implies destructor call for a followed by
                    // construction again immediately following label ly
}
end example
]
Dynamic initialization of a block-scope variable with static storage duration ([basic.stc.static]) or thread storage duration ([basic.stc.thread]) is performed the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization.
If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration.
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.92
If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
[Example
:
int foo(int i) {
  static int s = foo(2*i);      // recursive call - undefined
  return i+1;
}
end example
]
The destructor for a block-scope object with static or thread storage duration will be executed if and only if it was constructed.
[Note
:
[basic.start.term] describes the order in which block-scope objects with static and thread storage duration are destroyed.
end note
]
The transfer from the condition of a switch statement to a case label is considered a jump in this respect.
The implementation must not introduce any deadlock around execution of the initializer.
Deadlocks might still be caused by the program logic; the implementation need only avoid deadlocks due to its own synchronization operations.

9.8 Ambiguity resolution [stmt.ambig]

There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion ([expr.type.conv]) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (.
In those cases the statement is a declaration.
[Note
:
If the statement cannot syntactically be a declaration, there is no ambiguity, so this rule does not apply.
The whole statement might need to be examined to determine whether this is the case.
This resolves the meaning of many examples.
[Example
:
Assuming T is a simple-type-specifier ([dcl.type]),
T(a)->m = 7;        // expression-statement
T(a)++;             // expression-statement
T(a,5)<<c;          // expression-statement

T(*d)(int);         //  declaration
T(e)[5];            //  declaration
T(f) = { 1, 2 };    //  declaration
T(*g)(double(3));   //  declaration
In the last example above, g, which is a pointer to T, is initialized to double(3).
This is of course ill-formed for semantic reasons, but that does not affect the syntactic analysis.
end example
]
The remaining cases are declarations.
[Example
:
class T {
  // ...
public:
  T();
  T(int);
  T(int, int);
};
T(a);               //  declaration
T(*b)();            //  declaration
T(c)=7;             //  declaration
T(d),e,f=3;         //  declaration
extern int h;
T(g)(h,2);          //  declaration
end example
]
end note
]
The disambiguation is purely syntactic; that is, the meaning of the names occurring in such a statement, beyond whether they are type-names or not, is not generally used in or changed by the disambiguation.
Class templates are instantiated as necessary to determine if a qualified name is a type-name.
Disambiguation precedes parsing, and a statement disambiguated as a declaration may be an ill-formed declaration.
If, during parsing, a name in a template parameter is bound differently than it would be bound during a trial parse, the program is ill-formed.
No diagnostic is required.
[Note
:
This can occur only when the name is declared earlier in the declaration.
end note
]
[Example
:
struct T1 {
  T1 operator()(int x) { return T1(x); }
  int operator=(int x) { return x; }
  T1(int) { }
};
struct T2 { T2(int){ } };
int a, (*(*b)(T2))(int), c, d;

void f() {
  // disambiguation requires this to be parsed as a declaration:
  T1(a) = 3,
  T2(4),                        // T2 will be declared as a variable of type T1, but this will not
  (*(*b)(T2(c)))(int(d));       // allow the last part of the declaration to parse properly,
                                // since it depends on T2 being a type-name
}
end example
]

10 Declarations [dcl.dcl]

Declarations generally specify how names are to be interpreted.
Declarations have the form
Attributes are described in [dcl.attr].
decl-specifiers, the principal components of a decl-specifier-seq, are described in [dcl.spec].
declarators, the components of an init-declarator-list, are described in Clause [dcl.decl].
The attribute-specifier-seq appertains to each of the entities declared by the declarators of the init-declarator-list.
[Note
:
In the declaration for an entity, attributes appertaining to that entity may appear at the start of the declaration and after the declarator-id for that declaration.
end note
]
[Example
:
[[noreturn]] void f [[noreturn]] ();    // OK
end example
]
Except where otherwise specified, the meaning of an attribute-declaration is implementation-defined.
A declaration occurs in a scope ([basic.scope]); the scope rules are summarized in [basic.lookup].
A declaration that declares a function or defines a class, namespace, template, or function also has one or more scopes nested within it.
These nested scopes, in turn, can have declarations nested within them.
Unless otherwise stated, utterances in Clause [dcl.dcl] about components in, of, or contained by a declaration or subcomponent thereof refer only to those components of the declaration that are not nested within scopes nested within the declaration.
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause [class]) or enumeration ([dcl.enum]), that is, when the decl-specifier-seq contains either a class-specifier, an elaborated-type-specifier with a class-key ([class.name]), or an enum-specifier.
In these cases and whenever a class-specifier or enum-specifier is present in the decl-specifier-seq, the identifiers in these specifiers are among the names being declared by the declaration (as class-names, enum-names, or enumerators, depending on the syntax).
In such cases, the decl-specifier-seq shall introduce one or more names into the program, or shall redeclare a name introduced by a previous declaration.
[Example
:
enum { };           // ill-formed
typedef class { };  // ill-formed
end example
]
In a static_assert-declaration, the constant-expression shall be a contextually converted constant expression of type bool ([expr.const]).
If the value of the expression when so converted is true, the declaration has no effect.
Otherwise, the program is ill-formed, and the resulting diagnostic message ([intro.compliance]) shall include the text of the string-literal, if one is supplied, except that characters not in the basic source character set ([lex.charset]) are not required to appear in the diagnostic message.
[Example
:
static_assert(char(-1) < 0, "this library requires plain 'char' to be signed");
end example
]
An empty-declaration has no effect.
The decl-specifier-seq shall contain only the type-specifier auto ([dcl.spec.auto]) and cv-qualifiers.
The initializer shall be of the form “= assignment-expression”, of the form “{ assignment-expression }”, or of the form “( assignment-expression )”, where the assignment-expression is of array or non-union class type.
Each init-declarator in the init-declarator-list contains exactly one declarator-id, which is the name declared by that init-declarator and hence one of the names declared by the declaration.
The defining-type-specifiers in the decl-specifier-seq and the recursive declarator structure of the init-declarator describe a type ([dcl.meaning]), which is then associated with the name being declared by the init-declarator.
If the decl-specifier-seq contains the typedef specifier, the declaration is called a typedef declaration and the name of each init-declarator is declared to be a typedef-name, synonymous with its associated type ([dcl.typedef]).
If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with the name is a function type ([dcl.fct]) and an object declaration otherwise.
Syntactic components beyond those found in the general form of declaration are added to a function declaration to make a function-definition.
An object declaration, however, is also a definition unless it contains the extern specifier and has no initializer ([basic.def]).
A definition causes the appropriate amount of storage to be reserved and any appropriate initialization ([dcl.init]) to be done.
A nodeclspec-function-declaration shall declare a constructor, destructor, or conversion function.93
[Note
:
A nodeclspec-function-declaration can only be used in a template-declaration (Clause [temp]), explicit-instantiation ([temp.explicit]), or explicit-specialization ([temp.expl.spec]).
end note
]
The “implicit int” rule of C is no longer supported.

10.1 Specifiers [dcl.spec]

The specifiers that can be used in a declaration are
The attribute-specifier-seq affects the type only for the declaration it appears in, not other declarations involving the same type.
Each decl-specifier shall appear at most once in a complete decl-specifier-seq, except that long may appear twice.
If a type-name is encountered while parsing a decl-specifier-seq, it is interpreted as part of the decl-specifier-seq if and only if there is no previous defining-type-specifier other than a cv-qualifier in the decl-specifier-seq.
The sequence shall be self-consistent as described below.
[Example
:
typedef char* Pc;
static Pc;                      // error: name missing
Here, the declaration static Pc is ill-formed because no name was specified for the static variable of type Pc.
To get a variable called Pc, a type-specifier (other than const or volatile) has to be present to indicate that the typedef-name Pc is the name being (re)declared, rather than being part of the decl-specifier sequence.
For another example,
void f(const Pc);               // void f(char* const) (not const char*)
void g(const int Pc);           // void g(const int)
end example
]
[Note
:
Since signed, unsigned, long, and short by default imply int, a type-name appearing after one of those specifiers is treated as the name being (re)declared.
[Example
:
void h(unsigned Pc);            // void h(unsigned int)
void k(unsigned int Pc);        // void k(unsigned int)
end example
]
end note
]

10.1.1 Storage class specifiers [dcl.stc]

The storage class specifiers are
storage-class-specifier:
	static
	thread_local
	extern
	mutable
At most one storage-class-specifier shall appear in a given decl-specifier-seq, except that thread_­local may appear with static or extern.
If thread_­local appears in any declaration of a variable it shall be present in all declarations of that entity.
If a storage-class-specifier appears in a decl-specifier-seq, there can be no typedef specifier in the same decl-specifier-seq and the init-declarator-list or member-declarator-list of the declaration shall not be empty (except for an anonymous union declared in a named namespace or in the global namespace, which shall be declared static ([class.union.anon])).
The storage-class-specifier applies to the name declared by each init-declarator in the list and not to any names declared by other specifiers.
A storage-class-specifier other than thread_­local shall not be specified in an explicit specialization ([temp.expl.spec]) or an explicit instantiation ([temp.explicit]) directive.
[Note
:
A variable declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default ([basic.stc.auto]).
end note
]
The thread_­local specifier indicates that the named entity has thread storage duration ([basic.stc.thread]).
It shall be applied only to the names of variables of namespace or block scope and to the names of static data members.
When thread_­local is applied to a variable of block scope the storage-class-specifier static is implied if no other storage-class-specifier appears in the decl-specifier-seq.
The static specifier can be applied only to names of variables and functions and to anonymous unions ([class.union.anon]).
There can be no static function declarations within a block, nor any static function parameters.
A static specifier used in the declaration of a variable declares the variable to have static storage duration ([basic.stc.static]), unless accompanied by the thread_­local specifier, which declares the variable to have thread storage duration ([basic.stc.thread]).
A static specifier can be used in declarations of class members; [class.static] describes its effect.
For the linkage of a name declared with a static specifier, see [basic.link].
The extern specifier can be applied only to the names of variables and functions.
The extern specifier cannot be used in the declaration of class members or function parameters.
For the linkage of a name declared with an extern specifier, see [basic.link].
[Note
:
The extern keyword can also be used in explicit-instantiations and linkage-specifications, but it is not a storage-class-specifier in such contexts.
end note
]
The linkages implied by successive declarations for a given entity shall agree.
That is, within a given scope, each declaration declaring the same variable name or the same overloading of a function name shall imply the same linkage.
Each function in a given set of overloaded functions can have a different linkage, however.
[Example
:
static char* f();               // f() has internal linkage
char* f()                       // f() still has internal linkage
  { /* ... */ }

char* g();                      // g() has external linkage
static char* g()                // error: inconsistent linkage
  { /* ... */ }

void h();
inline void h();                // external linkage

inline void l();
void l();                       // external linkage

inline void m();
extern void m();                // external linkage

static void n();
inline void n();                // internal linkage

static int a;                   // a has internal linkage
int a;                          // error: two definitions

static int b;                   // b has internal linkage
extern int b;                   // b still has internal linkage

int c;                          // c has external linkage
static int c;                   // error: inconsistent linkage

extern int d;                   // d has external linkage
static int d;                   // error: inconsistent linkage
end example
]
The name of a declared but undefined class can be used in an extern declaration.
Such a declaration can only be used in ways that do not require a complete class type.
[Example
:
struct S;
extern S a;
extern S f();
extern void g(S);

void h() {
  g(a);                         // error: S is incomplete
  f();                          // error: S is incomplete
}
end example
]
The mutable specifier shall appear only in the declaration of a non-static data member ([class.mem]) whose type is neither const-qualified nor a reference type.
[Example
:
class X {
  mutable const int* p;         // OK
  mutable int* const q;         // ill-formed
};
end example
]
The mutable specifier on a class data member nullifies a const specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const ([dcl.type.cv]).

10.1.2 Function specifiers [dcl.fct.spec]

Function-specifiers can be used only in function declarations.
function-specifier:
	virtual
	explicit
The virtual specifier shall be used only in the initial declaration of a non-static class member function; see [class.virtual].
The explicit specifier shall be used only in the declaration of a constructor or conversion function within its class definition; see [class.conv.ctor] and [class.conv.fct].

10.1.3 The typedef specifier [dcl.typedef]

Declarations containing the decl-specifier typedef declare identifiers that can be used later for naming fundamental ([basic.fundamental]) or compound ([basic.compound]) types.
The typedef specifier shall not be combined in a decl-specifier-seq with any other kind of specifier except a defining-type-specifier, and it shall not be used in the decl-specifier-seq of a parameter-declaration nor in the decl-specifier-seq of a function-definition ([dcl.fct.def]).
If a typedef specifier appears in a declaration without a declarator, the program is ill-formed.
typedef-name:
	identifier
A name declared with the typedef specifier becomes a typedef-name.
Within the scope of its declaration, a typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier in the way described in Clause [dcl.decl].
A typedef-name is thus a synonym for another type.
A typedef-name does not introduce a new type the way a class declaration ([class.name]) or enum declaration does.
[Example
:
After
typedef int MILES, *KLICKSP;
the constructions
MILES distance;
extern KLICKSP metricp;
are all correct declarations; the type of distance is int and that of metricp is “pointer to int.
end example
]
A typedef-name can also be introduced by an alias-declaration.
The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name.
Such a typedef-name has the same semantics as if it were introduced by the typedef specifier.
In particular, it does not define a new type.
[Example
:
using handler_t = void (*)(int);
extern handler_t ignore;
extern void (*ignore)(int);         // redeclare ignore
using cell = pair<void*, cell*>;    // ill-formed
end example
]
The defining-type-specifier-seq of the defining-type-id shall not define a class or enumeration if the alias-declaration is the declaration of a template-declaration.
In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers.
[Example
:
typedef struct s { /* ... */ } s;
typedef int I;
typedef int I;
typedef I I;
end example
]
In a given class scope, a typedef specifier can be used to redefine any class-name declared in that scope that is not also a typedef-name to refer to the type to which it already refers.
[Example
:
struct S {
  typedef struct A { } A;       // OK
  typedef struct B B;           // OK
  typedef A A;                  // error
};
end example
]
If a typedef specifier is used to redefine in a given scope an entity that can be referenced using an elaborated-type-specifier, the entity can continue to be referenced by an elaborated-type-specifier or as an enumeration or class name in an enumeration or class definition respectively.
[Example
:
struct S;
typedef struct S S;
int main() {
  struct S* p;                  // OK
}
struct S { };                   // OK
end example
]
In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type.
[Example
:
class complex { /* ... */ };
typedef int complex;            // error: redefinition
end example
]
Similarly, in a given scope, a class or enumeration shall not be declared with the same name as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself.
[Example
:
typedef int complex;
class complex { /* ... */ };    // error: redefinition
end example
]
[Note
:
A typedef-name that names a class type, or a cv-qualified version thereof, is also a class-name ([class.name]).
If a typedef-name is used to identify the subject of an elaborated-type-specifier ([dcl.type.elab]), a class definition (Clause [class]), a constructor declaration ([class.ctor]), or a destructor declaration ([class.dtor]), the program is ill-formed.
end note
]
[Example
:
struct S {
  S();
  ~S();
};

typedef struct S T;

S a = T();                      // OK
struct T * p;                   // error
end example
]
If the typedef declaration defines an unnamed class (or enum), the first typedef-name declared by the declaration to be that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only ([basic.link]).
[Example
:
typedef struct { } *ps, S;      // S is the class name for linkage purposes
end example
]

10.1.4 The friend specifier [dcl.friend]

The friend specifier is used to specify access to class members; see [class.friend].

10.1.5 The constexpr specifier [dcl.constexpr]

The constexpr specifier shall be applied only to the definition of a variable or variable template or the declaration of a function or function template.
A function or static data member declared with the constexpr specifier is implicitly an inline function or variable ([dcl.inline]).
If any declaration of a function or function template has a constexpr specifier, then all its declarations shall contain the constexpr specifier.
[Note
:
An explicit specialization can differ from the template declaration with respect to the constexpr specifier.
end note
]
[Note
:
Function parameters cannot be declared constexpr.
end note
]
[Example
:
constexpr void square(int &x);  // OK: declaration
constexpr int bufsz = 1024;     // OK: definition
constexpr struct pixel {        // error: pixel is a type
  int x;
  int y;
  constexpr pixel(int);         // OK: declaration
};
constexpr pixel::pixel(int a)
  : x(a), y(x)                  // OK: definition
  { square(x); }
constexpr pixel small(2);       // error: square not defined, so small(2)
                                // not constant ([expr.const]) so constexpr not satisfied

constexpr void square(int &x) { // OK: definition
  x *= x;
}
constexpr pixel large(4);       // OK: square defined
int next(constexpr int x) {     // error: not for parameters
     return x + 1;
}
extern constexpr int memsz;     // error: not a definition
end example
]
A constexpr specifier used in the declaration of a function that is not a constructor declares that function to be a constexpr function.
Similarly, a constexpr specifier used in a constructor declaration declares that constructor to be a constexpr constructor.
The definition of a constexpr function shall satisfy the following requirements:
[Example
:
constexpr int square(int x)
  { return x * x; }             // OK
constexpr long long_max()
  { return 2147483647; }        // OK
constexpr int abs(int x) {
  if (x < 0)
    x = -x;
  return x;                     // OK
}
constexpr int first(int n) {
  static int value = n;         // error: variable has static storage duration
  return value;
}
constexpr int uninit() {
  int a;                        // error: variable is uninitialized
  return a;
}
constexpr int prev(int x)
  { return --x; }               // OK
constexpr int g(int x, int n) { // OK
  int r = 1;
  while (--n > 0) r *= x;
  return r;
}
end example
]
The definition of a constexpr constructor shall satisfy the following requirements:
In addition, either its function-body shall be = delete, or it shall satisfy the following requirements:
  • either its function-body shall be = default, or the compound-statement of its function-body shall satisfy the requirements for a function-body of a constexpr function;
  • every non-variant non-static data member and base class subobject shall be initialized ([class.base.init]);
  • if the class is a union having variant members ([class.union]), exactly one of them shall be initialized;
  • if the class is a union-like class, but is not a union, for each of its anonymous union members having variant members, exactly one of them shall be initialized;
  • for a non-delegating constructor, every constructor selected to initialize non-static data members and base class subobjects shall be a constexpr constructor;
  • for a delegating constructor, the target constructor shall be a constexpr constructor.
[Example
:
struct Length {
  constexpr explicit Length(int i = 0) : val(i) { }
private:
  int val;
};
end example
]
For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression ([expr.const]), or, for a constructor, a constant initializer for some object ([basic.start.static]), the program is ill-formed, no diagnostic required.
[Example
:
constexpr int f(bool b)
  { return b ? throw 0 : 0; }           // OK
constexpr int f() { return f(true); }   // ill-formed, no diagnostic required

struct B {
  constexpr B(int x) : i(0) { }         // x is unused
  int i;
};

int global;

struct D : B {
  constexpr D() : B(global) { }         // ill-formed, no diagnostic required
                                        // lvalue-to-rvalue conversion on non-constant global
};
end example
]
If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression.
If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed, no diagnostic required.
A call to a constexpr function produces the same result as a call to an equivalent non-constexpr function in all respects except that
The constexpr specifier has no effect on the type of a constexpr function or a constexpr constructor.
[Example
:
constexpr int bar(int x, int y)         // OK
    { return x + y + x*y; }
// ...
int bar(int x, int y)                   // error: redefinition of bar
    { return x * 2 + 3 * y; }
end example
]
A constexpr specifier used in an object declaration declares the object as const.
Such an object shall have literal type and shall be initialized.
In any constexpr variable declaration, the full-expression of the initialization shall be a constant expression ([expr.const]).
[Example
:
struct pixel {
  int x, y;
};
constexpr pixel ur = { 1294, 1024 };    // OK
constexpr pixel origin;                 // error: initializer missing
end example
]

10.1.6 The inline specifier [dcl.inline]

The inline specifier can be applied only to the declaration or definition of a variable or function.
A function declaration ([dcl.fct], [class.mfct], [class.friend]) with an inline specifier declares an inline function.
The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism.
An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions specified in this section shall still be respected.
A variable declaration with an inline specifier declares an inline variable.
A function defined within a class definition is an inline function.
The inline specifier shall not appear on a block scope declaration.94
If the inline specifier is used in a friend function declaration, that declaration shall be a definition or the function shall have previously been declared inline.
An inline function or variable shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case ([basic.def.odr]).
[Note
:
A call to the inline function or a use of the inline variable may be encountered before its definition appears in the translation unit.
end note
]
If the definition of a function or variable appears in a translation unit before its first declaration as inline, the program is ill-formed.
If a function or variable with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required.
An inline function or variable with external linkage shall have the same address in all translation units.
[Note
:
A static local variable in an inline function with external linkage always refers to the same object.
A type defined within the body of an inline function with external linkage is the same type in every translation unit.
end note
]
The inline keyword has no effect on the linkage of a function.

10.1.7 Type specifiers [dcl.type]

As a general rule, at most one defining-type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a defining-type-specifier-seq, and at most one type-specifier is allowed in a type-specifier-seq.
The only exceptions to this rule are the following:
  • const can be combined with any type specifier except itself.
  • volatile can be combined with any type specifier except itself.
  • signed or unsigned can be combined with char, long, short, or int.
  • short or long can be combined with int.
  • long can be combined with double.
  • long can be combined with long.
Except in a declaration of a constructor, destructor, or conversion function, at least one defining-type-specifier that is not a cv-qualifier shall appear in a complete type-specifier-seq or a complete decl-specifier-seq.95
[Note
:
enum-specifiers, class-specifiers, and typename-specifiers are discussed in [dcl.enum], Clause [class], and [temp.res], respectively.
The remaining type-specifiers are discussed in the rest of this section.
end note
]
There is no special provision for a decl-specifier-seq that lacks a type-specifier or that has a type-specifier that only specifies cv-qualifiers.
The “implicit int” rule of C is no longer supported.

10.1.7.1 The cv-qualifiers [dcl.type.cv]

There are two cv-qualifiers, const and volatile.
Each cv-qualifier shall appear at most once in a cv-qualifier-seq.
If a cv-qualifier appears in a decl-specifier-seq, the init-declarator-list or member-declarator-list of the declaration shall not be empty.
[Note
:
[basic.type.qualifier] and [dcl.fct] describe how cv-qualifiers affect object and function types.
end note
]
Redundant cv-qualifications are ignored.
[Note
:
For example, these could be introduced by typedefs.
end note
]
[Note
:
Declaring a variable const can affect its linkage ([dcl.stc]) and its usability in constant expressions ([expr.const]).
As described in [dcl.init], the definition of an object or subobject of const-qualified type must specify an initializer or be subject to default-initialization.
end note
]
A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path.
[Note
:
Cv-qualifiers are supported by the type system so that they cannot be subverted without casting ([expr.const.cast]).
end note
]
Except that any class member declared mutable ([dcl.stc]) can be modified, any attempt to modify a const object during its lifetime ([basic.life]) results in undefined behavior.
[Example
:
const int ci = 3;                       // cv-qualified (initialized as required)
ci = 4;                                 // ill-formed: attempt to modify const

int i = 2;                              // not cv-qualified
const int* cip;                         // pointer to const int
cip = &i;                               // OK: cv-qualified access path to unqualified
*cip = 4;                               // ill-formed: attempt to modify through ptr to const

int* ip;
ip = const_cast<int*>(cip);             // cast needed to convert const int* to int*
*ip = 4;                                // defined: *ip points to i, a non-const object

const int* ciq = new const int (3);     // initialized as required
int* iq = const_cast<int*>(ciq);        // cast required
*iq = 4;                                // undefined: modifies a const object
For another example,
struct X {
  mutable int i;
  int j;
};
struct Y {
  X x;
  Y();
};

const Y y;
y.x.i++;                                // well-formed: mutable member can be modified
y.x.j++;                                // ill-formed: const-qualified member modified
Y* p = const_cast<Y*>(&y);              // cast away const-ness of y
p->x.i = 99;                            // well-formed: mutable member can be modified
p->x.j = 99;                            // undefined: modifies a const member
end example
]
The semantics of an access through a volatile glvalue are implementation-defined.
If an attempt is made to access an object defined with a volatile-qualified type through the use of a non-volatile glvalue, the behavior is undefined.
[Note
:
volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation.
Furthermore, for some implementations, volatile might indicate that special hardware instructions are required to access the object.
See [intro.execution] for detailed semantics.
In general, the semantics of volatile are intended to be the same in C++ as they are in C.
end note
]

10.1.7.2 Simple type specifiers [dcl.type.simple]

The simple type specifiers are
The simple-type-specifier auto is a placeholder for a type to be deduced ([dcl.spec.auto]).
A type-specifier of the form typename nested-name-specifier template-name is a placeholder for a deduced class type ([dcl.type.class.deduct]).
The template-name shall name a class template that is not an injected-class-name.
The other simple-type-specifiers specify either a previously-declared type, a type determined from an expression, or one of the fundamental types ([basic.fundamental]).
Table 11 summarizes the valid combinations of simple-type-specifiers and the types they specify.
Table 11simple-type-specifiers and the types they specify
Specifier(s)
Type
type-name
the type named
simple-template-id
the type as defined in [temp.names]
template-name
placeholder for a type to be deduced
char
“char”
unsigned char
“unsigned char”
signed char
“signed char”
char16_t
“char16_t”
char32_t
“char32_t”
bool
“bool”
unsigned
“unsigned int”
unsigned int
“unsigned int”
signed
“int”
signed int
“int”
int
“int”
unsigned short int
“unsigned short int”
unsigned short
“unsigned short int”
unsigned long int
“unsigned long int”
unsigned long
“unsigned long int”
unsigned long long int
“unsigned long long int”
unsigned long long
“unsigned long long int”
signed long int
“long int”
signed long
“long int”
signed long long int
“long long int”
signed long long
“long long int”
long long int
“long long int”
long long
“long long int”
long int
“long int”
long
“long int”
signed short int
“short int”
signed short
“short int”
short int
“short int”
short
“short int”
wchar_t
“wchar_t”
float
“float”
double
“double”
long double
“long double”
void
“void”
auto
placeholder for a type to be deduced
decltype(auto)
placeholder for a type to be deduced
decltype(expression)
the type as defined below
When multiple simple-type-specifiers are allowed, they can be freely intermixed with other decl-specifiers in any order.
[Note
:
It is implementation-defined whether objects of char type are represented as signed or unsigned quantities.
The signed specifier forces char objects to be signed; it is redundant in other contexts.
end note
]
For an expression e, the type denoted by decltype(e) is defined as follows:
  • if e is an unparenthesized id-expression naming a structured binding ([dcl.struct.bind]), decltype(e) is the referenced type as given in the specification of the structured binding declaration;
  • otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access ([expr.ref]), decltype(e) is the type of the entity named by e.
    If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
  • otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;
  • otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
  • otherwise, decltype(e) is the type of e.
The operand of the decltype specifier is an unevaluated operand (Clause [expr]).
[Example
:
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17;        // type is const int&&
decltype(i) x2;                 // type is int
decltype(a->x) x3;              // type is double
decltype((a->x)) x4 = x3;       // type is const double&
end example
]
[Note
:
The rules for determining types involving decltype(auto) are specified in [dcl.spec.auto].
end note
]
If the operand of a decltype-specifier is a prvalue, the temporary materialization conversion is not applied ([conv.rval]) and no result object is provided for the prvalue.
The type of the prvalue may be incomplete.
[Note
:
As a result, storage is not allocated for the prvalue and it is not destroyed.
Thus, a class type is not instantiated as a result of being the type of a function call in this context.
In this context, the common purpose of writing the expression is merely to refer to its type.
In that sense, a decltype-specifier is analogous to a use of a typedef-name, so the usual reasons for requiring a complete type do not apply.
In particular, it is not necessary to allocate storage for a temporary object or to enforce the semantic constraints associated with invoking the type's destructor.
end note
]
[Note
:
Unlike the preceding rule, parentheses have no special meaning in this context.
end note
]
[Example
:
template<class T> struct A { ~A() = delete; };
template<class T> auto h()
  -> A<T>;
template<class T> auto i(T)     // identity
  -> T;
template<class T> auto f(T)     // #1
  -> decltype(i(h<T>()));       // forces completion of A<T> and implicitly uses A<T>​::​~A()
                                // for the temporary introduced by the use of h().
                                // (A temporary is not introduced as a result of the use of i().)
template<class T> auto f(T)     // #2
  -> void;
auto g() -> void {
  f(42);                        // OK: calls #2. (#1 is not a viable candidate: type deduction
                                // fails ([temp.deduct]) because A<int>​::​~A() is implicitly used in its
                                // decltype-specifier)
}
template<class T> auto q(T)
  -> decltype((h<T>()));        // does not force completion of A<T>; A<T>​::​~A() is not implicitly
                                // used within the context of this decltype-specifier
void r() {
  q(42);                        // Error: deduction against q succeeds, so overload resolution selects
                                // the specialization “q(T) -> decltype((h<T>())) [with T=int]”.
                                // The return type is A<int>, so a temporary is introduced and its
                                // destructor is used, so the program is ill-formed.
}
end example
]

10.1.7.3 Elaborated type specifiers [dcl.type.elab]

An attribute-specifier-seq shall not appear in an elaborated-type-specifier unless the latter is the sole constituent of a declaration.
If an elaborated-type-specifier is the sole constituent of a declaration, the declaration is ill-formed unless it is an explicit specialization ([temp.expl.spec]), an explicit instantiation ([temp.explicit]) or it has one of the following forms:
class-key attribute-specifier-seq identifier ;
friend class-key :: identifier ;
friend class-key :: simple-template-id ;
friend class-key nested-name-specifier identifier ;
friend class-key nested-name-specifier template simple-template-id ;
In the first case, the attribute-specifier-seq, if any, appertains to the class being declared; the attributes in the attribute-specifier-seq are thereafter considered attributes of the class whenever it is named.
[basic.lookup.elab] describes how name lookup proceeds for the identifier in an elaborated-type-specifier.
If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name.
If the identifier resolves to a typedef-name or the simple-template-id resolves to an alias template specialization, the elaborated-type-specifier is ill-formed.
[Note
:
This implies that, within a class template with a template type-parameter T, the declaration
friend class T;
is ill-formed.
However, the similar declaration friend T; is allowed ([class.friend]).
end note
]
The class-key or enum keyword present in the elaborated-type-specifier shall agree in kind with the declaration to which the name in the elaborated-type-specifier refers.
This rule also applies to the form of elaborated-type-specifier that declares a class-name or friend class since it can be construed as referring to the definition of the class.
Thus, in any elaborated-type-specifier, the enum keyword shall be used to refer to an enumeration ([dcl.enum]), the union class-key shall be used to refer to a union (Clause [class]), and either the class or struct class-key shall be used to refer to a class (Clause [class]) declared using the class or struct class-key.
[Example
:
enum class E { a, b };
enum E x = E::a;                // OK
end example
]

10.1.7.4 The auto specifier [dcl.spec.auto]

The auto and decltype(auto) type-specifiers are used to designate a placeholder type that will be replaced later by deduction from an initializer.
The auto type-specifier is also used to introduce a function type having a trailing-return-type or to signify that a lambda is a generic lambda ([expr.prim.lambda.closure]).
The auto type-specifier is also used to introduce a structured binding declaration ([dcl.struct.bind]).
The placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid.
If the function declarator includes a trailing-return-type ([dcl.fct]), that trailing-return-type specifies the declared return type of the function.
Otherwise, the function declarator shall declare a function.
If the declared return type of the function contains a placeholder type, the return type of the function is deduced from non-discarded return statements, if any, in the body of the function ([stmt.if]).
[Example
:
auto glambda = [](int i, auto a) { return i; };     // OK: a generic lambda
end example
]
The type of a variable declared using auto or decltype(auto) is deduced from its initializer.
This use is allowed in an initializing declaration ([dcl.init]) of a variable.
auto or decltype(auto) shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl-specifier-seq shall be followed by one or more declarators, each of which shall be followed by a non-empty initializer.
In an initializer of the form
( expression-list )
[Example
:
auto x = 5;                     // OK: x has type int
const auto *v = &x, u = 6;      // OK: v has type const int*, u has type const int
static auto y = 0.0;            // OK: y has type double
auto int r;                     // error: auto is not a storage-class-specifier
auto f() -> int;                // OK: f returns int
auto g() { return 0.0; }        // OK: g returns double
auto h();                       // OK: h's return type will be deduced when it is defined
end example
]
A placeholder type can also be used in the type-specifier-seq in the new-type-id or type-id of a new-expression and as a decl-specifier of the parameter-declaration's decl-specifier-seq in a template-parameter.
A program that uses auto or decltype(auto) in a context not explicitly allowed in this section is ill-formed.
If the init-declarator-list contains more than one init-declarator, they shall all form declarations of variables.
The type of each declared variable is determined by placeholder type deduction ([dcl.type.auto.deduct]), and if the type that replaces the placeholder type is not the same in each deduction, the program is ill-formed.
[Example
:
auto x = 5, *y = &x;            // OK: auto is int
auto a = 5, b = { 1, 2 };       // error: different types for auto
end example
]
If a function with a declared return type that contains a placeholder type has multiple non-discarded return statements, the return type is deduced for each such return statement.
If the type deduced is not the same in each deduction, the program is ill-formed.
If a function with a declared return type that uses a placeholder type has no non-discarded return statements, the return type is deduced as though from a return statement with no operand at the closing brace of the function body.
[Example
:
auto  f() { }                   // OK, return type is void
auto* g() { }                   // error, cannot deduce auto* from void()
end example
]
If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression, the program is ill-formed.
Once a non-discarded return statement has been seen in a function, however, the return type deduced from that statement can be used in the rest of the function, including in other return statements.
[Example
:
auto n = n;                     // error, n's type is unknown
auto f();
void g() { &f; }                // error, f's return type is unknown
auto sum(int i) {
  if (i == 1)
    return i;                   // sum's return type is int
  else
    return sum(i-1)+i;          // OK, sum's return type has been deduced
}
end example
]
Return type deduction for a function template with a placeholder in its declared type occurs when the definition is instantiated even if the function body contains a return statement with a non-type-dependent operand.
[Note
:
Therefore, any use of a specialization of the function template will cause an implicit instantiation.
Any errors that arise from this instantiation are not in the immediate context of the function type and can result in the program being ill-formed ([temp.deduct]).
end note
]
[Example
:
template <class T> auto f(T t) { return t; }    // return type deduced at instantiation time
typedef decltype(f(1)) fint_t;                  // instantiates f<int> to deduce return type
template<class T> auto f(T* t) { return *t; }
void g() { int (*p)(int*) = &f; }               // instantiates both fs to determine return types,
                                                // chooses second
end example
]
Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type.
[Example
:
auto f();
auto f() { return 42; }                         // return type is int
auto f();                                       // OK
int f();                                        // error, cannot be overloaded with auto f()
decltype(auto) f();                             // error, auto and decltype(auto) don't match

template <typename T> auto g(T t) { return t; } // #1
template auto g(int);                           // OK, return type is int
template char g(char);                          // error, no matching template
template<> auto g(double);                      // OK, forward declaration with unknown return type

template <class T> T g(T t) { return t; }       // OK, not functionally equivalent to #1
template char g(char);                          // OK, now there is a matching template
template auto g(float);                         // still matches #1

void h() { return g(42); }                      // error, ambiguous

template <typename T> struct A {
  friend T frf(T);
};
auto frf(int i) { return i; }                   // not a friend of A<int>
end example
]
A function declared with a return type that uses a placeholder type shall not be virtual ([class.virtual]).
An explicit instantiation declaration ([temp.explicit]) does not cause the instantiation of an entity declared using a placeholder type, but it also does not prevent that entity from being instantiated as needed to determine its type.
[Example
:
template <typename T> auto f(T t) { return t; }
extern template auto f(int);    // does not instantiate f<int>
int (*p)(int) = f;              // instantiates f<int> to determine its return type, but an explicit
                                // instantiation definition is still required somewhere in the program
end example
]

10.1.7.4.1 Placeholder type deduction [dcl.type.auto.deduct]

Placeholder type deduction is the process by which a type containing a placeholder type is replaced by a deduced type.
A type T containing a placeholder type, and a corresponding initializer e, are determined as follows:
  • for a non-discarded return statement that occurs in a function declared with a return type that contains a placeholder type, T is the declared return type and e is the operand of the return statement.
    If the return statement has no operand, then e is void();
  • for a variable declared with a type that contains a placeholder type, T is the declared type of the variable and e is the initializer.
    If the initialization is direct-list-initialization, the initializer shall be a braced-init-list containing only a single assignment-expression and e is the assignment-expression;
  • for a non-type template parameter declared with a type that contains a placeholder type, T is the declared type of the non-type template parameter and e is the corresponding template argument.
In the case of a return statement with no operand or with an operand of type void, T shall be either decltype(auto) or cv auto.
If the deduction is for a return statement and e is a braced-init-list ([dcl.init.list]), the program is ill-formed.
If the placeholder is the auto type-specifier, the deduced type T' replacing T is determined using the rules for template argument deduction.
Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initialization is copy-list-initialization, with std​::​initializer_­list<U>.
Deduce a value for U using the rules of template argument deduction from a function call ([temp.deduct.call]), where P is a function template parameter type and the corresponding argument is e.
If the deduction fails, the declaration is ill-formed.
Otherwise, T' is obtained by substituting the deduced U into P.
[Example
:
auto x1 = { 1, 2 };             // decltype(x1) is std​::​initializer_­list<int>
auto x2 = { 1, 2.0 };           // error: cannot deduce element type
auto x3{ 1, 2 };                // error: not a single element
auto x4 = { 3 };                // decltype(x4) is std​::​initializer_­list<int>
auto x5{ 3 };                   // decltype(x5) is int
end example
]
[Example
:
const auto &i = expr;
The type of i is the deduced type of the parameter u in the call f(expr) of the following invented function template:
template <class U> void f(const U& u);
end example
]
If the placeholder is the decltype(auto) type-specifier, T shall be the placeholder alone.
The type deduced for T is determined as described in [dcl.type.simple], as though e had been the operand of the decltype.
[Example
:
int i;
int&& f();
auto           x2a(i);          // decltype(x2a) is int
decltype(auto) x2d(i);          // decltype(x2d) is int
auto           x3a = i;         // decltype(x3a) is int
decltype(auto) x3d = i;         // decltype(x3d) is int
auto           x4a = (i);       // decltype(x4a) is int
decltype(auto) x4d = (i);       // decltype(x4d) is int&
auto           x5a = f();       // decltype(x5a) is int
decltype(auto) x5d = f();       // decltype(x5d) is int&&
auto           x6a = { 1, 2 };  // decltype(x6a) is std​::​initializer_­list<int>
decltype(auto) x6d = { 1, 2 };  // error, { 1, 2 } is not an expression
auto          *x7a = &i;        // decltype(x7a) is int*
decltype(auto)*x7d = &i;        // error, declared type is not plain decltype(auto)
end example
]

10.1.7.5 Deduced class template specialization types [dcl.type.class.deduct]

If a placeholder for a deduced class type appears as a decl-specifier in the decl-specifier-seq of an initializing declaration ([dcl.init]) of a variable, the placeholder is replaced by the return type of the function selected by overload resolution for class template deduction ([over.match.class.deduct]).
If the decl-specifier-seq is followed by an init-declarator-list or member-declarator-list containing more than one declarator, the type that replaces the placeholder shall be the same in each deduction.
A placeholder for a deduced class type can also be used in the type-specifier-seq in the new-type-id or type-id of a new-expression, or as the simple-type-specifier in an explicit type conversion (functional notation) ([expr.type.conv]).
A placeholder for a deduced class type shall not appear in any other context.
[Example
:
template<class T> struct container {
    container(T t) {}
    template<class Iter> container(Iter beg, Iter end);
};
template<class Iter>
container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>;
std::vector<double> v = { /* ... */ };

container c(7);                         // OK, deduces int for T
auto d = container(v.begin(), v.end()); // OK, deduces double for T
container e{5, 6};                      // error, int is not an iterator
end example
]

10.2 Enumeration declarations [dcl.enum]

An enumeration is a distinct type ([basic.compound]) with named constants.
Its name becomes an enum-name within its scope.
A : following “enum nested-name-specifier identifier” within the decl-specifier-seq of a member-declaration is parsed as part of an enum-base.
[Note
:
This resolves a potential ambiguity between the declaration of an enumeration with an enum-base and the declaration of an unnamed bit-field of enumeration type.
[Example
:
   struct S {
     enum E : int {};
     enum E : int {};           // error: redeclaration of enumeration
   };
end example
]
end note
]
If an opaque-enum-declaration contains a nested-name-specifier, the declaration shall be an explicit specialization ([temp.expl.spec]).
The enumeration type declared with an enum-key of only enum is an unscoped enumeration, and its enumerators are unscoped enumerators.
The enum-keys enum class and enum struct are semantically equivalent; an enumeration type declared with one of these is a scoped enumeration, and its enumerators are scoped enumerators.
The optional identifier shall not be omitted in the declaration of a scoped enumeration.
The type-specifier-seq of an enum-base shall name an integral type; any cv-qualification is ignored.
An opaque-enum-declaration declaring an unscoped enumeration shall not omit the enum-base.
The identifiers in an enumerator-list are declared as constants, and can appear wherever constants are required.
An enumerator-definition with = gives the associated enumerator the value indicated by the constant-expression.
If the first enumerator has no initializer, the value of the corresponding constant is zero.
An enumerator-definition without an initializer gives the enumerator the value obtained by increasing the value of the previous enumerator by one.
[Example
:
enum { a, b, c=0 };
enum { d, e, f=e+2 };
defines a, c, and d to be zero, b and e to be 1, and f to be 3.
end example
]
The optional attribute-specifier-seq in an enumerator appertains to that enumerator.
An opaque-enum-declaration is either a redeclaration of an enumeration in the current scope or a declaration of a new enumeration.
[Note
:
An enumeration declared by an opaque-enum-declaration has fixed underlying type and is a complete type.
The list of enumerators can be provided in a later redeclaration with an enum-specifier.
end note
]
A scoped enumeration shall not be later redeclared as unscoped or with a different underlying type.
An unscoped enumeration shall not be later redeclared as scoped and each redeclaration shall include an enum-base specifying the same underlying type as in the original declaration.
If the enum-key is followed by a nested-name-specifier, the enum-specifier shall refer to an enumeration that was previously declared directly in the class or namespace to which the nested-name-specifier refers (i.e., neither inherited nor introduced by a using-declaration), and the enum-specifier shall appear in a namespace enclosing the previous declaration.
Each enumeration defines a type that is different from all other types.
Each enumeration also has an underlying type.
The underlying type can be explicitly specified using an enum-base.
For a scoped enumeration type, the underlying type is int if it is not explicitly specified.
In both of these cases, the underlying type is said to be fixed.
Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration.
If the underlying type is fixed, the type of each enumerator prior to the closing brace is the underlying type and the constant-expression in the enumerator-definition shall be a converted constant expression of the underlying type ([expr.const]).
If the underlying type is not fixed, the type of each enumerator prior to the closing brace is determined as follows:
  • If an initializer is specified for an enumerator, the constant-expression shall be an integral constant expression ([expr.const]).
    If the expression has unscoped enumeration type, the enumerator has the underlying type of that enumeration type, otherwise it has the same type as the expression.
  • If no initializer is specified for the first enumerator, its type is an unspecified signed integral type.
  • Otherwise the type of the enumerator is the same as that of the preceding enumerator unless the incremented value is not representable in that type, in which case the type is an unspecified integral type sufficient to contain the incremented value.
    If no such type exists, the program is ill-formed.
An enumeration whose underlying type is fixed is an incomplete type from its point of declaration ([basic.scope.pdecl]) to immediately after its enum-base (if any), at which point it becomes a complete type.
An enumeration whose underlying type is not fixed is an incomplete type from its point of declaration to immediately after the closing } of its enum-specifier, at which point it becomes a complete type.
For an enumeration whose underlying type is not fixed, the underlying type is an integral type that can represent all the enumerator values defined in the enumeration.
If no integral type can represent all the enumerator values, the enumeration is ill-formed.
It is implementation-defined which integral type is used as the underlying type except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int.
If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0.
For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type.
Otherwise, for an enumeration where is the smallest enumerator and is the largest, the values of the enumeration are the values in the range to , defined as follows: Let K be 1 for a two's complement representation and 0 for a ones' complement or sign-magnitude representation.
is the smallest value greater than or equal to and equal to , where M is a non-negative integer.
is zero if is non-negative and otherwise.
The size of the smallest bit-field large enough to hold all the values of the enumeration type is if is zero and otherwise.
It is possible to define an enumeration that has values not defined by any of its enumerators.
If the enumerator-list is empty, the values of the enumeration are as if the enumeration had a single enumerator with value 0.96
Two enumeration types are layout-compatible enumerations if they have the same underlying type.
The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion ([conv.prom]).
[Example
:
  enum color { red, yellow, green=20, blue };
  color col = red;
  color* cp = &col;
  if (*cp == blue)              // ...
makes color a type describing various colors, and then declares col as an object of that type, and cp as a pointer to an object of that type.
The possible values of an object of type color are red, yellow, green, blue; these values can be converted to the integral values 0, 1, 20, and 21.
Since enumerations are distinct types, objects of type color can be assigned only values of type color.
color c = 1;                    // error: type mismatch, no conversion from int to color
int i = yellow;                 // OK: yellow converted to integral value 1, integral promotion
Note that this implicit enum to int conversion is not provided for a scoped enumeration:
enum class Col { red, yellow, green };
int x = Col::red;               // error: no Col to int conversion
Col y = Col::red;
if (y) { }                      // error: no Col to bool conversion
end example
]
Each enum-name and each unscoped enumerator is declared in the scope that immediately contains the enum-specifier.
Each scoped enumerator is declared in the scope of the enumeration.
These names obey the scope rules defined for all names in [basic.scope] and [basic.lookup].
[Example
:
enum direction { left='l', right='r' };

void g()  {
  direction d;                  // OK
  d = left;                     // OK
  d = direction::right;         // OK
}

enum class altitude { high='h', low='l' };

void h()  {
  altitude a;                   // OK
  a = high;                     // error: high not in scope
  a = altitude::low;            // OK
}
end example
]
An enumerator declared in class scope can be referred to using the class member access operators (​::​, . (dot) and -> (arrow)), see [expr.ref].
[Example
:
struct X {
  enum direction { left='l', right='r' };
  int f(int i) { return i==left ? 0 : i==right ? 1 : 2; }
};

void g(X* p) {
  direction d;                  // error: direction not in scope
  int i;
  i = p->f(left);               // error: left not in scope
  i = p->f(X::right);           // OK
  i = p->f(p->left);            // OK
  // ...
}
end example
]
If an enum-head contains a nested-name-specifier, the enum-specifier shall refer to an enumeration that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set ([namespace.def]) of that namespace (i.e., not merely inherited or introduced by a using-declaration), and the enum-specifier shall appear in a namespace enclosing the previous declaration.
In such cases, the nested-name-specifier of the enum-head of the definition shall not begin with a decltype-specifier.
This set of values is used to define promotion and conversion semantics for the enumeration type.
It does not preclude an expression of enumeration type from having a value that falls outside this range.

10.3 Namespaces [basic.namespace]

A namespace is an optionally-named declarative region.
The name of a namespace can be used to access entities declared in that namespace; that is, the members of the namespace.
Unlike other declarative regions, the definition of a namespace can be split over several parts of one or more translation units.
The outermost declarative region of a translation unit is a namespace; see [basic.scope.namespace].

10.3.1 Namespace definition [namespace.def]

Every namespace-definition shall appear in the global scope or in a namespace scope ([basic.scope.namespace]).
In a named-namespace-definition, the identifier is the name of the namespace.
If the identifier, when looked up ([basic.lookup.unqual]), refers to a namespace-name (but not a namespace-alias) that was introduced in the namespace in which the named-namespace-definition appears or that was introduced in a member of the inline namespace set of that namespace, the namespace-definition extends the previously-declared namespace.
Otherwise, the identifier is introduced as a namespace-name into the declarative region in which the named-namespace-definition appears.
Because a namespace-definition contains declarations in its namespace-body and a namespace-definition is itself a declaration, it follows that namespace-definitions can be nested.
[Example
:
namespace Outer {
  int i;
  namespace Inner {
    void f() { i++; }           // Outer​::​i
    int i;
    void g() { i++; }           // Inner​::​i
  }
}
end example
]
The enclosing namespaces of a declaration are those namespaces in which the declaration lexically appears, except for a redeclaration of a namespace member outside its original namespace (e.g., a definition as specified in [namespace.memdef]).
Such a redeclaration has the same enclosing namespaces as the original declaration.
[Example
:
namespace Q {
  namespace V {
    void f();                   // enclosing namespaces are the global namespace, Q, and Q​::​V
    class C { void m(); };
  }
  void V::f() {                 // enclosing namespaces are the global namespace, Q, and Q​::​V
    extern void h();            // ... so this declares Q​::​V​::​h
  }
  void V::C::m() {              // enclosing namespaces are the global namespace, Q, and Q​::​V
  }
}
end example
]
If the optional initial inline keyword appears in a namespace-definition for a particular namespace, that namespace is declared to be an inline namespace.
The inline keyword may be used on a namespace-definition that extends a namespace only if it was previously used on the namespace-definition that initially declared the namespace-name for that namespace.
The optional attribute-specifier-seq in a named-namespace-definition appertains to the namespace being defined or extended.
Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace.
Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces used in argument-dependent lookup ([basic.lookup.argdep]) whenever one of them is, and a using-directive that names the inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace ([namespace.unnamed]).
Furthermore, each member of the inline namespace can subsequently be partially specialized ([temp.class.spec]), explicitly instantiated ([temp.explicit]), or explicitly specialized ([temp.expl.spec]) as though it were a member of the enclosing namespace.
Finally, looking up a name in the enclosing namespace via explicit qualification ([namespace.qual]) will include members of the inline namespace brought in by the using-directive even if there are declarations of that name in the enclosing namespace.
These properties are transitive: if a namespace N contains an inline namespace M, which in turn contains an inline namespace O, then the members of O can be used as though they were members of M or N.
The inline namespace set of N is the transitive closure of all inline namespaces in N.
The enclosing namespace set of O is the set of namespaces consisting of the innermost non-inline namespace enclosing an inline namespace O, together with any intervening inline namespaces.
A nested-namespace-definition with an enclosing-namespace-specifier E, identifier I and namespace-body B is equivalent to
namespace E { namespace I { B } }
[Example
:
namespace A::B::C {
  int i;
}
The above has the same effect as:
namespace A {
  namespace B {
    namespace C {
      int i;
    }
  }
}
end example
]

10.3.1.1 Unnamed namespaces [namespace.unnamed]

An unnamed-namespace-definition behaves as if it were replaced by
inline namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }
where inline appears if and only if it appears in the unnamed-namespace-definition and all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the translation unit.
The optional attribute-specifier-seq in the unnamed-namespace-definition appertains to unique.
[Example
:
namespace { int i; }            // unique​::​i
void f() { i++; }               // unique​::​i++

namespace A {
  namespace {
    int i;                      // A​::​unique​::​i
    int j;                      // A​::​unique​::​j
  }
  void g() { i++; }             // A​::​unique​::​i++
}

using namespace A;
void h() {
  i++;                          // error: unique​::​i or A​::​unique​::​i
  A::i++;                       // A​::​unique​::​i
  j++;                          // A​::​unique​::​j
}
end example
]

10.3.1.2 Namespace member definitions [namespace.memdef]

A declaration in a namespace N (excluding declarations in nested scopes) whose declarator-id is an unqualified-id ([dcl.meaning]), whose class-head-name or enum-head-name is an identifier, or whose elaborated-type-specifier is of the form class-key attribute-specifier-seq identifier ([dcl.type.elab]), or that is an opaque-enum-declaration, declares (or redeclares) its unqualified-id or identifier as a member of N.
[Note
:
An explicit instantiation ([temp.explicit]) or explicit specialization ([temp.expl.spec]) of a template does not introduce a name and thus may be declared using an unqualified-id in a member of the enclosing namespace set, if the primary template is declared in an inline namespace.
end note
]
[Example
:
namespace X {
  void f() { /* ... */ }        // OK: introduces X​::​f()

  namespace M {
    void g();                   // OK: introduces X​::​M​::​g()
  }
  using M::g;
  void g();                     // error: conflicts with X​::​M​::​g()
}
end example
]
Members of a named namespace can also be defined outside that namespace by explicit qualification ([namespace.qual]) of the name being defined, provided that the entity being defined was already declared in the namespace and the definition appears after the point of declaration in a namespace that encloses the declaration's namespace.
[Example
:
namespace Q {
  namespace V {
    void f();
  }
  void V::f() { /* ... */ }     // OK
  void V::g() { /* ... */ }     // error: g() is not yet a member of V
  namespace V {
    void g();
  }
}

namespace R {
  void Q::V::g() { /* ... */ }  // error: R doesn't enclose Q
}
end example
]
If a friend declaration in a non-local class first declares a class, function, class template or function template97 the friend is a member of the innermost enclosing namespace.
The friend declaration does not by itself make the name visible to unqualified lookup ([basic.lookup.unqual]) or qualified lookup ([basic.lookup.qual]).
[Note
:
The name of the friend will be visible in its namespace if a matching declaration is provided at namespace scope (either before or after the class definition granting friendship).
end note
]
If a friend function or function template is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments ([basic.lookup.argdep]).
If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.
[Note
:
The other forms of friend declarations cannot declare a new member of the innermost enclosing namespace and thus follow the usual lookup rules.
end note
]
[Example
:
// Assume f and g have not yet been declared.
void h(int);
template <class T> void f2(T);
namespace A {
  class X {
    friend void f(X);           // A​::​f(X) is a friend
    class Y {
      friend void g();          // A​::​g is a friend
      friend void h(int);       // A​::​h is a friend
                                // ​::​h not considered
      friend void f2<>(int);    // ​::​f2<>(int) is a friend
    };
  };

  // A​::​f, A​::​g and A​::​h are not visible here
  X x;
  void g() { f(x); }            // definition of A​::​g
  void f(X) { /* ... */ }       // definition of A​::​f
  void h(int) { /* ... */ }     // definition of A​::​h
  // A​::​f, A​::​g and A​::​h are visible here and known to be friends
}

using A::x;

void h() {
  A::f(x);
  A::X::f(x);                   // error: f is not a member of A​::​X
  A::X::Y::g();                 // error: g is not a member of A​::​X​::​Y
}
end example
]
this implies that the name of the class or function is unqualified.

10.3.2 Namespace alias [namespace.alias]

The identifier in a namespace-alias-definition is a synonym for the name of the namespace denoted by the qualified-namespace-specifier and becomes a namespace-alias.
[Note
:
When looking up a namespace-name in a namespace-alias-definition, only namespace names are considered, see [basic.lookup.udir].
end note
]
In a declarative region, a namespace-alias-definition can be used to redefine a namespace-alias declared in that declarative region to refer only to the namespace to which it already refers.
[Example
:
The following declarations are well-formed:
namespace Company_with_very_long_name { /* ... */ }
namespace CWVLN = Company_with_very_long_name;
namespace CWVLN = Company_with_very_long_name;  // OK: duplicate
namespace CWVLN = CWVLN;
end example
]

10.3.3 The using declaration [namespace.udecl]

Each using-declarator in a using-declaration98 introduces a set of declarations into the declarative region in which the using-declaration appears.
The set of declarations introduced by the using-declarator is found by performing qualified name lookup ([basic.lookup.qual], [class.member.lookup]) for the name in the using-declarator, excluding functions that are hidden as described below.
If the using-declarator does not name a constructor, the unqualified-id is declared in the declarative region in which the using-declaration appears as a synonym for each declaration introduced by the using-declarator.
[Note
:
Only the specified name is so declared; specifying an enumeration name in a using-declaration does not declare its enumerators in the using-declaration's declarative region.
end note
]
If the using-declarator names a constructor, it declares that the class inherits the set of constructor declarations introduced by the using-declarator from the nominated base class.
Every using-declaration is a declaration and a member-declaration and can therefore be used in a class definition.
[Example
:
struct B {
  void f(char);
  void g(char);
  enum E { e };
  union { int x; };
};

struct D : B {
  using B::f;
  void f(int) { f('c'); }       // calls B​::​f(char)
  void g(int) { g('c'); }       // recursively calls D​::​g(int)
};
end example
]
In a using-declaration used as a member-declaration, each using-declarator's nested-name-specifier shall name a base class of the class being defined.
If a using-declarator names a constructor, its nested-name-specifier shall name a direct base class of the class being defined.
[Example
:
template <typename... bases>
struct X : bases... {
  using bases::g...;
};

X<B, D> x;                      // OK: B​::​g and D​::​g introduced
end example
]
[Example
:
class C {
  int g();
};

class D2 : public B {
  using B::f;                   // OK: B is a base of D2
  using B::e;                   // OK: e is an enumerator of base B
  using B::x;                   // OK: x is a union member of base B
  using C::g;                   // error: C isn't a base of D2
};
end example
]
[Note
:
Since destructors do not have names, a using-declaration cannot refer to a destructor for a base class.
Since specializations of member templates for conversion functions are not found by name lookup, they are not considered when a using-declaration specifies a conversion function ([temp.mem]).
end note
]
If a constructor or assignment operator brought from a base class into a derived class has the signature of a copy/move constructor or assignment operator for the derived class ([class.copy]), the using-declaration does not by itself suppress the implicit declaration of the derived class member; the member from the base class is hidden or overridden by the implicitly-declared copy/move constructor or assignment operator of the derived class, as described below.
A using-declaration shall not name a template-id.
[Example
:
struct A {
  template <class T> void f(T);
  template <class T> struct X { };
};
struct B : A {
  using A::f<double>;           // ill-formed
  using A::X<int>;              // ill-formed
};
end example
]
A using-declaration shall not name a namespace.
A using-declaration shall not name a scoped enumerator.
A using-declaration that names a class member shall be a member-declaration.
[Example
:
struct X {
  int i;
  static int s;
};

void f() {
  using X::i;                   // error: X​::​i is a class member and this is not a member declaration.
  using X::s;                   // error: X​::​s is a class member and this is not a member declaration.
}
end example
]
Members declared by a using-declaration can be referred to by explicit qualification just like other member names ([namespace.qual]).
[Example
:
void f();

namespace A {
  void g();
}

namespace X {
  using ::f;                    // global f
  using A::g;                   // A's g
}

void h()
{
  X::f();                       // calls ​::​f
  X::g();                       // calls A​::​g
}
end example
]
A using-declaration is a declaration and can therefore be used repeatedly where (and only where) multiple declarations are allowed.
[Example
:
namespace A {
  int i;
}

namespace A1 {
  using A::i, A::i;             // OK: double declaration
}

struct B {
  int i;
};

struct X : B {
  using B::i, B::i;             // error: double member declaration
};
end example
]
[Note
:
For a using-declaration whose nested-name-specifier names a namespace, members added to the namespace after the using-declaration are not in the set of introduced declarations, so they are not considered when a use of the name is made.
Thus, additional overloads added after the using-declaration are ignored, but default function arguments ([dcl.fct.default]), default template arguments ([temp.param]), and template specializations ([temp.class.spec], [temp.expl.spec]) are considered.
end note
]
[Example
:
namespace A {
  void f(int);
}

using A::f;         // f is a synonym for A​::​f; that is, for A​::​f(int).
namespace A {
  void f(char);
}

void foo() {
  f('a');           // calls f(int), even though f(char) exists.
}

void bar() {
  using A::f;       // f is a synonym for A​::​f; that is, for A​::​f(int) and A​::​f(char).
  f('a');           // calls f(char)
}
end example
]
[Note
:
Partial specializations of class templates are found by looking up the primary class template and then considering all partial specializations of that template.
If a using-declaration names a class template, partial specializations introduced after the using-declaration are effectively visible because the primary template is visible ([temp.class.spec]).
end note
]
Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same declarative region ([basic.scope]) also apply to using-declarations.
[Example
:
namespace A {
  int x;
}

namespace B {
  int i;
  struct g { };
  struct x { };
  void f(int);
  void f(double);
  void g(char);     // OK: hides struct g
}

void func() {
  int i;
  using B::i;       // error: i declared twice
  void f(char);
  using B::f;       // OK: each f is a function
  f(3.5);           // calls B​::​f(double)
  using B::g;
  g('a');           // calls B​::​g(char)
  struct g g1;      // g1 has class type B​::​g
  using B::x;
  using A::x;       // OK: hides struct B​::​x
  x = 99;           // assigns to A​::​x
  struct x x1;      // x1 has class type B​::​x
}
end example
]
If a function declaration in namespace scope or block scope has the same name and the same parameter-type-list ([dcl.fct]) as a function introduced by a using-declaration, and the declarations do not declare the same function, the program is ill-formed.
If a function template declaration in namespace scope has the same name, parameter-type-list, return type, and template parameter list as a function template introduced by a using-declaration, the program is ill-formed.
[Note
:
Two using-declarations may introduce functions with the same name and the same parameter-type-list.
If, for a call to an unqualified function name, function overload resolution selects the functions introduced by such using-declarations, the function call is ill-formed.
[Example
:
namespace B {
  void f(int);
  void f(double);
}
namespace C {
  void f(int);
  void f(double);
  void f(char);
}

void h() {
  using B::f;       // B​::​f(int) and B​::​f(double)
  using C::f;       // C​::​f(int), C​::​f(double), and C​::​f(char)
  f('h');           // calls C​::​f(char)
  f(1);             // error: ambiguous: B​::​f(int) or C​::​f(int)?
  void f(int);      // error: f(int) conflicts with C​::​f(int) and B​::​f(int)
}
end example
]
end note
]
When a using-declarator brings declarations from a base class into a derived class, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting).
Such hidden or overridden declarations are excluded from the set of declarations introduced by the using-declarator.
[Example
:
struct B {
  virtual void f(int);
  virtual void f(char);
  void g(int);
  void h(int);
};

struct D : B {
  using B::f;
  void f(int);      // OK: D​::​f(int) overrides B​::​f(int);

  using B::g;
  void g(char);     // OK

  using B::h;
  void h(int);      // OK: D​::​h(int) hides B​::​h(int)
};

void k(D* p)
{
  p->f(1);          // calls D​::​f(int)
  p->f('a');        // calls B​::​f(char)
  p->g(1);          // calls B​::​g(int)
  p->g('a');        // calls D​::​g(char)
}

struct B1 {
  B1(int);
};

struct B2 {
  B2(int);
};

struct D1 : B1, B2 {
  using B1::B1;
  using B2::B2;
};
D1 d1(0);           // ill-formed: ambiguous

struct D2 : B1, B2 {
  using B1::B1;
  using B2::B2;
  D2(int);          // OK: D2​::​D2(int) hides B1​::​B1(int) and B2​::​B2(int)
};
D2 d2(0);           // calls D2​::​D2(int)
end example
]
For the purpose of overload resolution, the functions that are introduced by a using-declaration into a derived class are treated as though they were members of the derived class.
In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class.
This has no effect on the type of the function, and in all other respects the function remains a member of the base class.
Likewise, constructors that are introduced by a using-declaration are treated as though they were constructors of the derived class when looking up the constructors of the derived class ([class.qual]) or forming a set of overload candidates ([over.match.ctor], [over.match.copy], [over.match.list]).
If such a constructor is selected to perform the initialization of an object of class type, all subobjects other than the base class from which the constructor originated are implicitly initialized ([class.inhctor.init]).
In a using-declarator that does not name a constructor, all members of the set of introduced declarations shall be accessible.
In a using-declarator that names a constructor, no access check is performed.
In particular, if a derived class uses a using-declarator to access a member of a base class, the member name shall be accessible.
If the name is that of an overloaded member function, then all functions named shall be accessible.
The base class members mentioned by a using-declarator shall be visible in the scope of at least one of the direct base classes of the class where the using-declarator is specified.
[Note
:
Because a using-declarator designates a base class member (and not a member subobject or a member function of a base class subobject), a using-declarator cannot be used to resolve inherited member ambiguities.
[Example
:
struct A { int x(); };
struct B : A { };
struct C : A {
  using A::x;
  int x(int);
};

struct D : B, C {
  using C::x;
  int x(double);
};
int f(D* d) {
  return d->x();    // error: overload resolution selects A​::​x, but A is an ambiguous base class
}
end example
]
end note
]
A synonym created by a using-declaration has the usual accessibility for a member-declaration.
A using-declarator that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored.
[Example
:
class A {
private:
    void f(char);
public:
    void f(int);
protected:
    void g();
};

class B : public A {
  using A::f;       // error: A​::​f(char) is inaccessible
public:
  using A::g;       // B​::​g is a public synonym for A​::​g
};
end example
]
If a using-declarator uses the keyword typename and specifies a dependent name ([temp.dep]), the name introduced by the using-declaration is treated as a typedef-name.
A using-declaration with more than one using-declarator is equivalent to a corresponding sequence of using-declarations with one using-declarator each.

10.3.4 Using directive [namespace.udir]

A using-directive shall not appear in class scope, but may appear in namespace scope or in block scope.
[Note
:
When looking up a namespace-name in a using-directive, only namespace names are considered, see [basic.lookup.udir].
end note
]
The optional attribute-specifier-seq appertains to the using-directive.
A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive.
During unqualified name lookup ([basic.lookup.unqual]), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace.
[Note
:
In this context, “contains” means “contains directly or indirectly”.
end note
]
A using-directive does not add any members to the declarative region in which it appears.
[Example
:
namespace A {
  int i;
  namespace B {
    namespace C {
      int i;
    }
    using namespace A::B::C;
    void f1() {
      i = 5;        // OK, C​::​i visible in B and hides A​::​i
    }
  }
  namespace D {
    using namespace B;
    using namespace C;
    void f2() {
      i = 5;        // ambiguous, B​::​C​::​i or A​::​i?
    }
  }
  void f3() {
    i = 5;          // uses A​::​i
  }
}
void f4() {
  i = 5;            // ill-formed; neither i is visible
}
end example
]
For unqualified lookup ([basic.lookup.unqual]), the using-directive is transitive: if a scope contains a using-directive that nominates a second namespace that itself contains using-directives, the effect is as if the using-directives from the second namespace also appeared in the first.
[Note
:
For qualified lookup, see [namespace.qual].
end note
]
[Example
:
namespace M {
  int i;
}

namespace N {
  int i;
  using namespace M;
}

void f() {
  using namespace N;
  i = 7;            // error: both M​::​i and N​::​i are visible
}
For another example,
namespace A {
  int i;
}
namespace B {
  int i;
  int j;
  namespace C {
    namespace D {
      using namespace A;
      int j;
      int k;
      int a = i;    // B​::​i hides A​::​i
    }
    using namespace D;
    int k = 89;     // no problem yet
    int l = k;      // ambiguous: C​::​k or D​::​k
    int m = i;      // B​::​i hides A​::​i
    int n = j;      // D​::​j hides B​::​j
  }
}
end example
]
If a namespace is extended ([namespace.def]) after a using-directive for that namespace is given, the additional members of the extended namespace and the members of namespaces nominated by using-directives in the extending namespace-definition can be used after the extending namespace-definition.
If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed.
[Note
:
In particular, the name of a variable, function or enumerator does not hide the name of a class or enumeration declared in a different namespace.
For example,
namespace A {
  class X { };
  extern "C"   int g();
  extern "C++" int h();
}
namespace B {
  void X(int);
  extern "C"   int g();
  extern "C++" int h(int);
}
using namespace A;
using namespace B;

void f() {
  X(1);             // error: name X found in two namespaces
  g();              // OK: name g refers to the same entity
  h();              // OK: overload resolution selects A​::​h
}
end note
]
During overload resolution, all functions from the transitive search are considered for argument matching.
The set of declarations found by the transitive search is unordered.
[Note
:
In particular, the order in which namespaces were considered and the relationships among the namespaces implied by the using-directives do not cause preference to be given to any of the declarations found by the search.
end note
]
An ambiguity exists if the best match finds two functions with the same signature, even if one is in a namespace reachable through using-directives in the namespace of the other.99
[Example
:
namespace D {
  int d1;
  void f(char);
}
using namespace D;

int d1;             // OK: no conflict with D​::​d1

namespace E {
  int e;
  void f(int);
}

namespace D {       // namespace extension
  int d2;
  using namespace E;
  void f(int);
}

void f() {
  d1++;             // error: ambiguous ​::​d1 or D​::​d1?
  ::d1++;           // OK
  D::d1++;          // OK
  d2++;             // OK: D​::​d2
  e++;              // OK: E​::​e
  f(1);             // error: ambiguous: D​::​f(int) or E​::​f(int)?
  f('a');           // OK: D​::​f(char)
}
end example
]
During name lookup in a class hierarchy, some ambiguities may be resolved by considering whether one member hides the other along some paths ([class.member.lookup]).
There is no such disambiguation when considering the set of names found as a result of following using-directives.

10.4 The asm declaration [dcl.asm]

An asm declaration has the form
asm-definition:
	attribute-specifier-seq asm ( string-literal ) ;
The asm declaration is conditionally-supported; its meaning is implementation-defined.
The optional attribute-specifier-seq in an asm-definition appertains to the asm declaration.
[Note
:
Typically it is used to pass information through the implementation to an assembler.
end note
]

10.6 Attributes [dcl.attr]

10.6.1 Attribute syntax and semantics [dcl.attr.grammar]

If an attribute-specifier contains an attribute-using-prefix, the attribute-list following that attribute-using-prefix shall not contain an attribute-scoped-token and every attribute-token in that attribute-list is treated as if its identifier were prefixed with N​::​, where N is the attribute-namespace specified in the attribute-using-prefix.
[Note
:
This rule imposes no constraints on how an attribute-using-prefix affects the tokens in an attribute-argument-clause.
end note
]
[Example
:
[[using CC: opt(1), debug]]         // same as [[CC​::​opt(1), CC​::​debug]]
  void f() {}
[[using CC: opt(1)]] [[CC::debug]]  // same as [[CC​::​opt(1)]] [[CC​::​debug]]
  void g() {}
[[using CC: CC::opt(1)]]            // error: cannot combine using and scoped attribute token
  void h() {}
end example
]
[Note
:
For each individual attribute, the form of the balanced-token-seq will be specified.
end note
]
In an attribute-list, an ellipsis may appear only if that attribute's specification permits it.
An attribute followed by an ellipsis is a pack expansion ([temp.variadic]).
An attribute-specifier that contains no attributes has no effect.
The order in which the attribute-tokens appear in an attribute-list is not significant.
If a keyword ([lex.key]) or an alternative token ([lex.digraph]) that satisfies the syntactic requirements of an identifier is contained in an attribute-token, it is considered an identifier.
No name lookup ([basic.lookup]) is performed on any of the identifiers contained in an attribute-token.
The attribute-token determines additional requirements on the attribute-argument-clause (if any).
Each attribute-specifier-seq is said to appertain to some entity or statement, identified by the syntactic context where it appears (Clause [stmt.stmt], Clause [dcl.dcl], Clause [dcl.decl]).
If an attribute-specifier-seq that appertains to some entity or statement contains an attribute or alignment-specifier that is not allowed to apply to that entity or statement, the program is ill-formed.
If an attribute-specifier-seq appertains to a friend declaration ([class.friend]), that declaration shall be a definition.
No attribute-specifier-seq shall appertain to an explicit instantiation ([temp.explicit]).
For an attribute-token (including an attribute-scoped-token) not specified in this International Standard, the behavior is implementation-defined.
Any attribute-token that is not recognized by the implementation is ignored.
[Note
:
Each implementation should choose a distinctive name for the attribute-namespace in an attribute-scoped-token.
end note
]
Two consecutive left square bracket tokens shall appear only when introducing an attribute-specifier or within the balanced-token-seq of an attribute-argument-clause.
[Note
:
If two consecutive left square brackets appear where an attribute-specifier is not allowed, the program is ill-formed even if the brackets match an alternative grammar production.
end note
]
[Example
:
int p[10];
void f() {
  int x = 42, y[5];
  int(p[[x] { return x; }()]);  // error: invalid attribute on a nested declarator-id and
                                // not a function-style cast of an element of p.
  y[[] { return 2; }()] = 2;    // error even though attributes are not allowed in this context.
  int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute.
}
end example
]

10.6.2 Alignment specifier [dcl.align]

An alignment-specifier may be applied to a variable or to a class data member, but it shall not be applied to a bit-field, a function parameter, or an exception-declaration ([except.handle]).
An alignment-specifier may also be applied to the declaration or definition of a class (in an elaborated-type-specifier or class-head, respectively) and to the declaration or definition of an enumeration (in an opaque-enum-declaration or enum-head, respectively ([dcl.enum])).
An alignment-specifier with an ellipsis is a pack expansion ([temp.variadic]).
When the alignment-specifier is of the form alignas( constant-expression ):
  • the constant-expression shall be an integral constant expression
  • if the constant expression does not evaluate to an alignment value ([basic.align]), or evaluates to an extended alignment and the implementation does not support that alignment in the context of the declaration, the program is ill-formed.
An alignment-specifier of the form alignas( type-id ) has the same effect as alignas(​alignof( type-id )) ([expr.alignof]).
The alignment requirement of an entity is the strictest nonzero alignment specified by its alignment-specifiers, if any; otherwise, the alignment-specifiers have no effect.
The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all alignment-specifiers appertaining to that entity were omitted.
[Example
:
struct alignas(8) S {};
struct alignas(1) U {
  S s;
};  // error: U specifies an alignment that is less strict than if the alignas(1) were omitted.
end example
]
If the defining declaration of an entity has an alignment-specifier, any non-defining declaration of that entity shall either specify equivalent alignment or have no alignment-specifier.
Conversely, if any declaration of an entity has an alignment-specifier, every defining declaration of that entity shall specify an equivalent alignment.
No diagnostic is required if declarations of an entity have different alignment-specifiers in different translation units.
[Example
:
// Translation unit #1:
struct S { int x; } s, *p = &s;

// Translation unit #2:
struct alignas(16) S;           // error: definition of S lacks alignment, no diagnostic required
extern S* p;
end example
]
[Example
:
An aligned buffer with an alignment requirement of A and holding N elements of type T can be declared as:
alignas(T) alignas(A) T buffer[N];
Specifying alignas(T) ensures that the final requested alignment will not be weaker than alignof(T), and therefore the program will not be ill-formed.
end example
]
[Example
:
alignas(double) void f();                           // error: alignment applied to function
alignas(double) unsigned char c[sizeof(double)];    // array of characters, suitably aligned for a double
extern unsigned char c[sizeof(double)];             // no alignas necessary
alignas(float)
  extern unsigned char c[sizeof(double)];           // error: different alignment in declaration
end example
]

10.6.3 Carries dependency attribute [dcl.attr.depend]

The attribute-token carries_­dependency specifies dependency propagation into and out of functions.
It shall appear at most once in each attribute-list and no attribute-argument-clause shall be present.
The attribute may be applied to the declarator-id of a parameter-declaration in a function declaration or lambda, in which case it specifies that the initialization of the parameter carries a dependency to ([intro.multithread]) each lvalue-to-rvalue conversion ([conv.lval]) of that object.
The attribute may also be applied to the declarator-id of a function declaration, in which case it specifies that the return value, if any, carries a dependency to the evaluation of the function call expression.
The first declaration of a function shall specify the carries_­dependency attribute for its declarator-id if any declaration of the function specifies the carries_­dependency attribute.
Furthermore, the first declaration of a function shall specify the carries_­dependency attribute for a parameter if any declaration of that function specifies the carries_­dependency attribute for that parameter.
If a function or one of its parameters is declared with the carries_­dependency attribute in its first declaration in one translation unit and the same function or one of its parameters is declared without the carries_­dependency attribute in its first declaration in another translation unit, the program is ill-formed, no diagnostic required.
[Note
:
The carries_­dependency attribute does not change the meaning of the program, but may result in generation of more efficient code.
end note
]
[Example
:
/* Translation unit A. */

struct foo { int* a; int* b; };
std::atomic<struct foo *> foo_head[10];
int foo_array[10][10];

[[carries_dependency]] struct foo* f(int i) {
  return foo_head[i].load(memory_order_consume);
}

int g(int* x, int* y [[carries_dependency]]) {
  return kill_dependency(foo_array[*x][*y]);
}

/* Translation unit B. */

[[carries_dependency]] struct foo* f(int i);
int g(int* x, int* y [[carries_dependency]]);

int c = 3;

void h(int i) {
  struct foo* p;

  p = f(i);
  do_something_with(g(&c, p->a));
  do_something_with(g(p->a, &c));
}
The carries_­dependency attribute on function f means that the return value carries a dependency out of f, so that the implementation need not constrain ordering upon return from f.
Implementations of f and its caller may choose to preserve dependencies instead of emitting hardware memory ordering instructions (a.
k.
a.
fences).
Function g's second parameter has a carries_­dependency attribute, but its first parameter does not.
Therefore, function h's first call to g carries a dependency into g, but its second call does not.
The implementation might need to insert a fence prior to the second call to g.
end example
]

10.6.4 Deprecated attribute [dcl.attr.deprecated]

The attribute-token deprecated can be used to mark names and entities whose use is still allowed, but is discouraged for some reason.
[Note
:
In particular, deprecated is appropriate for names and entities that are deemed obsolescent or unsafe.
end note
]
It shall appear at most once in each attribute-list.
An attribute-argument-clause may be present and, if present, it shall have the form:
( string-literal )
[Note
:
The string-literal in the attribute-argument-clause could be used to explain the rationale for deprecation and/or to suggest a replacing entity.
end note
]
The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data member, a function, a namespace, an enumeration, an enumerator, or a template specialization.
A name or entity declared without the deprecated attribute can later be redeclared with the attribute and vice-versa.
[Note
:
Thus, an entity initially declared without the attribute can be marked as deprecated by a subsequent redeclaration.
However, after an entity is marked as deprecated, later redeclarations do not un-deprecate the entity.
end note
]
Redeclarations using different forms of the attribute (with or without the attribute-argument-clause or with different attribute-argument-clauses) are allowed.
[Note
:
Implementations may use the deprecated attribute to produce a diagnostic message in case the program refers to a name or entity other than to declare it, after a declaration that specifies the attribute.
The diagnostic message may include the text provided within the attribute-argument-clause of any deprecated attribute applied to the name or entity.
end note
]

10.6.5 Fallthrough attribute [dcl.attr.fallthrough]

The attribute-token fallthrough may be applied to a null statement ([stmt.expr]); such a statement is a fallthrough statement.
The attribute-token fallthrough shall appear at most once in each attribute-list and no attribute-argument-clause shall be present.
A fallthrough statement may only appear within an enclosing switch statement ([stmt.switch]).
The next statement that would be executed after a fallthrough statement shall be a labeled statement whose label is a case label or default label for the same switch statement.
The program is ill-formed if there is no such statement.
[Note
:
The use of a fallthrough statement is intended to suppress a warning that an implementation might otherwise issue for a case or default label that is reachable from another case or default label along some path of execution.
Implementations are encouraged to issue a warning if a fallthrough statement is not dynamically reachable.
end note
]
[Example
:
void f(int n) {
  void g(), h(), i();
  switch (n) {
  case 1:
  case 2:
    g();
    [[fallthrough]];
  case 3:                       // warning on fallthrough discouraged
    h();
  case 4:                       // implementation may warn on fallthrough
    i();
    [[fallthrough]];            // ill-formed
  }
}
end example
]

10.6.6 Maybe unused attribute [dcl.attr.unused]

The attribute-token maybe_­unused indicates that a name or entity is possibly intentionally unused.
It shall appear at most once in each attribute-list and no attribute-argument-clause shall be present.
The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data member, a function, an enumeration, or an enumerator.
[Note
:
For an entity marked maybe_­unused, implementations are encouraged not to emit a warning that the entity is unused, or that the entity is used despite the presence of the attribute.
end note
]
A name or entity declared without the maybe_­unused attribute can later be redeclared with the attribute and vice versa.
An entity is considered marked after the first declaration that marks it.
[Example
:
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
                        [[maybe_unused]] bool thing2) {
  [[maybe_unused]] bool b = thing1 && thing2;
  assert(b);
}
Implementations are encouraged not to warn that b is unused, whether or not NDEBUG is defined.
end example
]

10.6.7 Nodiscard attribute [dcl.attr.nodiscard]

The attribute-token nodiscard may be applied to the declarator-id in a function declaration or to the declaration of a class or enumeration.
It shall appear at most once in each attribute-list and no attribute-argument-clause shall be present.
[Note
:
A nodiscard call is a function call expression that calls a function previously declared nodiscard, or whose return type is a possibly cv-qualified class or enumeration type marked nodiscard.
Appearance of a nodiscard call as a potentially-evaluated discarded-value expression (Clause [expr]) is discouraged unless explicitly cast to void.
Implementations are encouraged to issue a warning in such cases.
This is typically because discarding the return value of a nodiscard call has surprising consequences.
end note
]
[Example
:
struct [[nodiscard]] error_info { /* ... */ };
error_info enable_missile_safety_mode();
void launch_missiles();
void test_missiles() {
  enable_missile_safety_mode(); // warning encouraged
  launch_missiles();
}
error_info &foo();
void f() { foo(); }             // warning not encouraged: not a nodiscard call, because neither
                                // the (reference) return type nor the function is declared nodiscard
end example
]

10.6.8 Noreturn attribute [dcl.attr.noreturn]

The attribute-token noreturn specifies that a function does not return.
It shall appear at most once in each attribute-list and no attribute-argument-clause shall be present.
The attribute may be applied to the declarator-id in a function declaration.
The first declaration of a function shall specify the noreturn attribute if any declaration of that function specifies the noreturn attribute.
If a function is declared with the noreturn attribute in one translation unit and the same function is declared without the noreturn attribute in another translation unit, the program is ill-formed, no diagnostic required.
If a function f is called where f was previously declared with the noreturn attribute and f eventually returns, the behavior is undefined.
[Note
:
The function may terminate by throwing an exception.
end note
]
[Note
:
Implementations are encouraged to issue a warning if a function marked [[noreturn]] might return.
end note
]
[Example
:
[[ noreturn ]] void f() {
  throw "error";                // OK
}

[[ noreturn ]] void q(int i) {  // behavior is undefined if called with an argument <= 0
  if (i > 0)
    throw "positive";
}
end example
]

11 Declarators [dcl.decl]

A declarator declares a single variable, function, or type, within a declaration.
The init-declarator-list appearing in a declaration is a comma-separated sequence of declarators, each of which can have an initializer.
The three components of a simple-declaration are the attributes ([dcl.attr]), the specifiers (decl-specifier-seq; [dcl.spec]) and the declarators (init-declarator-list).
The specifiers indicate the type, storage class or other properties of the entities being declared.
The declarators specify the names of these entities and (optionally) modify the type of the specifiers with operators such as * (pointer to) and () (function returning).
Initial values can also be specified in a declarator; initializers are discussed in [dcl.init] and [class.init].
Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself.
[Note
:
A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator.
That is
T D1, D2, ... Dn;
is usually equivalent to
T D1; T D2; ... T Dn;
where T is a decl-specifier-seq and each Di is an init-declarator.
One exception is when a name introduced by one of the declarators hides a type name used by the decl-specifiers, so that when the same decl-specifiers are used in a subsequent declaration, they do not have the same meaning, as in
struct S { ... };
S S, T;                 // declare two instances of struct S
which is not equivalent to
struct S { ... };
S S;
S T;                    // error
Another exception is when T is auto ([dcl.spec.auto]), for example:
auto i = 1, j = 2.0;    // error: deduced types for i and j do not match
as opposed to
auto i = 1;             // OK: i deduced to have type int
auto j = 2.0;           // OK: j deduced to have type double
end note
]

11.1 Type names [dcl.name]

To specify type conversions explicitly, and as an argument of sizeof, alignof, new, or typeid, the name of a type shall be specified.
This can be done with a type-id, which is syntactically a declaration for a variable or function of that type that omits the name of the entity.
The named type is then the same as the type of the hypothetical identifier.
[Example
:
int                 // int i
int *               // int *pi
int *[3]            // int *p[3]
int (*)[3]          // int (*p3i)[3]
int *()             // int *f()
int (*)(double)     // int (*pf)(double)
name respectively the types “int”, “pointer to int”, “array of 3 pointers to int”, “pointer to array of 3 int”, “function of (no parameters) returning pointer to int”, and “pointer to a function of (double) returning int.
end example
]
A type can also be named (often more easily) by using a typedef ([dcl.typedef]).

11.2 Ambiguity resolution [dcl.ambig.res]

The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in [stmt.ambig] can also occur in the context of a declaration.
In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer.
Just as for the ambiguities mentioned in [stmt.ambig], the resolution is to consider any construct that could possibly be a declaration a declaration.
[Note
:
A declaration can be explicitly disambiguated by adding parentheses around the argument.
The ambiguity can be avoided by use of copy-initialization or list-initialization syntax, or by use of a non-function-style cast.
end note
]
[Example
:
struct S {
  S(int);
};

void foo(double a) {
  S w(int(a));                  // function declaration
  S x(int());                   // function declaration
  S y((int(a)));                // object declaration
  S y((int)a);                  // object declaration
  S z = int(a);                 // object declaration
}
end example
]
An ambiguity can arise from the similarity between a function-style cast and a type-id.
The resolution is that any construct that could possibly be a type-id in its syntactic context shall be considered a type-id.
[Example
:
template <class T> struct X {};
template <int N> struct Y {};
X<int()> a;                     // type-id
X<int(1)> b;                    // expression (ill-formed)
Y<int()> c;                     // type-id (ill-formed)
Y<int(1)> d;                    // expression

void foo(signed char a) {
  sizeof(int());                // type-id (ill-formed)
  sizeof(int(a));               // expression
  sizeof(int(unsigned(a)));     // type-id (ill-formed)

  (int())+1;                    // type-id (ill-formed)
  (int(a))+1;                   // expression
  (int(unsigned(a)))+1;         // type-id (ill-formed)
}
end example
]
Another ambiguity arises in a parameter-declaration-clause when a type-name is nested in parentheses.
In this case, the choice is between the declaration of a parameter of type pointer to function and the declaration of a parameter with redundant parentheses around the declarator-id.
The resolution is to consider the type-name as a simple-type-specifier rather than a declarator-id.
[Example
:
class C { };
void f(int(C)) { }              // void f(int(*fp)(C c)) { }
                                // not: void f(int C) { }

int g(C);

void foo() {
  f(1);                         // error: cannot convert 1 to function pointer
  f(g);                         // OK
}
For another example,
class C { };
void h(int *(C[10]));           // void h(int *(*_­fp)(C _­parm[10]));
                                // not: void h(int *C[10]);
end example
]

11.3 Meaning of declarators [dcl.meaning]

A declarator contains exactly one declarator-id; it names the identifier that is declared.
An unqualified-id occurring in a declarator-id shall be a simple identifier except for the declaration of some special functions ([class.ctor], [class.conv], [class.dtor], [over.oper]) and for the declaration of template specializations or partial specializations ([temp.spec]).
When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers (or, in the case of a namespace, of an element of the inline namespace set of that namespace ([namespace.def])) or to a specialization thereof; the member shall not merely have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id.
The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier.
[Note
:
If the qualifier is the global ​::​ scope resolution operator, the declarator-id refers to a name declared in the global namespace scope.
end note
]
The optional attribute-specifier-seq following a declarator-id appertains to the entity that is declared.
A static, thread_­local, extern, mutable, friend, inline, virtual, constexpr, explicit, or typedef specifier applies directly to each declarator-id in an init-declarator-list or member-declarator-list; the type specified for each declarator-id depends on both the decl-specifier-seq and its declarator.
Thus, a declaration of a particular identifier has the form
T D
where T is of the form attribute-specifier-seq decl-specifier-seq and D is a declarator.
Following is a recursive procedure for determining the type specified for the contained declarator-id by such a declaration.
First, the decl-specifier-seq determines a type.
In a declaration
T D
the decl-specifier-seq T determines the type T.
[Example
:
In the declaration
int unsigned i;
the type specifiers int unsigned determine the type “unsigned int” ([dcl.type.simple]).
end example
]
In a declaration attribute-specifier-seq T D where D is an unadorned identifier the type of this identifier is “T.
In a declaration T D where D has the form
( D1 )
the type of the contained declarator-id is the same as that of the contained declarator-id in the declaration
T D1
Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex declarators.

11.3.1 Pointers [dcl.ptr]

In a declaration T D where D has the form
* attribute-specifier-seq cv-qualifier-seq D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to T.
The cv-qualifiers apply to the pointer and not to the object pointed to.
Similarly, the optional attribute-specifier-seq appertains to the pointer and not to the object pointed to.
[Example
:
The declarations
const int ci = 10, *pc = &ci, *const cpc = pc, **ppc;
int i, *p, *const cp = &i;
declare ci, a constant integer; pc, a pointer to a constant integer; cpc, a constant pointer to a constant integer; ppc, a pointer to a pointer to a constant integer; i, an integer; p, a pointer to integer; and cp, a constant pointer to integer.
The value of ci, cpc, and cp cannot be changed after initialization.
The value of pc can be changed, and so can the object pointed to by cp.
Examples of some correct operations are
i = ci;
*cp = ci;
pc++;
pc = cpc;
pc = p;
ppc = &pc;
Examples of ill-formed operations are
ci = 1;             // error
ci++;               // error
*pc = 2;            // error
cp = &ci;           // error
cpc++;              // error
p = pc;             // error
ppc = &p;           // error
Each is unacceptable because it would either change the value of an object declared const or allow it to be changed through a cv-unqualified pointer later, for example:
*ppc = &ci;         // OK, but would make p point to ci because of previous error
*p = 5;             // clobber ci
end example
]
[Note
:
Forming a pointer to reference type is ill-formed; see [dcl.ref].
Forming a function pointer type is ill-formed if the function type has cv-qualifiers or a ref-qualifier; see [dcl.fct].
Since the address of a bit-field ([class.bit]) cannot be taken, a pointer can never point to a bit-field.
end note
]

11.3.2 References [dcl.ref]

In a declaration T D where D has either of the forms
& attribute-specifier-seq D1
&& attribute-specifier-seq D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list reference to T.
The optional attribute-specifier-seq appertains to the reference type.
Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier, in which case the cv-qualifiers are ignored.
[Example
:
typedef int& A;
const A aref = 3;   // ill-formed; lvalue reference to non-const initialized with rvalue
The type of aref is “lvalue reference to int”, not “lvalue reference to const int.
end example
]
[Note
:
A reference can be thought of as a name of an object.
end note
]
A declarator that specifies the type “reference to cv void” is ill-formed.
A reference type that is declared using & is called an lvalue reference, and a reference type that is declared using && is called an rvalue reference.
Lvalue references and rvalue references are distinct types.
Except where explicitly noted, they are semantically equivalent and commonly referred to as references.
[Example
:
void f(double& a) { a += 3.14; }
// ...
double d = 0;
f(d);
declares a to be a reference parameter of f so the call f(d) will add 3.14 to d.
int v[20];
// ...
int& g(int i) { return v[i]; }
// ...
g(3) = 7;
declares the function g() to return a reference to an integer so g(3)=7 will assign 7 to the fourth element of the array v.
For another example,
struct link {
  link* next;
};

link* first;

void h(link*& p) {  // p is a reference to pointer
  p->next = first;
  first = p;
  p = 0;
}

void k() {
   link* q = new link;
   h(q);
}
declares p to be a reference to a pointer to link so h(q) will leave q with the value zero.
end example
]
It is unspecified whether or not a reference requires storage ([basic.stc]).
There shall be no references to references, no arrays of references, and no pointers to references.
The declaration of a reference shall contain an initializer ([dcl.init.ref]) except when the declaration contains an explicit extern specifier ([dcl.stc]), is a class member ([class.mem]) declaration within a class definition, or is the declaration of a parameter or a return type ([dcl.fct]); see [basic.def].
A reference shall be initialized to refer to a valid object or function.
[Note
:
In particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior.
As described in [class.bit], a reference cannot be bound directly to a bit-field.
end note
]
If a typedef-name ([dcl.typedef], [temp.param]) or a decltype-specifier denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.
[Note
:
This rule is known as reference collapsing.
end note
]
[Example
:
int i;
typedef int& LRI;
typedef int&& RRI;

LRI& r1 = i;                    // r1 has the type int&
const LRI& r2 = i;              // r2 has the type int&
const LRI&& r3 = i;             // r3 has the type int&

RRI& r4 = i;                    // r4 has the type int&
RRI&& r5 = 5;                   // r5 has the type int&&

decltype(r2)& r6 = i;           // r6 has the type int&
decltype(r2)&& r7 = i;          // r7 has the type int&
end example
]
[Note
:
Forming a reference to function type is ill-formed if the function type has cv-qualifiers or a ref-qualifier; see [dcl.fct].
end note
]

11.3.3 Pointers to members [dcl.mptr]

In a declaration T D where D has the form
nested-name-specifier * attribute-specifier-seq cv-qualifier-seq D1
and the nested-name-specifier denotes a class, and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to member of class nested-name-specifier of type T.
The optional attribute-specifier-seq appertains to the pointer-to-member.
[Example
:
struct X {
  void f(int);
  int a;
};
struct Y;

int X::* pmi = &X::a;
void (X::* pmf)(int) = &X::f;
double X::* pmd;
char Y::* pmc;
declares pmi, pmf, pmd and pmc to be a pointer to a member of X of type int, a pointer to a member of X of type void(int), a pointer to a member of X of type double and a pointer to a member of Y of type char respectively.
The declaration of pmd is well-formed even though X has no members of type double.
Similarly, the declaration of pmc is well-formed even though Y is an incomplete type.
pmi and pmf can be used like this:
X obj;
// ...
obj.*pmi = 7;       // assign 7 to an integer member of obj
(obj.*pmf)(7);      // call a function member of obj with the argument 7
end example
]
A pointer to member shall not point to a static member of a class ([class.static]), a member with reference type, or “cv void.
[Note
:
The type “pointer to member” is distinct from the type “pointer”, that is, a pointer to member is declared only by the pointer to member declarator syntax, and never by the pointer declarator syntax.
There is no “reference-to-member” type in C++.
end note
]

11.3.4 Arrays [dcl.array]

In a declaration T D where D has the form
D1 [ constant-expression ] attribute-specifier-seq
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is an array type; if the type of the identifier of D contains the auto type-specifier, the program is ill-formed.
T is called the array element type; this type shall not be a reference type, cv void, a function type or an abstract class type.
If the constant-expression is present, it shall be a converted constant expression of type std​::​size_­t and its value shall be greater than zero.
The constant expression specifies the bound of (number of elements in) the array.
If the value of the constant expression is N, the array has N elements numbered 0 to N-1, and the type of the identifier of D is “derived-declarator-type-list array of N T.
An object of array type contains a contiguously allocated non-empty set of N subobjects of type T.
Except as noted below, if the constant expression is omitted, the type of the identifier of D is “derived-declarator-type-list array of unknown bound of T”, an incomplete object type.
The type “derived-declarator-type-list array of N T” is a different type from the type “derived-declarator-type-list array of unknown bound of T”, see [basic.types].
Any type of the form “cv-qualifier-seq array of N T” is adjusted to “array of N cv-qualifier-seq T”, and similarly for “array of unknown bound of T.
The optional attribute-specifier-seq appertains to the array.
[Example
:
typedef int A[5], AA[2][3];
typedef const A CA;             // type is “array of 5 const inttypedef const AA CAA;           // type is “array of 2 array of 3 const int
end example
]
[Note
:
An “array of N cv-qualifier-seq T” has cv-qualified type; see [basic.type.qualifier].
end note
]
An array can be constructed from one of the fundamental types (except void), from a pointer, from a pointer to member, from a class, from an enumeration type, or from another array.
When several “array of” specifications are adjacent, a multidimensional array type is created; only the first of the constant expressions that specify the bounds of the arrays may be omitted.
In addition to declarations in which an incomplete object type is allowed, an array bound may be omitted in some cases in the declaration of a function parameter ([dcl.fct]).
An array bound may also be omitted when the declarator is followed by an initializer or when a declarator for a static data member is followed by a brace-or-equal-initializer ([class.mem]).
In both cases the bound is calculated from the number of initial elements (say, N) supplied ([dcl.init.aggr]), and the type of the identifier of D is “array of N T.
Furthermore, if there is a preceding declaration of the entity in the same scope in which the bound was specified, an omitted array bound is taken to be the same as in that earlier declaration, and similarly for the definition of a static data member of a class.
[Example
:
float fa[17], *afp[17];
declares an array of float numbers and an array of pointers to float numbers.
For another example,
static int x3d[3][5][7];
declares a static three-dimensional array of integers, with rank .
In complete detail, x3d is an array of three items; each item is an array of five arrays; each of the latter arrays is an array of seven integers.
Any of the expressions x3d, x3d[i], x3d[i][j], x3d[i][j][k] can reasonably appear in an expression.
Finally,
extern int x[10];
struct S {
  static int y[10];
};

int x[];                // OK: bound is 10
int S::y[];             // OK: bound is 10

void f() {
  extern int x[];
  int i = sizeof(x);    // error: incomplete object type
}
end example
]
[Note
:
Conversions affecting expressions of array type are described in [conv.array].
Objects of array types cannot be modified, see [basic.lval].
end note
]
[Note
:
Except where it has been declared for a class ([over.sub]), the subscript operator [] is interpreted in such a way that E1[E2] is identical to *((E1)+(E2)) ([expr.sub]).
Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th member of E1.
Therefore, despite its asymmetric appearance, subscripting is a commutative operation.
end note
]
[Note
:
A consistent rule is followed for multidimensional arrays.
If E is an n-dimensional array of rank , then E appearing in an expression that is subject to the array-to-pointer conversion ([conv.array]) is converted to a pointer to an -dimensional array with rank .
If the * operator, either explicitly or implicitly as a result of subscripting, is applied to this pointer, the result is the pointed-to -dimensional array, which itself is immediately converted into a pointer.
[Example
:
Consider
int x[3][5];
Here x is a array of integers.
When x appears in an expression, it is converted to a pointer to (the first of three) five-membered arrays of integers.
In the expression x[i] which is equivalent to *(x+i), x is first converted to a pointer as described; then x+i is converted to the type of x, which involves multiplying i by the length of the object to which the pointer points, namely five integer objects.
The results are added and indirection applied to yield an array (of five integers), which in turn is converted to a pointer to the first of the integers.
If there is another subscript the same argument applies again; this time the result is an integer.
end example
]
end note
]
[Note
:
It follows from all this that arrays in C++ are stored row-wise (last subscript varies fastest) and that the first subscript in the declaration helps determine the amount of storage consumed by an array but plays no other part in subscript calculations.
end note
]

11.3.5 Functions [dcl.fct]

In a declaration T D where D has the form
D1 ( parameter-declaration-clause ) cv-qualifier-seq
ref-qualifier noexcept-specifier attribute-specifier-seq
and the type of the contained declarator-id in the declaration T D1 is “derived-declarator-type-list T”, the type of the declarator-id in D is “derived-declarator-type-list noexcept function of (parameter-declaration-clause) cv-qualifier-seq ref-qualifier returning T”, where the optional noexcept is present if and only if the exception specification ([except.spec]) is non-throwing.
The optional attribute-specifier-seq appertains to the function type.
In a declaration T D where D has the form
D1 ( parameter-declaration-clause ) cv-qualifier-seq
ref-qualifier noexcept-specifier attribute-specifier-seq trailing-return-type
and the type of the contained declarator-id in the declaration T D1 is “derived-declarator-type-list T”, T shall be the single type-specifier auto.
The type of the declarator-id in D is “derived-declarator-type-list noexcept function of (parameter-declaration-clause) cv-qualifier-seq ref-qualifier returning U”, where U is the type specified by the trailing-return-type, and where the optional noexcept is present if and only if the exception specification is non-throwing.
The optional attribute-specifier-seq appertains to the function type.
The parameter-declaration-clause determines the arguments that can be specified, and their processing, when the function is called.
[Note
:
The parameter-declaration-clause is used to convert the arguments specified on the function call; see [expr.call].
end note
]
If the parameter-declaration-clause is empty, the function takes no arguments.
A parameter list consisting of a single unnamed parameter of non-dependent type void is equivalent to an empty parameter list.
Except for this special case, a parameter shall not have type cv void.
If the parameter-declaration-clause terminates with an ellipsis or a function parameter pack ([temp.variadic]), the number of arguments shall be equal to or greater than the number of parameters that do not have a default argument and are not function parameter packs.
Where syntactically correct and where “...” is not part of an abstract-declarator, “, ...” is synonymous with “....
[Example
:
The declaration
int printf(const char*, ...);
declares a function that can be called with varying numbers and types of arguments.
printf("hello world");
printf("a=%d b=%d", a, b);
However, the first argument must be of a type that can be converted to a const char*
end example
]
[Note
:
The standard header <cstdarg> contains a mechanism for accessing arguments passed using the ellipsis (see [expr.call] and [support.runtime]).
end note
]
A single name can be used for several different functions in a single scope; this is function overloading (Clause [over]).
All declarations for a function shall agree exactly in both the return type and the parameter-type-list.
The type of a function is determined using the following rules.
The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator.
After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T.
After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type.
The resulting list of transformed parameter types and the presence or absence of the ellipsis or a function parameter pack is the function's parameter-type-list.
[Note
:
This transformation does not affect the types of the parameters.
For example, int(*)(const int p, decltype(p)*) and int(*)(int, const int*) are identical types.
end note
]
A function type with a cv-qualifier-seq or a ref-qualifier (including a type named by typedef-name ([dcl.typedef], [temp.param])) shall appear only as:
[Example
:
typedef int FIC(int) const;
FIC f;              // ill-formed: does not declare a member function
struct S {
  FIC f;            // OK
};
FIC S::*pm = &S::f; // OK
end example
]
The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type.
In the latter case, the cv-qualifiers are ignored.
[Note
:
A function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types.
end note
]
[Example
:
typedef void F();
struct S {
  const F f;        // OK: equivalent to: void f();
};
end example
]
The return type, the parameter-type-list, the ref-qualifier, the cv-qualifier-seq, and the exception specification, but not the default arguments ([dcl.fct.default]), are part of the function type.
[Note
:
Function types are checked during the assignments and initializations of pointers to functions, references to functions, and pointers to member functions.
end note
]
[Example
:
The declaration
int fseek(FILE*, long, int);
declares a function taking three arguments of the specified types, and returning int ([dcl.type]).
end example
]
Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.
There shall be no arrays of functions, although there can be arrays of pointers to functions.
Types shall not be defined in return or parameter types.
The type of a parameter or the return type for a function definition shall not be an incomplete (possibly cv-qualified) class type in the context of the function definition unless the function is deleted ([dcl.fct.def.delete]).
A typedef of function type may be used to declare a function but shall not be used to define a function ([dcl.fct.def]).
[Example
:
typedef void F();
F  fv;              // OK: equivalent to void fv();
F  fv { }           // ill-formed
void fv() { }       // OK: definition of fv
end example
]
An identifier can optionally be provided as a parameter name; if present in a function definition ([dcl.fct.def]), it names a parameter.
[Note
:
In particular, parameter names are also optional in function definitions and names used for a parameter in different declarations and the definition of a function need not be the same.
If a parameter name is present in a function declaration that is not a definition, it cannot be used outside of its function declarator because that is the extent of its potential scope ([basic.scope.proto]).
end note
]
[Example
:
The declaration
int i,
    *pi,
    f(),
    *fpi(int),
    (*pif)(const char*, const char*),
    (*fpif(int))(int);
declares an integer i, a pointer pi to an integer, a function f taking no arguments and returning an integer, a function fpi taking an integer argument and returning a pointer to an integer, a pointer pif to a function which takes two pointers to constant characters and returns an integer, a function fpif taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer.
It is especially useful to compare fpi and pif.
The binding of *fpi(int) is *(fpi(int)), so the declaration suggests, and the same construction in an expression requires, the calling of a function fpi, and then using indirection through the (pointer) result to yield an integer.
In the declarator (*pif)(const char*, const char*), the extra parentheses are necessary to indicate that indirection through a pointer to a function yields a function, which is then called.
end example
]
[Note
:
Typedefs and trailing-return-types are sometimes convenient when the return type of a function is complex.
For example, the function fpif above could have been declared
typedef int  IFUNC(int);
IFUNC*  fpif(int);
or
auto fpif(int)->int(*)(int);
A trailing-return-type is most useful for a type that would be more complicated to specify before the declarator-id:
template <class T, class U> auto add(T t, U u) -> decltype(t + u);
rather than
template <class T, class U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);
end note
]
A non-template function is a function that is not a function template specialization.
[Note
:
A function template is not a function.
end note
]
A declarator-id or abstract-declarator containing an ellipsis shall only be used in a parameter-declaration.
Such a parameter-declaration is a parameter pack ([temp.variadic]).
When it is part of a parameter-declaration-clause, the parameter pack is a function parameter pack ([temp.variadic]).
[Note
:
Otherwise, the parameter-declaration is part of a template-parameter-list and the parameter pack is a template parameter pack; see [temp.param].
end note
]
A function parameter pack is a pack expansion ([temp.variadic]).
[Example
:
template<typename... T> void f(T (* ...t)(int, int));

int add(int, int);
float subtract(int, int);

void g() {
  f(add, subtract);
}
end example
]
There is a syntactic ambiguity when an ellipsis occurs at the end of a parameter-declaration-clause without a preceding comma.
In this case, the ellipsis is parsed as part of the abstract-declarator if the type of the parameter either names a template parameter pack that has not been expanded or contains auto; otherwise, it is parsed as part of the parameter-declaration-clause.101
As indicated by syntax, cv-qualifiers are a significant component in function return types.
One can explicitly disambiguate the parse either by introducing a comma (so the ellipsis will be parsed as part of the parameter-declaration-clause) or by introducing a name for the parameter (so the ellipsis will be parsed as part of the declarator-id).

11.3.6 Default arguments [dcl.fct.default]

If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument.
Default arguments will be used in calls where trailing arguments are missing.
[Example
:
The declaration
void point(int = 3, int = 4);
declares a function that can be called with zero, one, or two arguments of type int.
It can be called in any of these ways:
point(1,2);  point(1);  point();
The last two calls are equivalent to point(1,4) and point(3,4), respectively.
end example
]
A default argument shall be specified only in the parameter-declaration-clause of a function declaration or lambda-declarator or in a template-parameter; in the latter case, the initializer-clause shall be an assignment-expression.
A default argument shall not be specified for a parameter pack.
If it is specified in a parameter-declaration-clause, it shall not occur within a declarator or abstract-declarator of a parameter-declaration.102
For non-template functions, default arguments can be added in later declarations of a function in the same scope.
Declarations in different scopes have completely distinct sets of default arguments.
That is, declarations in inner scopes do not acquire default arguments from declarations in outer scopes, and vice versa.
In a given function declaration, each parameter subsequent to a parameter with a default argument shall have a default argument supplied in this or a previous declaration or shall be a function parameter pack.
A default argument shall not be redefined by a later declaration (not even to the same value).
[Example
:
void g(int = 0, ...);           // OK, ellipsis is not a parameter so it can follow
                                // a parameter with a default argument
void f(int, int);
void f(int, int = 7);
void h() {
  f(3);                         // OK, calls f(3, 7)
  void f(int = 1, int);         // error: does not use default from surrounding scope
}
void m() {
  void f(int, int);             // has no defaults
  f(4);                         // error: wrong number of arguments
  void f(int, int = 5);         // OK
  f(4);                         // OK, calls f(4, 5);
  void f(int, int = 5);         // error: cannot redefine, even to same value
}
void n() {
  f(6);                         // OK, calls f(6, 7)
}
end example
]
For a given inline function defined in different translation units, the accumulated sets of default arguments at the end of the translation units shall be the same; see [basic.def.odr].
If a friend declaration specifies a default argument expression, that declaration shall be a definition and shall be the only declaration of the function or function template in the translation unit.
The default argument has the same semantic constraints as the initializer in a declaration of a variable of the parameter type, using the copy-initialization semantics ([dcl.init]).
The names in the default argument are bound, and the semantic constraints are checked, at the point where the default argument appears.
Name lookup and checking of semantic constraints for default arguments in function templates and in member functions of class templates are performed as described in [temp.inst].
[Example
:
In the following code, g will be called with the value f(2):
int a = 1;
int f(int);
int g(int x = f(a));            // default argument: f(​::​a)

void h() {
  a = 2;
  {
  int a = 3;
  g();                          // g(f(​::​a))
  }
}
end example
]
[Note
:
In member function declarations, names in default arguments are looked up as described in [basic.lookup.unqual].
Access checking applies to names in default arguments as described in Clause [class.access].
end note
]
Except for member functions of class templates, the default arguments in a member function definition that appears outside of the class definition are added to the set of default arguments provided by the member function declaration in the class definition; the program is ill-formed if a default constructor ([class.ctor]), copy or move constructor, or copy or move assignment operator ([class.copy]) is so declared.
Default arguments for a member function of a class template shall be specified on the initial declaration of the member function within the class template.
[Example
:
class C {
  void f(int i = 3);
  void g(int i, int j = 99);
};

void C::f(int i = 3) {}         // error: default argument already specified in class scope
void C::g(int i = 88, int j) {} // in this translation unit, C​::​g can be called with no argument
end example
]
A local variable shall not appear as a potentially-evaluated expression in a default argument.
[Example
:
void f() {
  int i;
  extern void g(int x = i);         // error
  extern void h(int x = sizeof(i)); // OK
  // ...
}
end example
]
[Note
:
The keyword this may not appear in a default argument of a member function; see [expr.prim.this].
[Example
:
class A {
  void f(A* p = this) { }           // error
};
end example
]
end note
]
A default argument is evaluated each time the function is called with no argument for the corresponding parameter.
A parameter shall not appear as a potentially-evaluated expression in a default argument.
Parameters of a function declared before a default argument are in scope and can hide namespace and class member names.
[Example
:
int a;
int f(int a, int b = a);            // error: parameter a used as default argument
typedef int I;
int g(float I, int b = I(2));       // error: parameter I found
int h(int a, int b = sizeof(a));    // OK, unevaluated operand
end example
]
A non-static member shall not appear in a default argument unless it appears as the id-expression of a class member access expression ([expr.ref]) or unless it is used to form a pointer to member ([expr.unary.op]).
[Example
:
The declaration of X​::​mem1() in the following example is ill-formed because no object is supplied for the non-static member X​::​a used as an initializer.
int b;
class X {
  int a;
  int mem1(int i = a);              // error: non-static member a used as default argument
  int mem2(int i = b);              // OK;  use X​::​b
  static int b;
};
The declaration of X​::​mem2() is meaningful, however, since no object is needed to access the static member X​::​b.
Classes, objects, and members are described in Clause [class].
end example
]
A default argument is not part of the type of a function.
[Example
:
int f(int = 0);

void h() {
  int j = f(1);
  int k = f();                      // OK, means f(0)
}

int (*p1)(int) = &f;
int (*p2)() = &f;                   // error: type mismatch
end example
]
When a declaration of a function is introduced by way of a using-declaration, any default argument information associated with the declaration is made known as well.
If the function is redeclared thereafter in the namespace with additional default arguments, the additional arguments are also known at any point following the redeclaration where the using-declaration is in scope.
A virtual function call ([class.virtual]) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object.
An overriding function in a derived class does not acquire default arguments from the function it overrides.
[Example
:
struct A {
  virtual void f(int a = 7);
};
struct B : public A {
  void f(int a);
};
void m() {
  B* pb = new B;
  A* pa = pb;
  pa->f();          // OK, calls pa->B​::​f(7)
  pb->f();          // error: wrong number of arguments for B​::​f()
}
end example
]
This means that default arguments cannot appear, for example, in declarations of pointers to functions, references to functions, or typedef declarations.

11.4 Function definitions [dcl.fct.def]

11.4.1 In general [dcl.fct.def.general]

Function definitions have the form
function-definition:
	attribute-specifier-seq decl-specifier-seq declarator virt-specifier-seq function-body
function-body:
	ctor-initializer compound-statement
	function-try-block
	= default ;
	= delete ;
Any informal reference to the body of a function should be interpreted as a reference to the non-terminal function-body.
The optional attribute-specifier-seq in a function-definition appertains to the function.
In a function-definition, either void declarator ; or declarator ; shall be a well-formed function declaration as described in [dcl.fct].
A function shall be defined only in namespace or class scope.
[Example
:
A simple example of a complete function definition is
int max(int a, int b, int c) {
  int m = (a > b) ? a : b;
  return (m > c) ? m : c;
}
Here int is the decl-specifier-seq; max(int a, int b, int c) is the declarator; { /* ... */ } is the function-body.
end example
]
A ctor-initializer is used only in a constructor; see [class.ctor] and [class.init].
[Note
:
A cv-qualifier-seq affects the type of this in the body of a member function; see [dcl.ref].
end note
]
[Note
:
Unused parameters need not be named.
For example,
void print(int a, int) {
  std::printf("a = %d\n",a);
}
end note
]
In the function-body, a function-local predefined variable denotes a block-scope object of static storage duration that is implicitly defined (see [basic.scope.block]).
The function-local predefined variable _­_­func_­_­ is defined as if a definition of the form
static const char __func__[] = "function-name";
had been provided, where function-name is an implementation-defined string.
It is unspecified whether such a variable has an address distinct from that of any other object in the program.103
[Example
:
struct S {
  S() : s(__func__) { }             // OK
  const char* s;
};
void f(const char* s = __func__);   // error: _­_­func_­_­ is undeclared
end example
]
Implementations are permitted to provide additional predefined variables with names that are reserved to the implementation ([lex.name]).
If a predefined variable is not odr-used ([basic.def.odr]), its string value need not be present in the program image.

11.4.2 Explicitly-defaulted functions [dcl.fct.def.default]

A function definition of the form:
attribute-specifier-seq decl-specifier-seq declarator virt-specifier-seq  = default ;
is called an explicitly-defaulted definition.
A function that is explicitly defaulted shall
  • be a special member function,
  • have the same declared function type (except for possibly differing ref-qualifiers and except that in the case of a copy constructor or copy assignment operator, the parameter type may be “reference to non-const T”, where T is the name of the member function's class) as if it had been implicitly declared, and
  • not have default arguments.
An explicitly-defaulted function that is not defined as deleted may be declared constexpr only if it would have been implicitly declared as constexpr.
If a function is explicitly defaulted on its first declaration, it is implicitly considered to be constexpr if the implicit declaration would be.
If a function that is explicitly defaulted is declared with a noexcept-specifier that does not produce the same exception specification as the implicit declaration ([except.spec]), then
  • if the function is explicitly defaulted on its first declaration, it is defined as deleted;
  • otherwise, the program is ill-formed.
[Example
:
struct S {
  constexpr S() = default;              // ill-formed: implicit S() is not constexpr
  S(int a = 0) = default;               // ill-formed: default argument
  void operator=(const S&) = default;   // ill-formed: non-matching return type
  ~S() noexcept(false) = default;       // deleted: exception specification does not match
private:
  int i;
  S(S&);                                // OK: private copy constructor
};
S::S(S&) = default;                     // OK: defines copy constructor
end example
]
Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy]), which might mean defining them as deleted.
A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.
A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.
[Note
:
Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base.
end note
]
[Example
:
struct trivial {
  trivial() = default;
  trivial(const trivial&) = default;
  trivial(trivial&&) = default;
  trivial& operator=(const trivial&) = default;
  trivial& operator=(trivial&&) = default;
  ~trivial() = default;
};

struct nontrivial1 {
  nontrivial1();
};
nontrivial1::nontrivial1() = default;   // not first declaration
end example
]

11.4.3 Deleted definitions [dcl.fct.def.delete]

A function definition of the form:
A function with a deleted definition is also called a deleted function.
A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.
[Note
:
This includes calling the function implicitly or explicitly and forming a pointer or pointer-to-member to the function.
It applies even for references in expressions that are not potentially-evaluated.
If a function is overloaded, it is referenced only if the function is selected by overload resolution.
The implicit odr-use ([basic.def.odr]) of a virtual function does not, by itself, constitute a reference.
end note
]
[Example
:
One can enforce non-default-initialization and non-integral initialization with
struct onlydouble {
  onlydouble() = delete;                // OK, but redundant
  onlydouble(std::intmax_t) = delete;
  onlydouble(double);
};
end example
]
[Example
:
One can prevent use of a class in certain new-expressions by using deleted definitions of a user-declared operator new for that class.
struct sometype {
  void* operator new(std::size_t) = delete;
  void* operator new[](std::size_t) = delete;
};
sometype* p = new sometype;     // error, deleted class operator new
sometype* q = new sometype[3];  // error, deleted class operator new[]
end example
]
[Example
:
One can make a class uncopyable, i.e. move-only, by using deleted definitions of the copy constructor and copy assignment operator, and then providing defaulted definitions of the move constructor and move assignment operator.
struct moveonly {
  moveonly() = default;
  moveonly(const moveonly&) = delete;
  moveonly(moveonly&&) = default;
  moveonly& operator=(const moveonly&) = delete;
  moveonly& operator=(moveonly&&) = default;
  ~moveonly() = default;
};
moveonly* p;
moveonly q(*p);                 // error, deleted copy constructor
end example
]
A deleted function is implicitly an inline function ([dcl.inline]).
[Note
:
The one-definition rule ([basic.def.odr]) applies to deleted definitions.
end note
]
A deleted definition of a function shall be the first declaration of the function or, for an explicit specialization of a function template, the first declaration of that specialization.
An implicitly declared allocation or deallocation function ([basic.stc.dynamic]) shall not be defined as deleted.
[Example
:
struct sometype {
  sometype();
};
sometype::sometype() = delete;  // ill-formed; not first declaration
end example
]

11.5 Structured binding declarations [dcl.struct.bind]

A structured binding declaration introduces the identifiers v, v, v, .
Let cv denote the cv-qualifiers in the decl-specifier-seq.
First, a variable with a unique name e is introduced.
If the assignment-expression in the initializer has array type A and no ref-qualifier is present, e has type cv A and each element is copy-initialized or direct-initialized from the corresponding element of the assignment-expression as specified by the form of the initializer.
Otherwise, e is defined as-if by
attribute-specifier-seq decl-specifier-seq ref-qualifier e initializer ;
where the declaration is never interpreted as a function declaration and the parts of the declaration other than the declarator-id are taken from the corresponding structured binding declaration.
The type of the id-expression e is called E.
[Note
:
E is never a reference type (Clause [expr]).
end note
]
If E is an array type with element type T, the number of elements in the identifier-list shall be equal to the number of elements of E.
Each v is the name of an lvalue that refers to the element i of the array and whose type is T; the referenced type is T.
[Note
:
The top-level cv-qualifiers of T are cv.
end note
]
[Example
:
  auto f() -> int(&)[2];
  auto [ x, y ] = f();          // x and y refer to elements in a copy of the array return value
  auto& [ xr, yr ] = f();       // xr and yr refer to elements in the array referred to by f's return value
end example
]
Otherwise, if the qualified-id std​::​tuple_­size<E> names a complete type, the expression std​::​tuple_­size<E>​::​value shall be a well-formed integral constant expression and the number of elements in the identifier-list shall be equal to the value of that expression.
The unqualified-id get is looked up in the scope of E by class member access lookup ([basic.lookup.classref]), and if that finds at least one declaration, the initializer is e.get<i>().
Otherwise, the initializer is get<i>(e), where get is looked up in the associated namespaces ([basic.lookup.argdep]).
In either case, get<i> is interpreted as a template-id.
[Note
:
Ordinary unqualified lookup ([basic.lookup.unqual]) is not performed.
end note
]
In either case, e is an lvalue if the type of the entity e is an lvalue reference and an xvalue otherwise.
Given the type designated by std​::​tuple_­element<i, E>​::​type, each v is a variable of type “reference to ” initialized with the initializer, where the reference is an lvalue reference if the initializer is an lvalue and an rvalue reference otherwise; the referenced type is .
Otherwise, all of E's non-static data members shall be public direct members of E or of the same unambiguous public base class of E, E shall not have an anonymous union member, and the number of elements in the identifier-list shall be equal to the number of non-static data members of E.
Designating the non-static data members of E as m, m, m, .
(in declaration order), each v is the name of an lvalue that refers to the member m of e and whose type is cv , where is the declared type of that member; the referenced type is cv .
The lvalue is a bit-field if that member is a bit-field.
[Example
:
struct S { int x1 : 2; volatile double y1; };
S f();
const auto [ x, y ] = f();
The type of the id-expression x is “const int”, the type of the id-expression y is “const volatile double.
end example
]

11.6 Initializers [dcl.init]

A declarator can specify an initial value for the identifier being declared.
The identifier designates a variable being initialized.
The process of initialization described in the remainder of [dcl.init] applies also to initializations specified by other syntactic contexts, such as the initialization of function parameters ([expr.call]) or the initialization of return values ([stmt.return]).
Except for objects declared with the constexpr specifier, for which see [dcl.constexpr], an initializer in the definition of a variable can consist of arbitrary expressions involving literals and previously declared variables and functions, regardless of the variable's storage duration.
[Example
:
int f(int);
int a = 2;
int b = f(a);
int c(b);
end example
]
[Note
:
Default arguments are more restricted; see [dcl.fct.default].
end note
]
[Note
:
The order of initialization of variables with static storage duration is described in [basic.start] and [stmt.dcl].
end note
]
A declaration of a block-scope variable with external or internal linkage that has an initializer is ill-formed.
To zero-initialize an object or reference of type T means:
  • if T is a scalar type ([basic.types]), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;104
  • if T is a (possibly cv-qualified) non-union class type, each non-static data member, each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized and padding is initialized to zero bits;
  • if T is a (possibly cv-qualified) union type, the object's first non-static named data member is zero-initialized and padding is initialized to zero bits;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
  • If T is a (possibly cv-qualified) class type (Clause [class]), constructors are considered.
    The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution ([over.match]).
    The constructor thus selected is called, with an empty argument list, to initialize the object.
  • If T is an array type, each element is default-initialized.
  • Otherwise, no initialization is performed.
A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if
  • each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,
  • if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,
  • if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and
  • each potentially constructed base class of T is const-default-constructible.
If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.
To value-initialize an object of type T means:
  • if T is a (possibly cv-qualified) class type (Clause [class]) with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;
  • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized.
A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.
[Note
:
Every object of static storage duration is zero-initialized at program startup before any other initialization takes place.
In some cases, additional initialization is done later.
end note
]
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
[Note
:
Since () is not permitted by the syntax for initializer,
X a();
is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X.
The form () is permitted in certain other initialization contexts ([expr.new], [expr.type.conv], [class.base.init]).
end note
]
If no initializer is specified for an object, the object is default-initialized.
When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]).
[Note
:
Objects with static or thread storage duration are zero-initialized, see [basic.start.static].
end note
]
If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:
  • If an indeterminate value of unsigned narrow character type ([basic.fundamental]) or std​::​byte type ([cstddef.syn]) is produced by the evaluation of: then the result of the operation is an indeterminate value.
  • If an indeterminate value of unsigned narrow character type or std​::​byte type is produced by the evaluation of the right operand of a simple assignment operator ([expr.ass]) whose first operand is an lvalue of unsigned narrow character type or std​::​byte type, an indeterminate value replaces the value of the object referred to by the left operand.
  • If an indeterminate value of unsigned narrow character type is produced by the evaluation of the initialization expression when initializing an object of unsigned narrow character type, that object is initialized to an indeterminate value.
  • If an indeterminate value of unsigned narrow character type or std​::​byte type is produced by the evaluation of the initialization expression when initializing an object of std​::​byte type, that object is initialized to an indeterminate value.
[Example
:
  int f(bool b) {
    unsigned char c;
    unsigned char d = c;        // OK, d has an indeterminate value
    int e = d;                  // undefined behavior
    return b ? d : 0;           // undefined behavior if b is true
  }
end example
]
An initializer for a static member is in the scope of the member's class.
[Example
:
int a;

struct X {
  static int a;
  static int b;
};

int X::a = 1;
int X::b = a;                   // X​::​b = X​::​a
end example
]
If the entity being initialized does not have class type, the expression-list in a parenthesized initializer shall be a single expression.
The initialization that occurs in the = form of a brace-or-equal-initializer or condition ([stmt.select]), as well as in argument passing, function return, throwing an exception ([except.throw]), handling an exception ([except.handle]), and aggregate member initialization ([dcl.init.aggr]), is called copy-initialization.
[Note
:
Copy-initialization may invoke a move ([class.copy]).
end note
]
The initialization that occurs in the forms
T x(a);
T x{a};
as well as in new expressions ([expr.new]), static_­cast expressions ([expr.static.cast]), functional notation type conversions ([expr.type.conv]), mem-initializers, and the braced-init-list form of a condition is called direct-initialization.
The semantics of initializers are as follows.
The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression.
If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.
  • If the initializer is a (non-parenthesized) braced-init-list or is = braced-init-list, the object or reference is list-initialized ([dcl.init.list]).
  • If the destination type is a reference type, see [dcl.init.ref].
  • If the destination type is an array of characters, an array of char16_­t, an array of char32_­t, or an array of wchar_­t, and the initializer is a string literal, see [dcl.init.string].
  • If the initializer is (), the object is value-initialized.
  • Otherwise, if the destination type is an array, the program is ill-formed.
  • If the destination type is a (possibly cv-qualified) class type:
    • If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object.
      [Example
      :
      T x = T(T(T())); calls the T default constructor to initialize x.
      end example
      ]
    • Otherwise, if the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered.
      The applicable constructors are enumerated ([over.match.ctor]), and the best one is chosen through overload resolution ([over.match]).
      The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s).
      If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.
    • Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in [over.match.copy], and the best one is chosen through overload resolution ([over.match]).
      If the conversion cannot be done or is ambiguous, the initialization is ill-formed.
      The function selected is called with the initializer expression as its argument; if the function is a constructor, the call is a prvalue of the cv-unqualified version of the destination type whose result object is initialized by the constructor.
      The call is used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization.
  • Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered.
    The applicable conversion functions are enumerated ([over.match.conv]), and the best one is chosen through overload resolution ([over.match]).
    The user-defined conversion so selected is called to convert the initializer expression into the object being initialized.
    If the conversion cannot be done or is ambiguous, the initialization is ill-formed.
  • Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression.
    Standard conversions (Clause [conv]) will be used, if necessary, to convert the initializer expression to the cv-unqualified version of the destination type; no user-defined conversions are considered.
    If the conversion cannot be done, the initialization is ill-formed.
    When initializing a bit-field with a value that it cannot represent, the resulting value of the bit-field is implementation-defined.
    [Note
    :
    An expression of type “cv1 T” can initialize an object of type “cv2 T” independently of the cv-qualifiers cv1 and cv2.
    int a;
    const int b = a;
    int c = b;
    end note
    ]
An initializer-clause followed by an ellipsis is a pack expansion ([temp.variadic]).
If the initializer is a parenthesized expression-list, the expressions are evaluated in the order specified for function calls ([expr.call]).
An object whose initialization has completed is deemed to be constructed, even if no constructor of the object's class is invoked for the initialization.
[Note
:
Such an object might have been value-initialized or initialized by aggregate initialization ([dcl.init.aggr]) or by an inherited constructor ([class.inhctor.init]).
end note
]
A declaration that specifies the initialization of a variable, whether from an explicit initializer or by default-initialization, is called the initializing declaration of that variable.
[Note
:
In most cases this is the defining declaration ([basic.def]) of the variable, but the initializing declaration of a non-inline static data member ([class.static.data]) might be the declaration within the class definition and not the definition at namespace scope.
end note
]
As specified in [conv.ptr], converting an integer literal whose value is 0 to a pointer type results in a null pointer value.

11.6.1 Aggregates [dcl.init.aggr]

An aggregate is an array or a class (Clause [class]) with
[Note
:
Aggregate initialization does not allow accessing protected and private base class' members or constructors.
end note
]
The elements of an aggregate are:
  • for an array, the array elements in increasing subscript order, or
  • for a class, the direct base classes in declaration order, followed by the direct non-static data members ([class.mem]) that are not members of an anonymous union, in declaration order.
When an aggregate is initialized by an initializer list as specified in [dcl.init.list], the elements of the initializer list are taken as initializers for the elements of the aggregate, in order.
Each element is copy-initialized from the corresponding initializer-clause.
If the initializer-clause is an expression and a narrowing conversion ([dcl.init.list]) is required to convert the expression, the program is ill-formed.
[Note
:
If an initializer-clause is itself an initializer list, the element is list-initialized, which will result in a recursive application of the rules in this section if the element is an aggregate.
end note
]
[Example
:
struct A {
  int x;
  struct B {
    int i;
    int j;
  } b;
} a = { 1, { 2, 3 } };
initializes a.x with 1, a.b.i with 2, a.b.j with 3.
struct base1 { int b1, b2 = 42; };
struct base2 {
  base2() {
    b3 = 42;
  }
  int b3;
};
struct derived : base1, base2 {
  int d;
};

derived d1{{1, 2}, {}, 4};
derived d2{{}, {}, 4};
initializes d1.b1 with 1, d1.b2 with 2, d1.b3 with 42, d1.d with 4, and d2.b1 with 0, d2.b2 with 42, d2.b3 with 42, d2.d with 4.
end example
]
An aggregate that is a class can also be initialized with a single expression not enclosed in braces, as described in [dcl.init].
An array of unknown bound initialized with a brace-enclosed initializer-list containing n initializer-clauses, where n shall be greater than zero, is defined as having n elements ([dcl.array]).
[Example
:
int x[] = { 1, 3, 5 };
declares and initializes x as a one-dimensional array that has three elements since no size was specified and there are three initializers.
end example
]
An empty initializer list {} shall not be used as the initializer-clause for an array of unknown bound.105
[Note
:
A default member initializer does not determine the bound for a member array of unknown bound.
Since the default member initializer is ignored if a suitable mem-initializer is present ([class.base.init]), the default member initializer is not considered to initialize the array of unknown bound.
[Example
:
struct S {
  int y[] = { 0 };          // error: non-static data member of incomplete type
};
end example
]
end note
]
[Note
:
Static data members and unnamed bit-fields are not considered elements of the aggregate.
[Example
:
struct A {
  int i;
  static int s;
  int j;
  int :17;
  int k;
} a = { 1, 2, 3 };
Here, the second initializer 2 initializes a.j and not the static data member A​::​s, and the third initializer 3 initializes a.k and not the unnamed bit-field before it.
end example
]
end note
]
An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of elements to initialize.
[Example
:
char cv[4] = { 'a', 's', 'd', 'f', 0 };     // error
is ill-formed.
end example
]
If there are fewer initializer-clauses in the list than there are elements in a non-union aggregate, then each element not explicitly initialized is initialized as follows:
  • If the element has a default member initializer ([class.mem]), the element is initialized from that initializer.
  • Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list ([dcl.init.list]).
  • Otherwise, the program is ill-formed.
If the aggregate is a union and the initializer list is empty, then
  • if any variant member has a default member initializer, that member is initialized from its default member initializer;
  • otherwise, the first member of the union (if any) is copy-initialized from an empty initializer list.
[Example
:
struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
initializes ss.a with 1, ss.b with "asdf", ss.c with the value of an expression of the form int{} (that is, 0), and ss.d with the value of ss.b[ss.a] (that is, 's'), and in
struct X { int i, j, k = 42; };
X a[] = { 1, 2, 3, 4, 5, 6 };
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
a and b have the same value
end example
]
If a reference member is initialized from its default member initializer and a potentially-evaluated subexpression thereof is an aggregate initialization that would use that default member initializer, the program is ill-formed.
[Example
:
  struct A;
  extern A a;
  struct A {
    const A& a1 { A{a,a} };     // OK
    const A& a2 { A{} };        // error
  };
  A a{a,a};                     // OK
end example
]
If an aggregate class C contains a subaggregate element e with no elements, the initializer-clause for e shall not be omitted from an initializer-list for an object of type C unless the initializer-clauses for all elements of C following e are also omitted.
[Example
:
struct S { } s;
struct A {
  S s1;
  int i1;
  S s2;
  int i2;
  S s3;
  int i3;
} a = {
  { },              // Required initialization
  0,
  s,                // Required initialization
  0
};                  // Initialization not required for A​::​s3 because A​::​i3 is also not initialized
end example
]
When initializing a multi-dimensional array, the initializer-clauses initialize the elements with the last (rightmost) index of the array varying the fastest ([dcl.array]).
[Example
:
int x[2][2] = { 3, 1, 4, 2 };
initializes x[0][0] to 3, x[0][1] to 1, x[1][0] to 4, and x[1][1] to 2.
On the other hand,
float y[4][3] = {
  { 1 }, { 2 }, { 3 }, { 4 }
};
initializes the first column of y (regarded as a two-dimensional array) and leaves the rest zero.
end example
]
Braces can be elided in an initializer-list as follows.
If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the elements of a subaggregate; it is erroneous for there to be more initializer-clauses than elements.
If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the elements of the subaggregate; any remaining initializer-clauses are left to initialize the next element of the aggregate of which the current subaggregate is an element.
[Example
:
float y[4][3] = {
  { 1, 3, 5 },
  { 2, 4, 6 },
  { 3, 5, 7 },
};
is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array y[0], namely y[0][0], y[0][1], and y[0][2].
Likewise the next two lines initialize y[1] and y[2].
The initializer ends early and therefore y[3]s elements are initialized as if explicitly initialized with an expression of the form float(), that is, are initialized with 0.0.
In the following example, braces in the initializer-list are elided; however the initializer-list has the same effect as the completely-braced initializer-list of the above example,
float y[4][3] = {
  1, 3, 5, 2, 4, 6, 3, 5, 7
};
The initializer for y begins with a left brace, but the one for y[0] does not, therefore three elements from the list are used.
Likewise the next three are taken successively for y[1] and y[2].
end example
]
All implicit type conversions (Clause [conv]) are considered when initializing the element with an assignment-expression.
If the assignment-expression can initialize an element, the element is initialized.
Otherwise, if the element is itself a subaggregate, brace elision is assumed and the assignment-expression is considered for the initialization of the first element of the subaggregate.
[Note
:
As specified above, brace elision cannot apply to subaggregates with no elements; an initializer-clause for the entire subobject is required.
end note
]
[Example
:
struct A {
  int i;
  operator int();
};
struct B {
  A a1, a2;
  int z;
};
A a;
B b = { 4, a, a };
Braces are elided around the initializer-clause for b.a1.i.
b.a1.i is initialized with 4, b.a2 is initialized with a, b.z is initialized with whatever a.operator int() returns.
end example
]
[Note
:
An aggregate array or an aggregate class may contain elements of a class type with a user-provided constructor ([class.ctor]).
Initialization of these aggregate objects is described in [class.expl.init].
end note
]
[Note
:
Whether the initialization of aggregates with static storage duration is static or dynamic is specified in [basic.start.static], [basic.start.dynamic], and [stmt.dcl].
end note
]
When a union is initialized with a brace-enclosed initializer, the braces shall only contain an initializer-clause for the first non-static data member of the union.
[Example
:
union u { int a; const char* b; };
u a = { 1 };
u b = a;
u c = 1;                        // error
u d = { 0, "asdf" };            // error
u e = { "asdf" };               // error
end example
]
[Note
:
As described above, the braces around the initializer-clause for a union member can be omitted if the union is a member of another aggregate.
end note
]
The syntax provides for empty initializer-lists, but nonetheless C++ does not have zero length arrays.

11.6.2 Character arrays [dcl.init.string]

An array of narrow character type ([basic.fundamental]), char16_­t array, char32_­t array, or wchar_­t array can be initialized by a narrow string literal, char16_­t string literal, char32_­t string literal, or wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces ([lex.string]).
Successive characters of the value of the string literal initialize the elements of the array.
[Example
:
char msg[] = "Syntax error on line %s\n";
shows a character array whose members are initialized with a string-literal.
Note that because '\n' is a single character and because a trailing '\0' is appended, sizeof(msg) is 25.
end example
]
There shall not be more initializers than there are array elements.
[Example
:
char cv[4] = "asdf";            // error
is ill-formed since there is no space for the implied trailing '\0'.
end example
]
If there are fewer initializers than there are array elements, each element not explicitly initialized shall be zero-initialized ([dcl.init]).

11.6.3 References [dcl.init.ref]

A variable whose declared type is “reference to type T” ([dcl.ref]) shall be initialized.
[Example
:
int g(int) noexcept;
void f() {
  int i;
  int& r = i;                   // r refers to i
  r = 1;                        // the value of i becomes 1
  int* p = &r;                  // p points to i
  int& rr = r;                  // rr refers to what r refers to, that is, to i
  int (&rg)(int) = g;           // rg refers to the function g
  rg(i);                        // calls function g
  int a[3];
  int (&ra)[3] = a;             // ra refers to the array a
  ra[1] = i;                    // modifies a[1]
}
end example
]
A reference cannot be changed to refer to another object after initialization.
[Note
:
Assignment to a reference assigns to the object referred to by the reference ([expr.ass]).
end note
]
Argument passing ([expr.call]) and function value return ([stmt.return]) are initializations.
The initializer can be omitted for a reference only in a parameter declaration ([dcl.fct]), in the declaration of a function return type, in the declaration of a class member within its class definition ([class.mem]), and where the extern specifier is explicitly used.
[Example
:
int& r1;                        // error: initializer missing
extern int& r2;                 // OK
end example
]
Given types “cv1 T1” and “cv2 T2”, “cv1 T1” is reference-related to “cv2 T2” if T1 is the same type as T2, or T1 is a base class of T2.
cv1 T1” is reference-compatible with “cv2 T2” if
  • T1 is reference-related to T2, or
  • T2 is “noexcept function” and T1 is “function”, where the function types are otherwise the same,
and cv1 is the same cv-qualification as, or greater cv-qualification than, cv2.
In all cases where the reference-related or reference-compatible relationship of two types is used to establish the validity of a reference binding, and T1 is a base class of T2, a program that necessitates such a binding is ill-formed if T1 is an inaccessible (Clause [class.access]) or ambiguous ([class.member.lookup]) base class of T2.
A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
  • If the reference is an lvalue reference and the initializer expression
    • is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2”, or
    • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be converted to an lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3106 (this conversion is selected by enumerating the applicable conversion functions ([over.match.ref]) and choosing the best one through overload resolution ([over.match])),
    then the reference is bound to the initializer expression lvalue in the first case and to the lvalue result of the conversion in the second case (or, in either case, to the appropriate base class subobject of the object).
    [Note
    :
    The usual lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions are not needed, and therefore are suppressed, when such direct bindings to lvalues are done.
    end note
    ]
    [Example
    :
    double d = 2.0;
    double& rd = d;                 // rd refers to d
    const double& rcd = d;          // rcd refers to d
    
    struct A { };
    struct B : A { operator int&(); } b;
    A& ra = b;                      // ra refers to A subobject in b
    const A& rca = b;               // rca refers to A subobject in b
    int& ir = B();                  // ir refers to the result of B​::​operator int&
    
    end example
    ]
  • Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference.
    [Example
    :
    double& rd2 = 2.0;              // error: not an lvalue and reference not const
    int  i = 2;
    double& rd3 = i;                // error: type mismatch and reference not const
    
    end example
    ]
    • If the initializer expression
      • is an rvalue (but not a bit-field) or function lvalue and “cv1 T1” is reference-compatible with “cv2 T2”, or
      • has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be converted to an rvalue or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3” (see [over.match.ref]),
      then the value of the initializer expression in the first case and the result of the conversion in the second case is called the converted initializer.
      If the converted initializer is a prvalue, its type T4 is adjusted to type “cv1 T4” ([conv.qual]) and the temporary materialization conversion ([conv.rval]) is applied.
      In any case, the reference is bound to the resulting glvalue (or to an appropriate base class subobject).
      [Example
      :
      struct A { };
      struct B : A { } b;
      extern B f();
      const A& rca2 = f();                // bound to the A subobject of the B rvalue.
      A&& rra = f();                      // same as above
      struct X {
        operator B();
        operator int&();
      } x;
      const A& r = x;                     // bound to the A subobject of the result of the conversion
      int i2 = 42;
      int&& rri = static_cast<int&&>(i2); // bound directly to i2
      B&& rrb = x;                        // bound directly to the result of operator B
      
      end example
      ]
    • Otherwise:
      • If T1 or T2 is a class type and T1 is not reference-related to T2, user-defined conversions are considered using the rules for copy-initialization of an object of type “cv1 T1” by user-defined conversion ([dcl.init], [over.match.copy], [over.match.conv]); the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed.
        The result of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference.
        For this direct-initialization, user-defined conversions are not considered.
      • Otherwise, the initializer expression is implicitly converted to a prvalue of type “cv1 T1.
        The temporary materialization conversion is applied and the reference is bound to the result.
      If T1 is reference-related to T2:
      • cv1 shall be the same cv-qualification as, or greater cv-qualification than, cv2; and
      • if the reference is an rvalue reference, the initializer expression shall not be an lvalue.
      [Example
      :
      struct Banana { };
      struct Enigma { operator const Banana(); };
      struct Alaska { operator Banana&(); };
      void enigmatic() {
        typedef const Banana ConstBanana;
        Banana &&banana1 = ConstBanana(); // ill-formed
        Banana &&banana2 = Enigma();      // ill-formed
        Banana &&banana3 = Alaska();      // ill-formed
      }
      
      const double& rcd2 = 2;         // rcd2 refers to temporary with value 2.0
      double&& rrd = 2;               // rrd refers to temporary with value 2.0
      const volatile int cvi = 1;
      const int& r2 = cvi;            // error: cv-qualifier dropped
      struct A { operator volatile int&(); } a;
      const int& r3 = a;              // error: cv-qualifier dropped
                                      // from result of conversion function
      double d2 = 1.0;
      double&& rrd2 = d2;             // error: initializer is lvalue of related type
      struct X { operator int&(); };
      int&& rri2 = X();               // error: result of conversion function is lvalue of related type
      int i3 = 2;
      double&& rrd3 = i3;             // rrd3 refers to temporary with value 2.0
      
      end example
      ]
In all cases except the last (i.e., implicitly converting the initializer expression to the underlying type of the reference), the reference is said to bind directly to the initializer expression.
[Note
:
[class.temporary] describes the lifetime of temporaries bound to references.
end note
]
This requires a conversion function ([class.conv.fct]) returning a reference type.

11.6.4 List-initialization [dcl.init.list]

List-initialization is initialization of an object or reference from a braced-init-list.
Such an initializer is called an initializer list, and the comma-separated initializer-clauses of the list are called the elements of the initializer list.
An initializer list may be empty.
List-initialization can occur in direct-initialization or copy-initialization contexts; list-initialization in a direct-initialization context is called direct-list-initialization and list-initialization in a copy-initialization context is called copy-list-initialization.
[Note
:
List-initialization can be used
[Example
:
int a = {1};
std::complex<double> z{1,2};
new std::vector<std::string>{"once", "upon", "a", "time"};  // 4 string elements
f( {"Nicholas","Annemarie"} );  // pass list of two elements
return { "Norah" };             // return list of one element
int* e {};                      // initialization to zero / null pointer
x = double{1};                  // explicitly construct a double
std::map<std::string,int> anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} };
end example
]
end note
]
A constructor is an initializer-list constructor if its first parameter is of type std​::​initializer_­list<E> or reference to possibly cv-qualified std​::​initializer_­list<E> for some type E, and either there are no other parameters or else all other parameters have default arguments ([dcl.fct.default]).
[Note
:
Initializer-list constructors are favored over other constructors in list-initialization ([over.match.list]).
Passing an initializer list as the argument to the constructor template template<class T> C(T) of a class C does not create an initializer-list constructor, because an initializer list argument causes the corresponding parameter to be a non-deduced context ([temp.deduct.call]).
end note
]
The template std​::​initializer_­list is not predefined; if the header <initializer_­list> is not included prior to a use of std​::​initializer_­list — even an implicit use in which the type is not named ([dcl.spec.auto]) — the program is ill-formed.
List-initialization of an object or reference of type T is defined as follows:
  • If T is an aggregate class and the initializer list has a single element of type cv U, where U is T or a class derived from T, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization).
  • Otherwise, if T is a character array and the initializer list has a single element that is an appropriately-typed string literal ([dcl.init.string]), initialization is performed as described in that section.
  • Otherwise, if T is an aggregate, aggregate initialization is performed ([dcl.init.aggr]).
    [Example
    :
    double ad[] = { 1, 2.0 };           // OK
    int ai[] = { 1, 2.0 };              // error: narrowing
    
    struct S2 {
      int m1;
      double m2, m3;
    };
    S2 s21 = { 1, 2, 3.0 };             // OK
    S2 s22 { 1.0, 2, 3 };               // error: narrowing
    S2 s23 { };                         // OK: default to 0,0,0
    
    end example
    ]
  • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
  • Otherwise, if T is a specialization of std​::​initializer_­list<E>, the object is constructed as described below.
  • Otherwise, if T is a class type, constructors are considered.
    The applicable constructors are enumerated and the best one is chosen through overload resolution ([over.match], [over.match.list]).
    If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.
    [Example
    :
    struct S {
      S(std::initializer_list<double>); // #1
      S(std::initializer_list<int>);    // #2
      S();                              // #3
      // ...
    };
    S s1 = { 1.0, 2.0, 3.0 };           // invoke #1
    S s2 = { 1, 2, 3 };                 // invoke #2
    S s3 = { };                         // invoke #3
    
    end example
    ]
    [Example
    :
    struct Map {
      Map(std::initializer_list<std::pair<std::string,int>>);
    };
    Map ship = {{"Sophie",14}, {"Surprise",28}};
    end example
    ]
    [Example
    :
    struct S {
      // no initializer-list constructors
      S(int, double, double);           // #1
      S();                              // #2
      // ...
    };
    S s1 = { 1, 2, 3.0 };               // OK: invoke #1
    S s2 { 1.0, 2, 3 };                 // error: narrowing
    S s3 { };                           // OK: invoke #2
    
    end example
    ]
  • Otherwise, if T is an enumeration with a fixed underlying type ([dcl.enum]), the initializer-list has a single element v, and the initialization is direct-list-initialization, the object is initialized with the value T(v) ([expr.type.conv]); if a narrowing conversion is required to convert v to the underlying type of T, the program is ill-formed.
    [Example
    :
    enum byte : unsigned char { };
    byte b { 42 };                      // OK
    byte c = { 42 };                    // error
    byte d = byte{ 42 };                // OK; same value as b
    byte e { -1 };                      // error
    
    struct A { byte b; };
    A a1 = { { 42 } };                  // error
    A a2 = { byte{ 42 } };              // OK
    
    void f(byte);
    f({ 42 });                          // error
    
    enum class Handle : uint32_t { Invalid = 0 };
    Handle h { 42 };                    // OK
    
    end example
    ]
  • Otherwise, if the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization); if a narrowing conversion (see below) is required to convert the element to T, the program is ill-formed.
    [Example
    :
    int x1 {2};                         // OK
    int x2 {2.0};                       // error: narrowing
    
    end example
    ]
  • Otherwise, if T is a reference type, a prvalue of the type referenced by T is generated.
    The prvalue initializes its result object by copy-list-initialization or direct-list-initialization, depending on the kind of initialization for the reference.
    The prvalue is then used to direct-initialize the reference.
    [Note
    :
    As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type.
    end note
    ]
    [Example
    :
    struct S {
      S(std::initializer_list<double>); // #1
      S(const std::string&);            // #2
      // ...
    };
    const S& r1 = { 1, 2, 3.0 };        // OK: invoke #1
    const S& r2 { "Spinach" };          // OK: invoke #2
    S& r3 = { 1, 2, 3 };                // error: initializer is not an lvalue
    const int& i1 = { 1 };              // OK
    const int& i2 = { 1.1 };            // error: narrowing
    const int (&iar)[2] = { 1, 2 };     // OK: iar is bound to temporary array
    
    end example
    ]
  • Otherwise, if the initializer list has no elements, the object is value-initialized.
    [Example
    :
    int** pp {};                        // initialized to null pointer
    
    end example
    ]
  • Otherwise, the program is ill-formed.
    [Example
    :
    struct A { int i; int j; };
    A a1 { 1, 2 };                      // aggregate initialization
    A a2 { 1.2 };                       // error: narrowing
    struct B {
      B(std::initializer_list<int>);
    };
    B b1 { 1, 2 };                      // creates initializer_­list<int> and calls constructor
    B b2 { 1, 2.0 };                    // error: narrowing
    struct C {
      C(int i, double j);
    };
    C c1 = { 1, 2.2 };                  // calls constructor with arguments (1, 2.2)
    C c2 = { 1.1, 2 };                  // error: narrowing
    
    int j { 1 };                        // initialize to 1
    int k { };                          // initialize to 0
    
    end example
    ]
Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions ([temp.variadic]), are evaluated in the order in which they appear.
That is, every value computation and side effect associated with a given initializer-clause is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list.
[Note
:
This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the initializer-list are interpreted as arguments of a constructor call, even though ordinarily there are no sequencing constraints on the arguments of a call.
end note
]
An object of type std​::​initializer_­list<E> is constructed from an initializer list as if the implementation generated and materialized ([conv.rval]) a prvalue of type “array of N const E”, where N is the number of elements in the initializer list.
Each element of that array is copy-initialized with the corresponding element of the initializer list, and the std​::​initializer_­list<E> object is constructed to refer to that array.
[Note
:
A constructor or conversion function selected for the copy shall be accessible (Clause [class.access]) in the context of the initializer list.
end note
]
If a narrowing conversion is required to initialize any of the elements, the program is ill-formed.
[Example
:
struct X {
  X(std::initializer_list<double> v);
};
X x{ 1,2,3 };
The initialization will be implemented in a way roughly equivalent to this:
const double __a[3] = {double{1}, double{2}, double{3}};
X x(std::initializer_list<double>(__a, __a+3));
assuming that the implementation can construct an initializer_­list object with a pair of pointers.
end example
]
The array has the same lifetime as any other temporary object ([class.temporary]), except that initializing an initializer_­list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.
[Example
:
typedef std::complex<double> cmplx;
std::vector<cmplx> v1 = { 1, 2, 3 };

void f() {
  std::vector<cmplx> v2{ 1, 2, 3 };
  std::initializer_list<int> i3 = { 1, 2, 3 };
}

struct A {
  std::initializer_list<int> i4;
  A() : i4{ 1, 2, 3 } {}  // ill-formed, would create a dangling reference
};
For v1 and v2, the initializer_­list object is a parameter in a function call, so the array created for { 1, 2, 3 } has full-expression lifetime.
For i3, the initializer_­list object is a variable, so the array persists for the lifetime of the variable.
For i4, the initializer_­list object is initialized in the constructor's ctor-initializer as if by binding a temporary array to a reference member, so the program is ill-formed ([class.base.init]).
end example
]
[Note
:
The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated.
end note
]
A narrowing conversion is an implicit conversion
  • from a floating-point type to an integer type, or
  • from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or
  • from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or
  • from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
[Note
:
As indicated above, such conversions are not allowed at the top level in list-initializations.
end note
]
[Example
:
int x = 999;              // x is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x;              // OK, though it might narrow (in this case, it does narrow)
char c2{x};               // error: might narrow
char c3{y};               // error: narrows (assuming char is 8 bits)
char c4{z};               // OK: no narrowing needed
unsigned char uc1 = {5};  // OK: no narrowing needed
unsigned char uc2 = {-1}; // error: narrows
unsigned int ui1 = {-1};  // error: narrows
signed int si1 =
  { (unsigned int)-1 };   // error: narrows
int ii = {2.0};           // error: narrows
float f1 { x };           // error: might narrow
float f2 { 7 };           // OK: 7 can be exactly represented as a float
int f(int);
int a[] =
  { 2, f(2), f(2.0) };    // OK: the double-to-int conversion is not at the top level
end example
]

12 Classes [class]

A class is a type.
Its name becomes a class-name ([class.name]) within its scope.
An object of a class consists of a (possibly empty) sequence of members and base class objects.
[Note
:
An unnamed class thus can't be final.
end note
]
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen.
The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name.
For purposes of access checking, the injected-class-name is treated as if it were a public member name.
A class-specifier is commonly referred to as a class definition.
A class is considered defined after the closing brace of its class-specifier has been seen even though its member functions are in general not yet defined.
The optional attribute-specifier-seq appertains to the class; the attributes in the attribute-specifier-seq are thereafter considered attributes of the class whenever it is named.
If a class is marked with the class-virt-specifier final and it appears as a class-or-decltype in a base-clause, the program is ill-formed.
Whenever a class-key is followed by a class-head-name, the identifier final, and a colon or left brace, final is interpreted as a class-virt-specifier.
[Example
:
struct A;
struct A final {};      // OK: definition of struct A,
                        // not value-initialization of variable final

struct X {
 struct C { constexpr operator int() { return 5; } };
 struct B final : C{};  // OK: definition of nested class B,
                        // not declaration of a bit-field member final
};
end example
]
Complete objects and member subobjects of class type shall have nonzero size.107
[Note
:
Class objects can be assigned, passed as arguments to functions, and returned by functions (except objects of classes for which copying or moving has been restricted; see [class.copy]).
Other plausible operators, such as equality comparison, can be defined by the user; see [over.oper].
end note
]
A union is a class defined with the class-key union; it holds at most one data member at a time ([class.union]).
[Note
:
Aggregates of class type are described in [dcl.init.aggr].
end note
]
  • where each copy constructor, move constructor, copy assignment operator, and move assignment operator ([class.copy], [over.ass]) is either deleted or trivial,
  • that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator, and
  • that has a trivial, non-deleted destructor ([class.dtor]).
A trivial class is a class that is trivially copyable and has one or more default constructors ([class.ctor]), all of which are either trivial or deleted and at least one of which is not deleted.
[Note
:
In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.
end note
]
A class S is a standard-layout class if it:
  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]),
  • has the same access control (Clause [class.access]) for all non-static data members,
  • has no non-standard-layout base classes,
  • has at most one base class subobject of any given type,
  • has all non-static data members and bit-fields in the class and its base classes first declared in the same class, and
  • has no element of the set M(S) of types (defined below) as a base class.108
M(X) is defined as follows:
  • If X is a non-union class type with no (possibly inherited (Clause [class.derived])) non-static data members, the set M(X) is empty.
  • If X is a non-union class type whose first non-static data member has type (where said member may be an anonymous union), the set M(X) consists of and the elements of .
  • If X is a union type, the set M(X) is the union of all and the set containing all , where each is the type of the ith non-static data member of X.
  • If X is an array type with element type , the set M(X) consists of and the elements of .
  • If X is a non-class, non-array type, the set M(X) is empty.
[Note
:
M(X) is the set of the types of all non-base-class subobjects that are guaranteed in a standard-layout class to be at a zero offset in X.
end note
]
[Example
:
   struct B { int i; };         // standard-layout class
   struct C : B { };            // standard-layout class
   struct D : C { };            // standard-layout class
   struct E : D { char : 4; };  // not a standard-layout class

   struct Q {};
   struct S : Q { };
   struct T : Q { };
   struct U : S, T { };         // not a standard-layout class
end example
]
A standard-layout struct is a standard-layout class defined with the class-key struct or the class-key class.
A standard-layout union is a standard-layout class defined with the class-key union.
[Note
:
Standard-layout classes are useful for communicating with code written in other programming languages.
Their layout is specified in [class.mem].
end note
]
A POD struct109 is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types).
Similarly, a POD union is a union that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types).
A POD class is a class that is either a POD struct or a POD union.
[Example
:
struct N {          // neither trivial nor standard-layout
  int i;
  int j;
  virtual ~N();
};

struct T {          // trivial but not standard-layout
  int i;
private:
  int j;
};

struct SL {         // standard-layout but not trivial
  int i;
  int j;
  ~SL();
};

struct POD {        // both trivial and standard-layout
  int i;
  int j;
};
end example
]
If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set ([namespace.def]) of that namespace (i.e., not merely inherited or introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration.
In such cases, the nested-name-specifier of the class-head-name of the definition shall not begin with a decltype-specifier.
Base class subobjects are not so constrained.
This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address ([expr.eq]).
The acronym POD stands for “plain old data”.

12.1 Class names [class.name]

A class definition introduces a new type.
[Example
:
struct X { int a; };
struct Y { int a; };
X a1;
Y a2;
int a3;
declares three variables of three different types.
This implies that
a1 = a2;                        // error: Y assigned to X
a1 = a3;                        // error: int assigned to X
are type mismatches, and that
int f(X);
int f(Y);
declare an overloaded (Clause [over]) function f() and not simply a single function f() twice.
For the same reason,
struct S { int a; };
struct S { int a; };            // error, double definition
is ill-formed because it defines S twice.
end example
]
A class declaration introduces the class name into the scope where it is declared and hides any class, variable, function, or other declaration of that name in an enclosing scope ([basic.scope]).
If a class name is declared in a scope where a variable, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier ([basic.lookup.elab]).
[Example
:
struct stat {
  // ...
};

stat gstat;                     // use plain stat to define variable

int stat(struct stat*);         // redeclare stat as function

void f() {
  struct stat* ps;              // struct prefix needed to name struct stat
  stat(ps);                     // call stat()
}
end example
]
A declaration consisting solely of class-key identifier; is either a redeclaration of the name in the current scope or a forward declaration of the identifier as a class name.
It introduces the class name into the current scope.
[Example
:
struct s { int a; };

void g() {
  struct s;                     // hide global struct s with a block-scope declaration
  s* p;                         // refer to local struct s
  struct s { char* p; };        // define local struct s
  struct s;                     // redeclaration, has no effect
}
end example
]
[Note
:
Such declarations allow definition of classes that refer to each other.
[Example
:
class Vector;

class Matrix {
  // ...
  friend Vector operator*(const Matrix&, const Vector&);
};

class Vector {
  // ...
  friend Vector operator*(const Matrix&, const Vector&);
};
Declaration of friends is described in [class.friend], operator functions in [over.oper].
end example
]
end note
]
[Note
:
An elaborated-type-specifier ([dcl.type.elab]) can also be used as a type-specifier as part of a declaration.
It differs from a class declaration in that if a class of the elaborated name is in scope the elaborated name will refer to it.
end note
]
[Example
:
struct s { int a; };

void g(int s) {
  struct s* p = new struct s;   // global s
  p->a = s;                     // parameter s
}
end example
]
[Note
:
The declaration of a class name takes effect immediately after the identifier is seen in the class definition or elaborated-type-specifier.
For example,
class A * A;
first specifies A to be the name of a class and then redefines it as the name of a pointer to an object of that class.
This means that the elaborated form class A must be used to refer to the class.
Such artistry with names can be confusing and is best avoided.
end note
]
A typedef-name that names a class type, or a cv-qualified version thereof, is also a class-name.
If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored.
A typedef-name shall not be used as the identifier in a class-head.

12.2 Class members [class.mem]

The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere.
A direct member of a class X is a member of X that was first declared within the member-specification of X, including anonymous union objects ([class.union.anon]) and direct members thereof.
Members of a class are data members, member functions ([class.mfct]), nested types, enumerators, and member templates ([temp.mem]) and specializations thereof.
[Note
:
A specialization of a static data member template is a static data member.
A specialization of a member function template is a member function.
A specialization of a member class template is a nested class.
end note
]
A member-declaration does not declare new members of the class if it is
For any other member-declaration, each declared entity that is not an unnamed bit-field ([class.bit]) is a member of the class, and each such member-declaration shall either declare at least one member name of the class or declare at least one unnamed bit-field.
A data member is a non-function member introduced by a member-declarator.
A member function is a member that is a function.
Nested types are classes ([class.name], [class.nest]) and enumerations ([dcl.enum]) declared in the class and arbitrary types declared as members by use of a typedef declaration ([dcl.typedef]) or alias-declaration.
The enumerators of an unscoped enumeration ([dcl.enum]) defined in the class are members of the class.
A data member or member function may be declared static in its member-declaration, in which case it is a static member (see [class.static]) (a static data member ([class.static.data]) or static member function ([class.static.mfct]), respectively) of the class.
Any other data member or member function is a non-static member (a non-static data member or non-static member function ([class.mfct.non-static]), respectively).
[Note
:
A non-static data member of non-reference type is a member subobject of a class object ([intro.object]).
end note
]
A member shall not be declared twice in the member-specification, except that
[Note
:
A single name can denote several member functions provided their types are sufficiently different (Clause [over]).
end note
]
A class is considered a completely-defined object type ([basic.types]) (or complete type) at the closing } of the class-specifier.
Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes).
Otherwise it is regarded as incomplete within its own class member-specification.
In a member-declarator, an = immediately following the declarator is interpreted as introducing a pure-specifier if the declarator-id has function type, otherwise it is interpreted as introducing a brace-or-equal-initializer.
[Example
:
struct S {
  using T = void();
  T * p = 0;        // OK: brace-or-equal-initializer
  virtual T f = 0;  // OK: pure-specifier
};
end example
]
A brace-or-equal-initializer shall appear only in the declaration of a data member.
(For static data members, see [class.static.data]; for non-static data members, see [class.base.init] and [dcl.init.aggr]).
A brace-or-equal-initializer for a non-static data member specifies a default member initializer for the member, and shall not directly or indirectly cause the implicit definition of a defaulted default constructor for the enclosing class or the exception specification of that constructor.
A member shall not be declared with the extern storage-class-specifier.
Within a class definition, a member shall not be declared with the thread_­local storage-class-specifier unless also declared static.
The decl-specifier-seq may be omitted in constructor, destructor, and conversion function declarations only; when declaring another kind of member the decl-specifier-seq shall contain a type-specifier that is not a cv-qualifier.
The member-declarator-list can be omitted only after a class-specifier or an enum-specifier or in a friend declaration ([class.friend]).
A pure-specifier shall be used only in the declaration of a virtual function ([class.virtual]) that is not a friend declaration.
The optional attribute-specifier-seq in a member-declaration appertains to each of the entities declared by the member-declarators; it shall not appear if the optional member-declarator-list is omitted.
A virt-specifier-seq shall contain at most one of each virt-specifier.
A virt-specifier-seq shall appear only in the declaration of a virtual member function ([class.virtual]).
Non-static data members shall not have incomplete types.
In particular, a class C shall not contain a non-static member of class C, but it can contain a pointer or reference to an object of class C.
[Note
:
See [expr.prim] for restrictions on the use of non-static data members and non-static member functions.
end note
]
[Note
:
The type of a non-static member function is an ordinary function type, and the type of a non-static data member is an ordinary object type.
There are no special member function types or data member types.
end note
]
[Example
:
A simple example of a class definition is
struct tnode {
  char tword[20];
  int count;
  tnode* left;
  tnode* right;
};
which contains an array of twenty characters, an integer, and two pointers to objects of the same type.
Once this definition has been given, the declaration
tnode s, *sp;
declares s to be a tnode and sp to be a pointer to a tnode.
With these declarations, sp->count refers to the count member of the object to which sp points; s.left refers to the left subtree pointer of the object s; and s.right->tword[0] refers to the initial character of the tword member of the right subtree of s.
end example
]
Non-static data members of a (non-union) class with the same access control (Clause [class.access]) are allocated so that later members have higher addresses within a class object.
The order of allocation of non-static data members with different access control is unspecified (Clause [class.access]).
Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions ([class.virtual]) and virtual base classes ([class.mi]).
If T is the name of a class, then each of the following shall have a name different from T:
  • every static data member of class T;
  • every member function of class T
    [Note
    :
    This restriction does not apply to constructors, which do not have names ([class.ctor])
    end note
    ]
    ;
  • every member of class T that is itself a type;
  • every member template of class T;
  • every enumerator of every member of class T that is an unscoped enumerated type; and
  • every member of every anonymous union that is a member of class T.
In addition, if class T has a user-declared constructor ([class.ctor]), every non-static data member of class T shall have a name different from T.
The common initial sequence of two standard-layout struct (Clause [class]) types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types and either neither entity is a bit-field or both are bit-fields with the same width.
[Example
:
  struct A { int a; char b; };
  struct B { const int b1; volatile char b2; };
  struct C { int c; unsigned : 0; char b; };
  struct D { int d; char b : 4; };
  struct E { unsigned int e; char b; };
The common initial sequence of A and B comprises all members of either class.
The common initial sequence of A and C and of A and D comprises the first member in each case.
The common initial sequence of A and E is empty.
end example
]
Two standard-layout struct (Clause [class]) types are layout-compatible classes if their common initial sequence comprises all members and bit-fields of both classes ([basic.types]).
Two standard-layout unions are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in any order) have layout-compatible types ([basic.types]).
In a standard-layout union with an active member ([class.union]) of struct type T1, it is permitted to read a non-static data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2; the behavior is as if the corresponding member of T1 were nominated.
[Example
:
struct T1 { int a, b; };
struct T2 { int c; double d; };
union U { T1 t1; T2 t2; };
int f() {
  U u = { { 1, 2 } };   // active member is t1
  return u.t2.c;        // OK, as if u.t1.a were nominated
}
end example
]
[Note
:
Reading a volatile object through a non-volatile glvalue has undefined behavior ([dcl.type.cv]).
end note
]
If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member.
Otherwise, its address is the same as the address of its first base class subobject (if any).
[Note
:
There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment.
end note
]
[Note
:
The object and its first subobject are pointer-interconvertible ([basic.compound], [expr.static.cast]).
end note
]

12.2.1 Member functions [class.mfct]

A member function may be defined ([dcl.fct.def]) in its class definition, in which case it is an inline member function ([dcl.inline]), or it may be defined outside of its class definition if it has already been declared but not defined in its class definition.
A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition.
Except for member function definitions that appear outside of a class definition, and except for explicit specializations of member functions of class templates and member function templates ([temp.spec]) appearing outside of the class definition, a member function shall not be redeclared.
An inline member function (whether static or non-static) may also be defined outside of its class definition provided either its declaration in the class definition or its definition outside of the class definition declares the function as inline or constexpr.
[Note
:
Member functions of a class in namespace scope have the linkage of that class.
Member functions of a local class ([class.local]) have no linkage.
end note
]
[Note
:
There can be at most one definition of a non-inline member function in a program.
There may be more than one inline member function definition in a program.
end note
]
If the definition of a member function is lexically outside its class definition, the member function name shall be qualified by its class name using the ​::​ operator.
[Note
:
A name used in a member function definition (that is, in the parameter-declaration-clause including the default arguments ([dcl.fct.default]) or in the member function body) is looked up as described in [basic.lookup].
end note
]
[Example
:
struct X {
  typedef int T;
  static T count;
  void f(T);
};
void X::f(T t = count) { }
The member function f of class X is defined in global scope; the notation X​::​f specifies that the function f is a member of class X and in the scope of class X.
In the function definition, the parameter type T refers to the typedef member T declared in class X and the default argument count refers to the static data member count declared in class X.
end example
]
[Note
:
A static local variable or local type in a member function always refers to the same entity, whether or not the member function is inline.
end note
]
Previously declared member functions may be mentioned in friend declarations.
Member functions of a local class shall be defined inline in their class definition, if they are defined at all.
[Note
:
A member function can be declared (but not defined) using a typedef for a function type.
The resulting member function has exactly the same type as it would have if the function declarator were provided explicitly, see [dcl.fct].
For example,
typedef void fv();
typedef void fvc() const;
struct S {
  fv memfunc1;      // equivalent to: void memfunc1();
  void memfunc2();
  fvc memfunc3;     // equivalent to: void memfunc3() const;
};
fv  S::* pmfv1 = &S::memfunc1;
fv  S::* pmfv2 = &S::memfunc2;
fvc S::* pmfv3 = &S::memfunc3;
Also see [temp.arg].
end note
]

12.2.2 Non-static member functions [class.mfct.non-static]

A non-static member function may be called for an object of its class type, or for an object of a class derived (Clause [class.derived]) from its class type, using the class member access syntax ([expr.ref], [over.match.call]).
A non-static member function may also be called directly using the function call syntax ([expr.call], [over.match.call]) from within the body of a member function of its class or of a class derived from its class.
If a non-static member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined.
When an id-expression ([expr.prim]) that is not part of a class member access syntax ([expr.ref]) and not used to form a pointer to member ([expr.unary.op]) is used in a member of class X in a context where this can be used ([expr.prim.this]), if name lookup ([basic.lookup]) resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression ([expr.ref]) using (*this) ([class.this]) as the postfix-expression to the left of the . operator.
[Note
:
If C is not X or a base class of X, the class member access expression is ill-formed.
end note
]
Similarly during name lookup, when an unqualified-id ([expr.prim]) used in the definition of a member function for class X resolves to a static member, an enumerator or a nested type of class X or of a base class of X, the unqualified-id is transformed into a qualified-id ([expr.prim]) in which the nested-name-specifier names the class of the member function.
These transformations do not apply in the template definition context ([temp.dep.type]).
[Example
:
struct tnode {
  char tword[20];
  int count;
  tnode* left;
  tnode* right;
  void set(const char*, tnode* l, tnode* r);
};

void tnode::set(const char* w, tnode* l, tnode* r) {
  count = strlen(w)+1;
  if (sizeof(tword)<=count)
      perror("tnode string too long");
  strcpy(tword,w);
  left = l;
  right = r;
}

void f(tnode n1, tnode n2) {
  n1.set("abc",&n2,0);
  n2.set("def",0,0);
}
In the body of the member function tnode​::​set, the member names tword, count, left, and right refer to members of the object for which the function is called.
Thus, in the call n1.set("abc",&n2,0), tword refers to n1.tword, and in the call n2.set("def",0,0), it refers to n2.tword.
The functions strlen, perror, and strcpy are not members of the class tnode and should be declared elsewhere.110
end example
]
A non-static member function may be declared const, volatile, or const volatile.
These cv-qualifiers affect the type of the this pointer ([class.this]).
They also affect the function type ([dcl.fct]) of the member function; a member function declared const is a const member function, a member function declared volatile is a volatile member function and a member function declared const volatile is a const volatile member function.
[Example
:
struct X {
  void g() const;
  void h() const volatile;
};
X​::​g is a const member function and X​::​h is a const volatile member function.
end example
]
A non-static member function may be declared with a ref-qualifier ([dcl.fct]); see [over.match.funcs].
A non-static member function may be declared virtual ([class.virtual]) or pure virtual ([class.abstract]).
See, for example, <cstring> ([c.strings]).

12.2.2.1 The this pointer [class.this]

In the body of a non-static ([class.mfct]) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called.
The type of this in a member function of a class X is X*.
If the member function is declared const, the type of this is const X*, if the member function is declared volatile, the type of this is volatile X*, and if the member function is declared const volatile, the type of this is const volatile X*.
[Note
:
Thus in a const member function, the object for which the function is called is accessed through a const access path.
end note
]
[Example
:
struct s {
  int a;
  int f() const;
  int g() { return a++; }
  int h() const { return a++; } // error
};

int s::f() const { return a; }
The a++ in the body of s​::​h is ill-formed because it tries to modify (a part of) the object for which s​::​h() is called.
This is not allowed in a const member function because this is a pointer to const; that is, *this has const type.
end example
]
Similarly, volatile semantics ([dcl.type.cv]) apply in volatile member functions when accessing the object and its non-static data members.
A cv-qualified member function can be called on an object-expression ([expr.ref]) only if the object-expression is as cv-qualified or less-cv-qualified than the member function.
[Example
:
void k(s& x, const s& y) {
  x.f();
  x.g();
  y.f();
  y.g();                        // error
}
The call y.g() is ill-formed because y is const and s​::​g() is a non-const member function, that is, s​::​g() is less-qualified than the object-expression y.
end example
]
Constructors ([class.ctor]) and destructors ([class.dtor]) shall not be declared const, volatile or const volatile.
[Note
:
However, these functions can be invoked to create and destroy objects with cv-qualified types, see [class.ctor] and [class.dtor].
end note
]

12.2.3 Static members [class.static]

A static member s of class X may be referred to using the qualified-id expression X​::​s; it is not necessary to use the class member access syntax ([expr.ref]) to refer to a static member.
A static member may be referred to using the class member access syntax, in which case the object expression is evaluated.
[Example
:
struct process {
  static void reschedule();
};
process& g();

void f() {
  process::reschedule();        // OK: no object necessary
  g().reschedule();             // g() is called
}
end example
]
A static member may be referred to directly in the scope of its class or in the scope of a class derived (Clause [class.derived]) from its class; in this case, the static member is referred to as if a qualified-id expression was used, with the nested-name-specifier of the qualified-id naming the class scope from which the static member is referenced.
[Example
:
int g();
struct X {
  static int g();
};
struct Y : X {
  static int i;
};
int Y::i = g();                 // equivalent to Y​::​g();
end example
]
If an unqualified-id ([expr.prim]) is used in the definition of a static member following the member's declarator-id, and name lookup ([basic.lookup.unqual]) finds that the unqualified-id refers to a static member, enumerator, or nested type of the member's class (or of a base class of the member's class), the unqualified-id is transformed into a qualified-id expression in which the nested-name-specifier names the class scope from which the member is referenced.
[Note
:
See [expr.prim] for restrictions on the use of non-static data members and non-static member functions.
end note
]
Static members obey the usual class member access rules (Clause [class.access]).
When used in the declaration of a class member, the static specifier shall only be used in the member declarations that appear within the member-specification of the class definition.
[Note
:
It cannot be specified in member declarations that appear in namespace scope.
end note
]

12.2.3.1 Static member functions [class.static.mfct]

[Note
:
The rules described in [class.mfct] apply to static member functions.
end note
]
[Note
:
A static member function does not have a this pointer ([class.this]).
end note
]
A static member function shall not be virtual.
There shall not be a static and a non-static member function with the same name and the same parameter types ([over.load]).
A static member function shall not be declared const, volatile, or const volatile.

12.2.3.2 Static data members [class.static.data]

A static data member is not part of the subobjects of a class.
If a static data member is declared thread_­local there is one copy of the member per thread.
If a static data member is not declared thread_­local there is one copy of the data member that is shared by all the objects of the class.
The declaration of a non-inline static data member in its class definition is not a definition and may be of an incomplete type other than cv void.
The definition for a static data member that is not defined inline in the class definition shall appear in a namespace scope enclosing the member's class definition.
In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the ​::​ operator.
The initializer expression in the definition of a static data member is in the scope of its class ([basic.scope.class]).
[Example
:
class process {
  static process* run_chain;
  static process* running;
};

process* process::running = get_main();
process* process::run_chain = running;
The static data member run_­chain of class process is defined in global scope; the notation process​::​run_­chain specifies that the member run_­chain is a member of class process and in the scope of class process.
In the static data member definition, the initializer expression refers to the static data member running of class process.
end example
]
[Note
:
Once the static data member has been defined, it exists even if no objects of its class have been created.
[Example
:
In the example above, run_­chain and running exist even if no objects of class process are created by the program.
end example
]
end note
]
If a non-volatile non-inline const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression ([expr.const]).
The member shall still be defined in a namespace scope if it is odr-used ([basic.def.odr]) in the program and the namespace scope definition shall not contain an initializer.
An inline static data member may be defined in the class definition and may specify a brace-or-equal-initializer.
If the member is declared with the constexpr specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated; see [depr.static_constexpr]).
Declarations of other static data members shall not specify a brace-or-equal-initializer.
[Note
:
There shall be exactly one definition of a static data member that is odr-used ([basic.def.odr]) in a program; no diagnostic is required.
end note
]
Unnamed classes and classes contained directly or indirectly within unnamed classes shall not contain static data members.
[Note
:
Static data members of a class in namespace scope have the linkage of that class ([basic.link]).
A local class cannot have static data members ([class.local]).
end note
]
Static data members are initialized and destroyed exactly like non-local variables ([basic.start.static], [basic.start.dynamic], [basic.start.term]).
A static data member shall not be mutable ([dcl.stc]).

12.2.4 Bit-fields [class.bit]

A member-declarator of the form
identifier attribute-specifier-seq : constant-expression
specifies a bit-field; its length is set off from the bit-field name by a colon.
The optional attribute-specifier-seq appertains to the entity being declared.
The bit-field attribute is not part of the type of the class member.
The constant-expression shall be an integral constant expression with a value greater than or equal to zero.
The value of the integral constant expression may be larger than the number of bits in the object representation ([basic.types]) of the bit-field's type; in such cases the extra bits are used as padding bits and do not participate in the value representation ([basic.types]) of the bit-field.
Allocation of bit-fields within a class object is implementation-defined.
Alignment of bit-fields is implementation-defined.
Bit-fields are packed into some addressable allocation unit.
[Note
:
Bit-fields straddle allocation units on some machines and not on others.
Bit-fields are assigned right-to-left on some machines, left-to-right on others.
end note
]
A declaration for a bit-field that omits the identifier declares an unnamed bit-field.
Unnamed bit-fields are not members and cannot be initialized.
[Note
:
An unnamed bit-field is useful for padding to conform to externally-imposed layouts.
end note
]
As a special case, an unnamed bit-field with a width of zero specifies alignment of the next bit-field at an allocation unit boundary.
Only when declaring an unnamed bit-field may the value of the constant-expression be equal to zero.
A bit-field shall not be a static member.
A bit-field shall have integral or enumeration type ([basic.fundamental]).
A bool value can successfully be stored in a bit-field of any nonzero size.
The address-of operator & shall not be applied to a bit-field, so there are no pointers to bit-fields.
A non-const reference shall not be bound to a bit-field ([dcl.init.ref]).
[Note
:
If the initializer for a reference of type const T& is an lvalue that refers to a bit-field, the reference is bound to a temporary initialized to hold the value of the bit-field; the reference is not bound to the bit-field directly.
end note
]
If the value true or false is stored into a bit-field of type bool of any size (including a one bit bit-field), the original bool value and the value of the bit-field shall compare equal.
If the value of an enumerator is stored into a bit-field of the same enumeration type and the number of bits in the bit-field is large enough to hold all the values of that enumeration type ([dcl.enum]), the original enumerator value and the value of the bit-field shall compare equal.
[Example
:
enum BOOL { FALSE=0, TRUE=1 };
struct A {
  BOOL b:1;
};
A a;
void f() {
  a.b = TRUE;
  if (a.b == TRUE)              // yields true
    { /* ... */ }
}
end example
]

12.2.5 Nested class declarations [class.nest]

A class can be declared within another class.
A class declared within another is called a nested class.
The name of a nested class is local to its enclosing class.
The nested class is in the scope of its enclosing class.
[Note
:
See [expr.prim] for restrictions on the use of non-static data members and non-static member functions.
end note
]
[Example
:
int x;
int y;

struct enclose {
  int x;
  static int s;

  struct inner {
    void f(int i) {
      int a = sizeof(x);        // OK: operand of sizeof is an unevaluated operand
      x = i;                    // error: assign to enclose​::​x
      s = i;                    // OK: assign to enclose​::​s
      ::x = i;                  // OK: assign to global x
      y = i;                    // OK: assign to global y
    }
    void g(enclose* p, int i) {
      p->x = i;                 // OK: assign to enclose​::​x
    }
  };
};

inner* p = 0;                   // error: inner not in scope
end example
]
Member functions and static data members of a nested class can be defined in a namespace scope enclosing the definition of their class.
[Example
:
struct enclose {
  struct inner {
    static int x;
    void f(int i);
  };
};

int enclose::inner::x = 1;

void enclose::inner::f(int i) { /* ... */ }
end example
]
If class X is defined in a namespace scope, a nested class Y may be declared in class X and later defined in the definition of class X or be later defined in a namespace scope enclosing the definition of class X.
[Example
:
class E {
  class I1;                     // forward declaration of nested class
  class I2;
  class I1 { };                 // definition of nested class
};
class E::I2 { };                // definition of nested class
end example
]
Like a member function, a friend function ([class.friend]) defined within a nested class is in the lexical scope of that class; it obeys the same rules for name binding as a static member function of that class ([class.static]), but it has no special access rights to members of an enclosing class.

12.2.6 Nested type names [class.nested.type]

Type names obey exactly the same scope rules as other names.
In particular, type names defined within a class definition cannot be used outside their class without qualification.
[Example
:
struct X {
  typedef int I;
  class Y { /* ... */ };
  I a;
};

I b;                            // error
Y c;                            // error
X::Y d;                         // OK
X::I e;                         // OK
end example
]

12.3 Unions [class.union]

In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended ([basic.life]).
At most one of the non-static data members of an object of union type can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.
[Note
:
One special guarantee is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout structs that share a common initial sequence ([class.mem]), and if a non-static data member of an object of this standard-layout union type is active and is one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of the standard-layout struct members; see [class.mem].
end note
]
The size of a union is sufficient to contain the largest of its non-static data members.
Each non-static data member is allocated as if it were the sole member of a struct.
[Note
:
A union object and its non-static data members are pointer-interconvertible ([basic.compound], [expr.static.cast]).
As a consequence, all non-static data members of a union object have the same address.
end note
]
A union can have member functions (including constructors and destructors), but it shall not have virtual ([class.virtual]) functions.
A union shall not have base classes.
A union shall not be used as a base class.
If a union contains a non-static data member of reference type the program is ill-formed.
[Note
:
Absent default member initializers ([class.mem]), if any non-static data member of a union has a non-trivial default constructor ([class.ctor]), copy constructor ([class.copy]), move constructor ([class.copy]), copy assignment operator ([class.copy]), move assignment operator ([class.copy]), or destructor ([class.dtor]), the corresponding member function of the union must be user-provided or it will be implicitly deleted ([dcl.fct.def.delete]) for the union.
end note
]
[Example
:
Consider the following union:
union U {
  int i;
  float f;
  std::string s;
};
Since std​::​string ([string.classes]) declares non-trivial versions of all of the special member functions, U will have an implicitly deleted default constructor, copy/move constructor, copy/move assignment operator, and destructor.
To use U, some or all of these member functions must be user-provided.
end example
]
When the left operand of an assignment operator involves a member access expression ([expr.ref]) that nominates a union member, it may begin the lifetime of that union member, as described below.
For an expression E, define the set S(E) of subexpressions of E as follows:
  • If E is of the form A.B, S(E) contains the elements of S(A), and also contains A.B if B names a union member of a non-class, non-array type, or of a class type with a trivial default constructor that is not deleted, or an array of such types.
  • If E is of the form A[B] and is interpreted as a built-in array subscripting operator, S(E) is S(A) if A is of array type, S(B) if B is of array type, and empty otherwise.
  • Otherwise, S(E) is empty.
In an assignment expression of the form E1 = E2 that uses either the built-in assignment operator ([expr.ass]) or a trivial assignment operator ([class.copy]), for each element X of S(E1), if modification of X would have undefined behavior under [basic.life], an object of the type of X is implicitly created in the nominated storage; no initialization is performed and the beginning of its lifetime is sequenced after the value computation of the left and right operands and before the assignment.
[Note
:
This ends the lifetime of the previously-active member of the union, if any ([basic.life]).
end note
]
[Example
:
union A { int x; int y[4]; };
struct B { A a; };
union C { B b; int k; };
int f() {
  C c;                  // does not start lifetime of any union member
  c.b.a.y[3] = 4;       // OK: S(c.b.a.y[3]) contains c.b and c.b.a.y;
                        // creates objects to hold union members c.b and c.b.a.y
  return c.b.a.y[3];    // OK: c.b.a.y refers to newly created object (see [basic.life])
}

struct X { const int a; int b; };
union Y { X x; int k; };
void g() {
  Y y = { { 1, 2 } };   // OK, y.x is active union member ([class.mem])
  int n = y.x.a;
  y.k = 4;              // OK: ends lifetime of y.x, y.k is active member of union
  y.x.b = n;            // undefined behavior: y.x.b modified outside its lifetime,
                        // S(y.x.b) is empty because X's default constructor is deleted,
                        // so union member y.x's lifetime does not implicitly start
}
end example
]
[Note
:
In general, one must use explicit destructor calls and placement new-expression to change the active member of a union.
end note
]
[Example
:
Consider an object u of a union type U having non-static data members m of type M and n of type N.
If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement new-expression as follows:
u.m.~M();
new (&u.n) N;
end example
]

12.3.1 Anonymous unions [class.union.anon]

A union of the form
union { member-specification } ;
is called an anonymous union; it defines an unnamed type and an unnamed object of that type called an anonymous union object.
Each member-declaration in the member-specification of an anonymous union shall either define a non-static data member or be a static_assert-declaration.
[Note
:
Nested types, anonymous unions, and functions cannot be declared within an anonymous union.
end note
]
The names of the members of an anonymous union shall be distinct from the names of any other entity in the scope in which the anonymous union is declared.
For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared.
[Example
:
void f() {
  union { int a; const char* p; };
  a = 1;
  p = "Jennifer";
}
Here a and p are used like ordinary (non-member) variables, but since they are union members they have the same address.
end example
]
Anonymous unions declared in a named namespace or in the global namespace shall be declared static.
Anonymous unions declared at block scope shall be declared with any storage class allowed for a block-scope variable, or with no storage class.
A storage class is not allowed in a declaration of an anonymous union in a class scope.
An anonymous union shall not have private or protected members (Clause [class.access]).
An anonymous union shall not have member functions.
A union for which objects, pointers, or references are declared is not an anonymous union.
[Example
:
void f() {
  union { int aa; char* p; } obj, *ptr = &obj;
  aa = 1;           // error
  ptr->aa = 1;      // OK
}
The assignment to plain aa is ill-formed since the member name is not visible outside the union, and even if it were visible, it is not associated with any particular object.
end example
]
[Note
:
Initialization of unions with no user-declared constructors is described in [dcl.init.aggr].
end note
]
A union-like class is a union or a class that has an anonymous union as a direct member.
A union-like class X has a set of variant members.
If X is a union, a non-static data member of X that is not an anonymous union is a variant member of X.
In addition, a non-static data member of an anonymous union that is a member of X is also a variant member of X.
At most one variant member of a union may have a default member initializer.
[Example
:
union U {
  int x = 0;
  union {
    int k;
  };
  union {
    int z;
    int y = 1;      // error: initialization for second variant member of U
  };
};
end example
]

12.4 Local class declarations [class.local]

A class can be declared within a function definition; such a class is called a local class.
The name of a local class is local to its enclosing scope.
The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function.
Declarations in a local class shall not odr-use ([basic.def.odr]) a variable with automatic storage duration from an enclosing scope.
[Example
:
int x;
void f() {
  static int s;
  int x;
  const int N = 5;
  extern int q();

  struct local {
    int g() { return x; }       // error: odr-use of automatic variable x
    int h() { return s; }       // OK
    int k() { return ::x; }     // OK
    int l() { return q(); }     // OK
    int m() { return N; }       // OK: not an odr-use
    int* n() { return &N; }     // error: odr-use of automatic variable N
  };
}

local* p = 0;                   // error: local not in scope
end example
]
An enclosing function has no special access to members of the local class; it obeys the usual access rules (Clause [class.access]).
Member functions of a local class shall be defined within their class definition, if they are defined at all.
If class X is a local class a nested class Y may be declared in class X and later defined in the definition of class X or be later defined in the same scope as the definition of class X.
A class nested within a local class is a local class.
A local class shall not have static data members.

13 Derived classes [class.derived]

A class-or-decltype shall denote a class type that is not an incompletely defined class (Clause [class]).
The class denoted by the class-or-decltype of a base-specifier is called a direct base class for the class being defined.
During the lookup for a base class name, non-type names are ignored ([basic.scope.hiding]).
If the name found is not a class-name, the program is ill-formed.
A class B is a base class of a class D if it is a direct base class of D or a direct base class of one of D's base classes.
A class is an indirect base class of another if it is a base class but not a direct base class.
A class is said to be (directly or indirectly) derived from its (direct or indirect) base classes.
[Note
:
See Clause [class.access] for the meaning of access-specifier.
end note
]
Unless redeclared in the derived class, members of a base class are also considered to be members of the derived class.
Members of a base class other than constructors are said to be inherited by the derived class.
Constructors of a base class can also be inherited as described in [namespace.udecl].
Inherited members can be referred to in expressions in the same manner as other members of the derived class, unless their names are hidden or ambiguous ([class.member.lookup]).
[Note
:
The scope resolution operator ​::​ ([expr.prim]) can be used to refer to a direct or indirect base member explicitly.
This allows access to a name that has been redeclared in the derived class.
A derived class can itself serve as a base class subject to access control; see [class.access.base].
A pointer to a derived class can be implicitly converted to a pointer to an accessible unambiguous base class ([conv.ptr]).
An lvalue of a derived class type can be bound to a reference to an accessible unambiguous base class ([dcl.init.ref]).
end note
]
The base-specifier-list specifies the type of the base class subobjects contained in an object of the derived class type.
[Example
:
struct Base {
  int a, b, c;
};
struct Derived : Base {
  int b;
};
struct Derived2 : Derived {
  int c;
};
Here, an object of class Derived2 will have a subobject of class Derived which in turn will have a subobject of class Base.
end example
]
A base-specifier followed by an ellipsis is a pack expansion ([temp.variadic]).
The order in which the base class subobjects are allocated in the most derived object ([intro.object]) is unspecified.
[Note
:
A derived class and its base class subobjects can be represented by a directed acyclic graph (DAG) where an arrow means “directly derived from”.
An arrow need not have a physical representation in memory.
A DAG of subobjects is often referred to as a “subobject lattice”.
dag Base Base Derived1 Derived1 Derived1->Base Derived2 Derived2 Derived2->Derived1
Figure 2 — Directed acyclic graph
end note
]
[Note
:
Initialization of objects representing base classes can be specified in constructors; see [class.base.init].
end note
]
[Note
:
A base class subobject might have a layout ([basic.stc]) different from the layout of a most derived object of the same type.
A base class subobject might have a polymorphic behavior ([class.cdtor]) different from the polymorphic behavior of a most derived object of the same type.
A base class subobject may be of zero size (Clause [class]); however, two subobjects that have the same class type and that belong to the same most derived object must not be allocated at the same address ([expr.eq]).
end note
]

13.1 Multiple base classes [class.mi]

A class can be derived from any number of base classes.
[Note
:
The use of more than one direct base class is often called multiple inheritance.
end note
]
[Example
:
class A { /* ... */ };
class B { /* ... */ };
class C { /* ... */ };
class D : public A, public B, public C { /* ... */ };
end example
]
[Note
:
The order of derivation is not significant except as specified by the semantics of initialization by constructor ([class.base.init]), cleanup ([class.dtor]), and storage layout ([class.mem], [class.access.spec]).
end note
]
A class shall not be specified as a direct base class of a derived class more than once.
[Note
:
A class can be an indirect base class more than once and can be a direct and an indirect base class.
There are limited things that can be done with such a class.
The non-static data members and member functions of the direct base class cannot be referred to in the scope of the derived class.
However, the static members, enumerations and types can be unambiguously referred to.
end note
]
[Example
:
class X { /* ... */ };
class Y : public X, public X { /* ... */ };             // ill-formed
class L { public: int next;  /* ... */ };
class A : public L { /* ... */ };
class B : public L { /* ... */ };
class C : public A, public B { void f(); /* ... */ };   // well-formed
class D : public A, public L { void f(); /* ... */ };   // well-formed
end example
]
A base class specifier that does not contain the keyword virtual specifies a non-virtual base class.
A base class specifier that contains the keyword virtual specifies a virtual base class.
For each distinct occurrence of a non-virtual base class in the class lattice of the most derived class, the most derived object ([intro.object]) shall contain a corresponding distinct base class subobject of that type.
For each distinct base class that is specified virtual, the most derived object shall contain a single base class subobject of that type.
[Note
:
For an object of class type C, each distinct occurrence of a (non-virtual) base class L in the class lattice of C corresponds one-to-one with a distinct L subobject within the object of type C.
Given the class C defined above, an object of class C will have two subobjects of class L as shown in Figure [fig:nonvirt].
nonvirt L1 L L2 L A A A->L1 B B B->L2 C C C->A C->B
Figure 3 — Non-virtual base
In such lattices, explicit qualification can be used to specify which subobject is meant.
The body of function C​::​f could refer to the member next of each L subobject:
void C::f() { A::next = B::next; }      // well-formed
Without the A​::​ or B​::​ qualifiers, the definition of C​::​f above would be ill-formed because of ambiguity ([class.member.lookup]).
end note
]
[Note
:
In contrast, consider the case with a virtual base class:
class V { /* ... */ };
class A : virtual public V { /* ... */ };
class B : virtual public V { /* ... */ };
class C : public A, public B { /* ... */ };
virt V V A A A->V B B B->V C C C->A C->B
Figure 4 — Virtual base
For an object c of class type C, a single subobject of type V is shared by every base class subobject of c that has a virtual base class of type V.
Given the class C defined above, an object of class C will have one subobject of class V, as shown in Figure [fig:virt].
end note
]
[Note
:
A class can have both virtual and non-virtual base classes of a given type.
class B { /* ... */ };
class X : virtual public B { /* ... */ };
class Y : virtual public B { /* ... */ };
class Z : public B { /* ... */ };
class AA : public X, public Y, public Z { /* ... */ };
For an object of class AA, all virtual occurrences of base class B in the class lattice of AA correspond to a single B subobject within the object of type AA, and every other occurrence of a (non-virtual) base class B in the class lattice of AA corresponds one-to-one with a distinct B subobject within the object of type AA.
Given the class AA defined above, class AA has two subobjects of class B: Z's B and the virtual B shared by X and Y, as shown in Figure [fig:virtnonvirt].
virtnonvirt B1 B B2 B AA AA X X AA->X Y Y AA->Y Z Z AA->Z X->B1 Y->B1 Z->B2
Figure 5 — Virtual and non-virtual base
end note
]

13.2 Member name lookup [class.member.lookup]

Member name lookup determines the meaning of a name (id-expression) in a class scope ([basic.scope.class]).
Name lookup can result in an ambiguity, in which case the program is ill-formed.
For an id-expression, name lookup begins in the class scope of this; for a qualified-id, name lookup begins in the scope of the nested-name-specifier.
Name lookup takes place before access control ([basic.lookup], Clause [class.access]).
The following steps define the result of name lookup for a member name f in a class scope C.
The lookup set for f in C, called , consists of two component sets: the declaration set, a set of members named f; and the subobject set, a set of subobjects where declarations of these members (possibly including using-declarations) were found.
In the declaration set, using-declarations are replaced by the set of designated members that are not hidden or overridden by members of the derived class ([namespace.udecl]), and type declarations (including injected-class-names) are replaced by the types they designate.
is calculated as follows:
If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C that satisfies the requirements of the language construct in which the lookup occurs.
[Note
:
Looking up a name in an elaborated-type-specifier ([basic.lookup.elab]) or base-specifier (Clause [class.derived]), for instance, ignores all non-type declarations, while looking up a name in a nested-name-specifier ([basic.lookup.qual]) ignores function, variable, and enumerator declarations.
As another example, looking up a name in a using-declaration ([namespace.udecl]) includes the declaration of a class or enumeration that would ordinarily be hidden by another declaration of that name in the same scope.
end note
]
If the resulting declaration set is not empty, the subobject set contains C itself, and calculation is complete.
Otherwise (i.e., C does not contain a declaration of f or the resulting declaration set is empty), is initially empty.
If C has base classes, calculate the lookup set for f in each direct base class subobject , and merge each such lookup set in turn into .
The following steps define the result of merging lookup set into the intermediate :
  • If each of the subobject members of is a base class subobject of at least one of the subobject members of , or if is empty, is unchanged and the merge is complete.
    Conversely, if each of the subobject members of is a base class subobject of at least one of the subobject members of , or if is empty, the new is a copy of .
  • Otherwise, if the declaration sets of and differ, the merge is ambiguous: the new is a lookup set with an invalid declaration set and the union of the subobject sets.
    In subsequent merges, an invalid declaration set is considered different from any other.
  • Otherwise, the new is a lookup set with the shared set of declarations and the union of the subobject sets.
The result of name lookup for f in C is the declaration set of .
If it is an invalid set, the program is ill-formed.
[Example
:
struct A { int x; };                    // S(x,A) = { { A​::​x }, { A } }
struct B { float x; };                  // S(x,B) = { { B​::​x }, { B } }
struct C: public A, public B { };       // S(x,C) = { invalid, { A in C, B in C } }
struct D: public virtual C { };         // S(x,D) = S(x,C)
struct E: public virtual C { char x; }; // S(x,E) = { { E​::​x }, { E } }
struct F: public D, public E { };       // S(x,F) = S(x,E)
int main() {
  F f;
  f.x = 0;                              // OK, lookup finds E​::​x
}
is unambiguous because the A and B base class subobjects of D are also base class subobjects of E, so is discarded in the first merge step.
end example
]
If the name of an overloaded function is unambiguously found, overload resolution ([over.match]) also takes place before access control.
Ambiguities can often be resolved by qualifying a name with its class name.
[Example
:
struct A {
  int f();
};
struct B {
  int f();
};
struct C : A, B {
  int f() { return A::f() + B::f(); }
};
end example
]
[Note
:
A static member, a nested type or an enumerator defined in a base class T can unambiguously be found even if an object has more than one base class subobject of type T.
Two base class subobjects share the non-static member subobjects of their common virtual base classes.
end note
]
[Example
:
struct V {
  int v;
};
struct A {
  int a;
  static int   s;
  enum { e };
};
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };

void f(D* pd) {
  pd->v++;          // OK: only one v (virtual)
  pd->s++;          // OK: only one s (static)
  int i = pd->e;    // OK: only one e (enumerator)
  pd->a++;          // error, ambiguous: two as in D
}
end example
]
[Note
:
When virtual base classes are used, a hidden declaration can be reached along a path through the subobject lattice that does not pass through the hiding declaration.
This is not an ambiguity.
The identical use with non-virtual base classes is an ambiguity; in that case there is no unique instance of the name that hides all the others.
end note
]
[Example
:
struct V { int f();  int x; };
struct W { int g();  int y; };
struct B : virtual V, W {
  int f();  int x;
  int g();  int y;
};
struct C : virtual V, W { };

struct D : B, C { void glorp(); };
virt W1 W V V W2 W B B B->W1 B->V C C C->V C->W2 D D D->B D->C
Figure 6 — Name lookup
The names declared in V and the left-hand instance of W are hidden by those in B, but the names declared in the right-hand instance of W are not hidden at all.
void D::glorp() {
  x++;              // OK: B​::​x hides V​::​x
  f();              // OK: B​::​f() hides V​::​f()
  y++;              // error: B​::​y and C's W​::​y
  g();              // error: B​::​g() and C's W​::​g()
}
end example
]
An explicit or implicit conversion from a pointer to or an expression designating an object of a derived class to a pointer or reference to one of its base classes shall unambiguously refer to a unique object representing the base class.
[Example
:
struct V { };
struct A { };
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };

void g() {
  D d;
  B* pb = &d;
  A* pa = &d;       // error, ambiguous: C's A or B's A?
  V* pv = &d;       // OK: only one V subobject
}
end example
]
[Note
:
Even if the result of name lookup is unambiguous, use of a name found in multiple subobjects might still be ambiguous ([conv.mem], [expr.ref], [class.access.base]).
end note
]
[Example
:
struct B1 {
  void f();
  static void f(int);
  int i;
};
struct B2 {
  void f(double);
};
struct I1: B1 { };
struct I2: B1 { };

struct D: I1, I2, B2 {
  using B1::f;
  using B2::f;
  void g() {
    f();                        // Ambiguous conversion of this
    f(0);                       // Unambiguous (static)
    f(0.0);                     // Unambiguous (only one B2)
    int B1::* mpB1 = &D::i;     // Unambiguous
    int D::* mpD = &D::i;       // Ambiguous conversion
  }
};
end example
]

13.3 Virtual functions [class.virtual]

[Note
:
Virtual functions support dynamic binding and object-oriented programming.
end note
]
A class that declares or inherits a virtual function is called a polymorphic class.
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base​::​vf is declared, then Derived​::​vf is also virtual (whether or not it is so declared) and it overrides111 Base​::​vf.
For convenience we say that any virtual function overrides itself.
A virtual member function C​::​vf of a class object S is a final overrider unless the most derived class ([intro.object]) of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.
In a derived class, if a virtual member function of a base class subobject has more than one final overrider the program is ill-formed.
[Example
:
struct A {
  virtual void f();
};
struct B : virtual A {
  virtual void f();
};
struct C : B , virtual A {
  using A::f;
};

void foo() {
  C c;
  c.f();              // calls B​::​f, the final overrider
  c.C::f();           // calls A​::​f because of the using-declaration
}
end example
]
[Example
:
struct A { virtual void f(); };
struct B : A { };
struct C : A { void f(); };
struct D : B, C { };  // OK: A​::​f and C​::​f are the final overriders
                      // for the B and C subobjects, respectively
end example
]
[Note
:
A virtual member function does not have to be visible to be overridden, for example,
struct B {
  virtual void f();
};
struct D : B {
  void f(int);
};
struct D2 : D {
  void f();
};
the function f(int) in class D hides the virtual function f() in its base class B; D​::​f(int) is not a virtual function.
However, f() declared in class D2 has the same name and the same parameter list as B​::​f(), and therefore is a virtual function that overrides the function B​::​f() even though B​::​f() is not visible in class D2.
end note
]
If a virtual function f in some class B is marked with the virt-specifier final and in a class D derived from B a function D​::​f overrides B​::​f, the program is ill-formed.
[Example
:
struct B {
  virtual void f() const final;
};

struct D : B {
  void f() const;     // error: D​::​f attempts to override final B​::​f
};
end example
]
If a virtual function is marked with the virt-specifier override and does not override a member function of a base class, the program is ill-formed.
[Example
:
struct B {
  virtual void f(int);
};

struct D : B {
  virtual void f(long) override;  // error: wrong signature overriding B​::​f
  virtual void f(int) override;   // OK
};
end example
]
Even though destructors are not inherited, a destructor in a derived class overrides a base class destructor declared virtual; see [class.dtor] and [class.free].
The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions.
If a function D​::​f overrides a function B​::​f, the return types of the functions are covariant if they satisfy the following criteria:
  • both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes112
  • the class in the return type of B​::​f is the same class as the class in the return type of D​::​f, or is an unambiguous and accessible direct or indirect base class of the class in the return type of D​::​f
  • both pointers or references have the same cv-qualification and the class type in the return type of D​::​f has the same cv-qualification as or less cv-qualification than the class type in the return type of B​::​f.
If the class type in the covariant return type of D​::​f differs from that of B​::​f, the class type in the return type of D​::​f shall be complete at the point of declaration of D​::​f or shall be the class type D.
When the overriding function is called as the final overrider of the overridden function, its result is converted to the type returned by the (statically chosen) overridden function ([expr.call]).
[Example
:
class B { };
class D : private B { friend class Derived; };
struct Base {
  virtual void vf1();
  virtual void vf2();
  virtual void vf3();
  virtual B*   vf4();
  virtual B*   vf5();
  void f();
};

struct No_good : public Base {
  D*  vf4();        // error: B (base class of D) inaccessible
};

class A;
struct Derived : public Base {
    void vf1();     // virtual and overrides Base​::​vf1()
    void vf2(int);  // not virtual, hides Base​::​vf2()
    char vf3();     // error: invalid difference in return type only
    D*   vf4();     // OK: returns pointer to derived class
    A*   vf5();     // error: returns pointer to incomplete class
    void f();
};

void g() {
  Derived d;
  Base* bp = &d;                // standard conversion:
                                // Derived* to Base*
  bp->vf1();                    // calls Derived​::​vf1()
  bp->vf2();                    // calls Base​::​vf2()
  bp->f();                      // calls Base​::​f() (not virtual)
  B*  p = bp->vf4();            // calls Derived​::​pf() and converts the
                                // result to B*
  Derived*  dp = &d;
  D*  q = dp->vf4();            // calls Derived​::​pf() and does not
                                // convert the result to B*
  dp->vf2();                    // ill-formed: argument mismatch
}
end example
]
[Note
:
The interpretation of the call of a virtual function depends on the type of the object for which it is called (the dynamic type), whereas the interpretation of a call of a non-virtual member function depends only on the type of the pointer or reference denoting that object (the static type) ([expr.call]).
end note
]
[Note
:
The virtual specifier implies membership, so a virtual function cannot be a non-member ([dcl.fct.spec]) function.
Nor can a virtual function be a static member, since a virtual function call relies on a specific object for determining which function to invoke.
A virtual function declared in one class can be declared a friend in another class.
end note
]
A virtual function declared in a class shall be defined, or declared pure ([class.abstract]) in that class, or both; no diagnostic is required ([basic.def.odr]).
[Example
:
Here are some uses of virtual functions with multiple base classes:
struct A {
  virtual void f();
};

struct B1 : A {                 // note non-virtual derivation
  void f();
};

struct B2 : A {
  void f();
};

struct D : B1, B2 {             // D has two separate A subobjects
};

void foo() {
  D   d;
//   A*  ap = &d;                  // would be ill-formed: ambiguous
  B1*  b1p = &d;
  A*   ap = b1p;
  D*   dp = &d;
  ap->f();                      // calls D​::​B1​::​f
  dp->f();                      // ill-formed: ambiguous
}
In class D above there are two occurrences of class A and hence two occurrences of the virtual member function A​::​f.
The final overrider of B1​::​A​::​f is B1​::​f and the final overrider of B2​::​A​::​f is B2​::​f.
end example
]
[Example
:
The following example shows a function that does not have a unique final overrider:
struct A {
  virtual void f();
};

struct VB1 : virtual A {        // note virtual derivation
  void f();
};

struct VB2 : virtual A {
  void f();
};

struct Error : VB1, VB2 {       // ill-formed
};

struct Okay : VB1, VB2 {
  void f();
};
Both VB1​::​f and VB2​::​f override A​::​f but there is no overrider of both of them in class Error.
This example is therefore ill-formed.
Class Okay is well formed, however, because Okay​::​f is a final overrider.
end example
]
[Example
:
The following example uses the well-formed classes from above.
struct VB1a : virtual A {       // does not declare f
};

struct Da : VB1a, VB2 {
};

void foe() {
  VB1a*  vb1ap = new Da;
  vb1ap->f();                   // calls VB2​::​f
}
end example
]
Explicit qualification with the scope operator ([expr.prim]) suppresses the virtual call mechanism.
[Example
:
class B { public: virtual void f(); };
class D : public B { public: void f(); };

void D::f() { /* ... */ B::f(); }
Here, the function call in D​::​f really does call B​::​f and not D​::​f.
end example
]
A function with a deleted definition ([dcl.fct.def]) shall not override a function that does not have a deleted definition.
Likewise, a function that does not have a deleted definition shall not override a function with a deleted definition.
A function with the same name but a different parameter list (Clause [over]) as a virtual function is not necessarily virtual and does not override.
The use of the virtual specifier in the declaration of an overriding function is legal but redundant (has empty semantics).
Access control (Clause [class.access]) is not considered in determining overriding.
Multi-level pointers to classes or references to multi-level pointers to classes are not allowed.

13.4 Abstract classes [class.abstract]

[Note
:
The abstract class mechanism supports the notion of a general concept, such as a shape, of which only more concrete variants, such as circle and square, can actually be used.
An abstract class can also be used to define an interface for which derived classes provide a variety of implementations.
end note
]
An abstract class is a class that can be used only as a base class of some other class; no objects of an abstract class can be created except as subobjects of a class derived from it.
A class is abstract if it has at least one pure virtual function.
[Note
:
Such a function might be inherited: see below.
end note
]
A virtual function is specified pure by using a pure-specifier in the function declaration in the class definition.
A pure virtual function need be defined only if called with, or as if with ([class.dtor]), the qualified-id syntax ([expr.prim]).
[Example
:
class point { /* ... */ };
class shape {                   // abstract class
  point center;
public:
  point where() { return center; }
  void move(point p) { center=p; draw(); }
  virtual void rotate(int) = 0; // pure virtual
  virtual void draw() = 0;      // pure virtual
};
end example
]
[Note
:
A function declaration cannot provide both a pure-specifier and a definition
end note
]
[Example
:
struct C {
  virtual void f() = 0 { };     // ill-formed
};
end example
]
An abstract class shall not be used as a parameter type, as a function return type, or as the type of an explicit conversion.
Pointers and references to an abstract class can be declared.
[Example
:
shape x;                        // error: object of abstract class
shape* p;                       // OK
shape f();                      // error
void g(shape);                  // error
shape& h(shape&);               // OK
end example
]
A class is abstract if it contains or inherits at least one pure virtual function for which the final overrider is pure virtual.
[Example
:
class ab_circle : public shape {
  int radius;
public:
  void rotate(int) { }
  // ab_­circle​::​draw() is a pure virtual
};
Since shape​::​draw() is a pure virtual function ab_­circle​::​draw() is a pure virtual by default.
The alternative declaration,
class circle : public shape {
  int radius;
public:
  void rotate(int) { }
  void draw();                  // a definition is required somewhere
};
would make class circle non-abstract and a definition of circle​::​draw() must be provided.
end example
]
[Note
:
An abstract class can be derived from a class that is not abstract, and a pure virtual function may override a virtual function which is not pure.
end note
]
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call ([class.virtual]) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.

14 Member access control [class.access]

A member of a class can be
  • private; that is, its name can be used only by members and friends of the class in which it is declared.
  • protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see [class.protected]).
  • public; that is, its name can be used anywhere without access restriction.
A member of a class can also access all the names to which the class has access.
A local class of a member function may access the same names that the member function itself may access.113
Members of a class defined with the keyword class are private by default.
Members of a class defined with the keywords struct or union are public by default.
[Example
:
class X {
  int a;            // X​::​a is private by default
};

struct S {
  int a;            // S​::​a is public by default
};
end example
]
Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.
[Note
:
Access control applies to names nominated by friend declarations ([class.friend]) and using-declarations ([namespace.udecl]).
end note
]
In the case of overloaded function names, access control is applied to the function selected by overload resolution.
[Note
:
Because access control applies to names, if access control is applied to a typedef name, only the accessibility of the typedef name itself is considered.
The accessibility of the entity referred to by the typedef is not considered.
For example,
class A {
  class B { };
public:
  typedef B BB;
};

void f() {
  A::BB x;          // OK, typedef name A​::​BB is public
  A::B y;           // access error, A​::​B is private
}
end note
]
It should be noted that it is access to members and base classes that is controlled, not their visibility.
Names of members are still visible, and implicit conversions to base classes are still considered, when those members and base classes are inaccessible.
The interpretation of a given construct is established without regard to access control.
If the interpretation established makes use of inaccessible member names or base classes, the construct is ill-formed.
All access controls in Clause [class.access] affect the ability to access a class member name from the declaration of a particular entity, including parts of the declaration preceding the name of the entity being declared and, if the entity is a class, the definitions of members of the class appearing outside the class's member-specification.
[Note
:
This access also applies to implicit references to constructors, conversion functions, and destructors.
end note
]
[Example
:
class A {
  typedef int I;    // private member
  I f();
  friend I g(I);
  static I x;
  template<int> struct Q;
  template<int> friend struct R;
protected:
    struct B { };
};

A::I A::f() { return 0; }
A::I g(A::I p = A::x);
A::I g(A::I p) { return 0; }
A::I A::x = 0;
template<A::I> struct A::Q { };
template<A::I> struct R { };

struct D: A::B, A { };
Here, all the uses of A​::​I are well-formed because A​::​f, A​::​x, and A​::​Q are members of class A and g and R are friends of class A.
This implies, for example, that access checking on the first use of A​::​I must be deferred until it is determined that this use of A​::​I is as the return type of a member of class A.
Similarly, the use of A​::​B as a base-specifier is well-formed because D is derived from A, so checking of base-specifiers must be deferred until the entire base-specifier-list has been seen.
end example
]
The names in a default argument ([dcl.fct.default]) are bound at the point of declaration, and access is checked at that point rather than at any points of use of the default argument.
Access checking for default arguments in function templates and in member functions of class templates is performed as described in [temp.inst].
The names in a default template-argument ([temp.param]) have their access checked in the context in which they appear rather than at any points of use of the default template-argument.
[Example
:
class B { };
template <class T> class C {
protected:
  typedef T TT;
};

template <class U, class V = typename U::TT>
class D : public U { };

D <C<B> >* d;       // access error, C​::​TT is protected
end example
]
Access permissions are thus transitive and cumulative to nested and local classes.

14.1 Access specifiers [class.access.spec]

Member declarations can be labeled by an access-specifier:
access-specifier : member-specification
An access-specifier specifies the access rules for members following it until the end of the class or until another access-specifier is encountered.
[Example
:
class X {
  int a;            // X​::​a is private by default: class used
public:
  int b;            // X​::​b is public
  int c;            // X​::​c is public
};
end example
]
Any number of access specifiers is allowed and no particular order is required.
[Example
:
struct S {
  int a;            // S​::​a is public by default: struct used
protected:
  int b;            // S​::​b is protected
private:
  int c;            // S​::​c is private
public:
  int d;            // S​::​d is public
};
end example
]
[Note
:
The effect of access control on the order of allocation of data members is described in [class.mem].
end note
]
When a member is redeclared within its class definition, the access specified at its redeclaration shall be the same as at its initial declaration.
[Example
:
struct S {
  class A;
  enum E : int;
private:
  class A { };        // error: cannot change access
  enum E: int { e0 }; // error: cannot change access
};
end example
]
[Note
:
In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared.
The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared.
end note
]
[Example
:
class A { };
class B : private A { };
class C : public B {
  A* p;             // error: injected-class-name A is inaccessible
  ::A* q;           // OK
};
end example
]

14.2 Accessibility of base classes and base class members [class.access.base]

If a class is declared to be a base class (Clause [class.derived]) for another class using the public access specifier, the public members of the base class are accessible as public members of the derived class and protected members of the base class are accessible as protected members of the derived class.
If a class is declared to be a base class for another class using the protected access specifier, the public and protected members of the base class are accessible as protected members of the derived class.
If a class is declared to be a base class for another class using the private access specifier, the public and protected members of the base class are accessible as private members of the derived class114.
In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with the class-key struct and private is assumed when the class is defined with the class-key class.
[Example
:
class B { /* ... */ };
class D1 : private B { /* ... */ };
class D2 : public B { /* ... */ };
class D3 : B { /* ... */ };             // B private by default
struct D4 : public B { /* ... */ };
struct D5 : private B { /* ... */ };
struct D6 : B { /* ... */ };            // B public by default
class D7 : protected B { /* ... */ };
struct D8 : protected B { /* ... */ };
Here B is a public base of D2, D4, and D6, a private base of D1, D3, and D5, and a protected base of D7 and D8.
end example
]
[Note
:
A member of a private base class might be inaccessible as an inherited member name, but accessible directly.
Because of the rules on pointer conversions ([conv.ptr]) and explicit casts ([expr.cast]), a conversion from a pointer to a derived class to a pointer to an inaccessible base class might be ill-formed if an implicit conversion is used, but well-formed if an explicit cast is used.
For example,
class B {
public:
  int mi;                       // non-static member
  static int si;                // static member
};
class D : private B {
};
class DD : public D {
  void f();
};

void DD::f() {
  mi = 3;                       // error: mi is private in D
  si = 3;                       // error: si is private in D
  ::B  b;
  b.mi = 3;                     // OK (b.mi is different from this->mi)
  b.si = 3;                     // OK (b.si is different from this->si)
  ::B::si = 3;                  // OK
  ::B* bp1 = this;              // error: B is a private base class
  ::B* bp2 = (::B*)this;        // OK with cast
  bp2->mi = 3;                  // OK: access through a pointer to B.
}
end note
]
A base class B of N is accessible at R, if
  • an invented public member of B would be a public member of N, or
  • R occurs in a member or friend of class N, and an invented public member of B would be a private or protected member of N, or
  • R occurs in a member or friend of a class P derived from N, and an invented public member of B would be a private or protected member of P, or
  • there exists a class S such that B is a base class of S accessible at R and S is a base class of N accessible at R.
[Example
:
class B {
public:
  int m;
};

class S: private B {
  friend class N;
};

class N: private S {
  void f() {
    B* p = this;    // OK because class S satisfies the fourth condition above: B is a base class of N
                    // accessible in f() because B is an accessible base class of S and S is an accessible
                    // base class of N.
  }
};
end example
]
If a base class is accessible, one can implicitly convert a pointer to a derived class to a pointer to that base class ([conv.ptr], [conv.mem]).
[Note
:
It follows that members and friends of a class X can implicitly convert an X* to a pointer to a private or protected immediate base class of X.
end note
]
The access to a member is affected by the class in which the member is named.
This naming class is the class in which the member name was looked up and found.
[Note
:
This class can be explicit, e.g., when a qualified-id is used, or implicit, e.g., when a class member access operator ([expr.ref]) is used (including cases where an implicit “this->” is added).
If both a class member access operator and a qualified-id are used to name the member (as in p->T​::​m), the class naming the member is the class denoted by the nested-name-specifier of the qualified-id (that is, T).
end note
]
A member m is accessible at the point R when named in class N if
  • m as a member of N is public, or
  • m as a member of N is private, and R occurs in a member or friend of class N, or
  • m as a member of N is protected, and R occurs in a member or friend of class N, or in a member of a class P derived from N, where m as a member of P is public, private, or protected, or
  • there exists a base class B of N that is accessible at R, and m is accessible at R when named in class B.
    [Example
    :
    class B;
    class A {
    private:
      int i;
      friend void f(B*);
    };
    class B : public A { };
    void f(B* p) {
      p->i = 1;         // OK: B* can be implicitly converted to A*, and f has access to i in A
    }
    end example
    ]
If a class member access operator, including an implicit “this->”, is used to access a non-static data member or non-static member function, the reference is ill-formed if the left operand (considered as a pointer in the “.” operator case) cannot be implicitly converted to a pointer to the naming class of the right operand.
[Note
:
This requirement is in addition to the requirement that the member be accessible as named.
end note
]
As specified previously in Clause [class.access], private members of a base class remain inaccessible even to derived classes unless friend declarations within the base class definition are used to grant access explicitly.

14.3 Friends [class.friend]

A friend of a class is a function or class that is given permission to use the private and protected member names from the class.
A class specifies its friends, if any, by way of friend declarations.
Such declarations give special access rights to the friends, but they do not make the nominated friends members of the befriending class.
[Example
:
The following example illustrates the differences between members and friends:
class X {
  int a;
  friend void friend_set(X*, int);
public:
  void member_set(int);
};

void friend_set(X* p, int i) { p->a = i; }
void X::member_set(int i) { a = i; }

void f() {
  X obj;
  friend_set(&obj,10);
  obj.member_set(10);
}
end example
]
Declaring a class to be a friend implies that the names of private and protected members from the class granting friendship can be accessed in the base-specifiers and member declarations of the befriended class.
[Example
:
class A {
  class B { };
  friend class X;
};

struct X : A::B {               // OK: A​::​B accessible to friend
  A::B mx;                      // OK: A​::​B accessible to member of friend
  class Y {
    A::B my;                    // OK: A​::​B accessible to nested member of friend
  };
};
end example
]
[Example
:
class X {
  enum { a=100 };
  friend class Y;
};

class Y {
  int v[X::a];                  // OK, Y is a friend of X
};

class Z {
  int v[X::a];                  // error: X​::​a is private
};
end example
]
A class shall not be defined in a friend declaration.
[Example
:
class A {
  friend class B { };           // error: cannot define class in friend declaration
};
end example
]
A friend declaration that does not declare a function shall have one of the following forms:
friend elaborated-type-specifier ;
friend simple-type-specifier ;
friend typename-specifier ;
[Note
:
A friend declaration may be the declaration in a template-declaration (Clause [temp], [temp.friend]).
end note
]
If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, the friend declaration is ignored.
[Example
:
class C;
typedef C Ct;

class X1 {
  friend C;                     // OK: class C is a friend
};

class X2 {
  friend Ct;                    // OK: class C is a friend
  friend D;                     // error: no type-name D in scope
  friend class D;               // OK: elaborated-type-specifier declares new class
};

template <typename T> class R {
  friend T;
};

R<C> rc;                        // class C is a friend of R<C>
R<int> Ri;                      // OK: "friend int;" is ignored
end example
]
A function first declared in a friend declaration has the linkage of the namespace of which it is a member ([basic.link]).
Otherwise, the function retains its previous linkage ([dcl.stc]).
When a friend declaration refers to an overloaded name or operator, only the function specified by the parameter types becomes a friend.
A member function of a class X can be a friend of a class Y.
[Example
:
class Y {
  friend char* X::foo(int);
  friend X::X(char);            // constructors can be friends
  friend X::~X();               // destructors can be friends
};
end example
]
A function can be defined in a friend declaration of a class if and only if the class is a non-local class ([class.local]), the function name is unqualified, and the function has namespace scope.
[Example
:
class M {
  friend void f() { }           // definition of global f, a friend of M,
                                // not the definition of a member function
};
end example
]
Such a function is implicitly an inline function ([dcl.inline]).
A friend function defined in a class is in the (lexical) scope of the class in which it is defined.
A friend function defined outside the class is not ([basic.lookup.unqual]).
No storage-class-specifier shall appear in the decl-specifier-seq of a friend declaration.
A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.
The meaning of the friend declaration is the same whether the friend declaration appears in the private, protected or public ([class.mem]) portion of the class member-specification.
Friendship is neither inherited nor transitive.
[Example
:
class A {
  friend class B;
  int a;
};

class B {
  friend class C;
};

class C  {
  void f(A* p) {
    p->a++;         // error: C is not a friend of A despite being a friend of a friend
  }
};

class D : public B  {
  void f(A* p) {
    p->a++;         // error: D is not a friend of A despite being derived from a friend
  }
};
end example
]
If a friend declaration appears in a local class ([class.local]) and the name specified is an unqualified name, a prior declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope.
For a friend function declaration, if there is no prior declaration, the program is ill-formed.
For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing non-class scope.
[Example
:
class X;
void a();
void f() {
  class Y;
  extern void b();
  class A {
  friend class X;   // OK, but X is a local class, not ​::​X
  friend class Y;   // OK
  friend class Z;   // OK, introduces local class Z
  friend void a();  // error, ​::​a is not considered
  friend void b();  // OK
  friend void c();  // error
  };
  X* px;            // OK, but ​::​X is found
  Z* pz;            // error, no Z is found
}
end example
]

14.4 Protected member access [class.protected]

An additional access check beyond those described earlier in Clause [class.access] is applied when a non-static data member or non-static member function is a protected member of its naming class ([class.access.base])115 As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C.
If the access is to form a pointer to member ([expr.unary.op]), the nested-name-specifier shall denote C or a class derived from C.
All other accesses involve a (possibly implicit) object expression ([expr.ref]).
In this case, the class of the object expression shall be C or a class derived from C.
[Example
:
class B {
protected:
  int i;
  static int j;
};

class D1 : public B {
};

class D2 : public B {
  friend void fr(B*,D1*,D2*);
  void mem(B*,D1*);
};

void fr(B* pb, D1* p1, D2* p2) {
  pb->i = 1;                    // ill-formed
  p1->i = 2;                    // ill-formed
  p2->i = 3;                    // OK (access through a D2)
  p2->B::i = 4;                 // OK (access through a D2, even though naming class is B)
  int B::* pmi_B = &B::i;       // ill-formed
  int B::* pmi_B2 = &D2::i;     // OK (type of &D2​::​i is int B​::​*)
  B::j = 5;                     // ill-formed (not a friend of naming class B)
  D2::j = 6;                    // OK (because refers to static member)
}

void D2::mem(B* pb, D1* p1) {
  pb->i = 1;                    // ill-formed
  p1->i = 2;                    // ill-formed
  i = 3;                        // OK (access through this)
  B::i = 4;                     // OK (access through this, qualification ignored)
  int B::* pmi_B = &B::i;       // ill-formed
  int B::* pmi_B2 = &D2::i;     // OK
  j = 5;                        // OK (because j refers to static member)
  B::j = 6;                     // OK (because B​::​j refers to static member)
}

void g(B* pb, D1* p1, D2* p2) {
  pb->i = 1;                    // ill-formed
  p1->i = 2;                    // ill-formed
  p2->i = 3;                    // ill-formed
}
end example
]
This additional check does not apply to other members, e.g., static data members or enumerator member constants.

14.5 Access to virtual functions [class.access.virt]

The access rules (Clause [class.access]) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.
[Example
:
class B {
public:
  virtual int f();
};

class D : public B {
private:
  int f();
};

void f() {
  D d;
  B* pb = &d;
  D* pd = &d;

  pb->f();                      // OK: B​::​f() is public, D​::​f() is invoked
  pd->f();                      // error: D​::​f() is private
}
end example
]
Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above).
The access of the member function in the class in which it was defined (D in the example above) is in general not known.

14.6 Multiple access [class.paths]

If a name can be reached by several paths through a multiple inheritance graph, the access is that of the path that gives most access.
[Example
:
class W { public: void f(); };
class A : private virtual W { };
class B : public virtual W { };
class C : public A, public B {
  void f() { W::f(); }          // OK
};
Since W​::​f() is available to C​::​f() along the public path through B, access is allowed.
end example
]

14.7 Nested classes [class.access.nest]

A nested class is a member and as such has the same access rights as any other member.
The members of an enclosing class have no special access to members of a nested class; the usual access rules (Clause [class.access]) shall be obeyed.
[Example
:
class E {
  int x;
  class B { };

  class I {
    B b;                        // OK: E​::​I can access E​::​B
    int y;
    void f(E* p, int i) {
      p->x = i;                 // OK: E​::​I can access E​::​x
    }
  };

  int g(I* p) {
    return p->y;                // error: I​::​y is private
  }
};
end example
]

15 Special member functions [special]

The default constructor ([class.ctor]), copy constructor and copy assignment operator ([class.copy]), move constructor and move assignment operator ([class.copy]), and destructor ([class.dtor]) are special member functions.
[Note
:
The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them.
The implementation will implicitly define them if they are odr-used ([basic.def.odr]).
end note
]
An implicitly-declared special member function is declared at the closing } of the class-specifier.
Programs shall not define implicitly-declared special member functions.
Programs may explicitly refer to implicitly-declared special member functions.
[Example
:
A program may explicitly call, take the address of, or form a pointer to member to an implicitly-declared special member function.
struct A { };                   // implicitly declared A​::​operator=
struct B : A {
  B& operator=(const B &);
};
B& B::operator=(const B& s) {
  this->A::operator=(s);        // well formed
  return *this;
}
end example
]
[Note
:
The special member functions affect the way objects of class type are created, copied, moved, and destroyed, and how values can be converted to values of other types.
Often such special member functions are called implicitly.
end note
]
Special member functions obey the usual access rules (Clause [class.access]).
[Example
:
Declaring a constructor protected ensures that only derived classes and friends can create objects using it.
end example
]
For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract ([class.abstract]), its virtual base classes are called its potentially constructed subobjects.

15.1 Constructors [class.ctor]

Constructors do not have names.
In a declaration of a constructor, the declarator is a function declarator ([dcl.fct]) of the form
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:
The class-name shall not be a typedef-name.
In a constructor declaration, each decl-specifier in the optional decl-specifier-seq shall be friend, inline, explicit, or constexpr.
[Example
:
struct S {
  S();              // declares the constructor
};

S::S() { }          // defines the constructor
end example
]
A constructor is used to initialize objects of its class type.
Because constructors do not have names, they are never found during name lookup; however an explicit type conversion using the functional notation ([expr.type.conv]) will cause a constructor to be called to initialize an object.
[Note
:
For initialization of objects of class type see [class.init].
end note
]
A constructor can be invoked for a const, volatile or const volatile object.
const and volatile semantics ([dcl.type.cv]) are not applied on an object under construction.
They come into effect when the constructor for the most derived object ([intro.object]) ends.
A default constructor for a class X is a constructor of class X for which each parameter that is not a function parameter pack has a default argument (including the case of a constructor with no parameters).
If there is no user-declared constructor for class X, a non-explicit constructor having no parameters is implicitly declared as defaulted ([dcl.fct.def]).
An implicitly-declared default constructor is an inline public member of its class.
A defaulted default constructor for class X is defined as deleted if:
  • X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer,
  • X is a non-union class that has a variant member M with a non-trivial default constructor and no variant member of the anonymous union containing M has a default member initializer,
  • any non-static data member with no default member initializer ([class.mem]) is of reference type,
  • any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-initializer does not have a user-provided default constructor,
  • X is a union and all of its variant members are of const-qualified type (or array thereof),
  • X is a non-union class and all members of any anonymous union member are of const-qualified type (or array thereof),
  • any potentially constructed subobject, except for a non-static data member with a brace-or-equal-initializer, has class type M (or array thereof) and either M has no default constructor or overload resolution ([over.match]) as applied to find M's corresponding constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or
  • any potentially constructed subobject has a type with a destructor that is deleted or inaccessible from the defaulted default constructor.
A default constructor is trivial if it is not user-provided and if:
  • its class has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]), and
  • no non-static data member of its class has a default member initializer ([class.mem]), and
  • all the direct base classes of its class have trivial default constructors, and
  • for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.
Otherwise, the default constructor is non-trivial.
A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) to create an object of its class type ([intro.object]) or when it is explicitly defaulted after its first declaration.
The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer and an empty compound-statement.
If that user-written default constructor would be ill-formed, the program is ill-formed.
If that user-written default constructor would satisfy the requirements of a constexpr constructor ([dcl.constexpr]), the implicitly-defined default constructor is constexpr.
Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members shall have been implicitly defined.
[Note
:
An implicitly-declared default constructor has an exception specification ([except.spec]).
An explicitly-defaulted definition might have an implicit exception specification, see [dcl.fct.def].
end note
]
Default constructors are called implicitly to create class objects of static, thread, or automatic storage duration ([basic.stc.static], [basic.stc.thread], [basic.stc.auto]) defined without an initializer ([dcl.init]), are called to create class objects of dynamic storage duration ([basic.stc.dynamic]) created by a new-expression in which the new-initializer is omitted ([expr.new]), or are called when the explicit type conversion syntax ([expr.type.conv]) is used.
A program is ill-formed if the default constructor for an object is implicitly used and the constructor is not accessible (Clause [class.access]).
[Note
:
[class.base.init] describes the order in which constructors for base classes and non-static data members are called and describes how arguments can be specified for the calls to these constructors.
end note
]
A return statement in the body of a constructor shall not specify a return value.
The address of a constructor shall not be taken.
A functional notation type conversion ([expr.type.conv]) can be used to create new objects of its type.
[Note
:
The syntax looks like an explicit call of the constructor.
end note
]
[Example
:
complex zz = complex(1,2.3);
cprint( complex(7.8,1.2) );
end example
]
An object created in this way is unnamed.
[Note
:
[class.temporary] describes the lifetime of temporary objects.
end note
]
[Note
:
Explicit constructor calls do not yield lvalues, see [basic.lval].
end note
]
[Note
:
Some language constructs have special semantics when used during construction; see [class.base.init] and [class.cdtor].
end note
]
During the construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor's this pointer, the value of the object or subobject thus obtained is unspecified.
[Example
:
struct C;
void no_opt(C*);

struct C {
  int c;
  C() : c(0) { no_opt(this); }
};

const C cobj;

void no_opt(C* cptr) {
  int i = cobj.c * 100;         // value of cobj.c is unspecified
  cptr->c = 1;
  cout << cobj.c * 100          // value of cobj.c is unspecified
       << '\n';
}

extern struct D d;
struct D {
  D(int a) : a(a), b(d.a) {}
  int a, b;
};
D d = D(1);                     // value of d.b is unspecified
end example
]

15.2 Temporary objects [class.temporary]

Temporary objects are created
  • when a prvalue is materialized so that it can be used as a glvalue ([conv.rval]),
  • when needed by the implementation to pass or return an object of trivially-copyable type (see below), and
  • when throwing an exception ([except.throw]).
    [Note
    :
    The lifetime of exception objects is described in [except.throw].
    end note
    ]
Even when the creation of the temporary object is unevaluated (Clause [expr]), all the semantic restrictions shall be respected as if the temporary object had been created and later destroyed.
[Note
:
This includes accessibility (Clause [class.access]) and whether it is deleted, for the constructor selected and for the destructor.
However, in the special case of the operand of a decltype-specifier ([expr.call]), no temporary is introduced, so the foregoing does not apply to such a prvalue.
end note
]
The materialization of a temporary object is generally delayed as long as possible in order to avoid creating unnecessary temporary objects.
[Note
:
Temporary objects are materialized:
end note
]
[Example
:
Consider the following code:
class X {
public:
  X(int);
  X(const X&);
  X& operator=(const X&);
  ~X();
};

class Y {
public:
  Y(int);
  Y(Y&&);
  ~Y();
};

X f(X);
Y g(Y);

void h() {
  X a(1);
  X b = f(X(2));
  Y c = g(Y(3));
  a = f(a);
}
X(2) is constructed in the space used to hold f()'s argument and Y(3) is constructed in the space used to hold g()'s argument.
Likewise, f()'s result is constructed directly in b and g()'s result is constructed directly in c.
On the other hand, the expression a = f(a) requires a temporary for the result of f(a), which is materialized so that the reference parameter of A​::​operator=(const A&) can bind to it.
end example
]
When an object of class type X is passed to or returned from a function, if each copy constructor, move constructor, and destructor of X is either trivial or deleted, and X has at least one non-deleted copy or move constructor, implementations are permitted to create a temporary object to hold the function parameter or result object.
The temporary object is constructed from the function argument or return value, respectively, and the function's parameter or return object is initialized as if by using the non-deleted trivial constructor to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object).
[Note
:
This latitude is granted to allow objects of class type to be passed to or returned from functions in registers.
end note
]
When an implementation introduces a temporary object of a class that has a non-trivial constructor ([class.ctor], [class.copy]), it shall ensure that a constructor is called for the temporary object.
Similarly, the destructor shall be called for a temporary with a non-trivial destructor ([class.dtor]).
Temporary objects are destroyed as the last step in evaluating the full-expression ([intro.execution]) that (lexically) contains the point where they were created.
This is true even if that evaluation ends in throwing an exception.
The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.
There are three contexts in which temporaries are destroyed at a different point than the end of the full-expression.
The first context is when a default constructor is called to initialize an element of an array with no corresponding initializer ([dcl.init]).
The second context is when a copy constructor is called to copy an element of an array while the entire array is copied ([expr.prim.lambda.capture], [class.copy]).
In either case, if the constructor has one or more default arguments, the destruction of every temporary created in a default argument is sequenced before the construction of the next array element, if any.
The third context is when a reference is bound to a temporary.116
The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
  • A temporary object bound to a reference parameter in a function call ([expr.call]) persists until the completion of the full-expression containing the call.
  • The lifetime of a temporary bound to the returned value in a function return statement ([stmt.return]) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
  • A temporary bound to a reference in a new-initializer persists until the completion of the full-expression containing the new-initializer.
    [Example
    :
    struct S { int mi; const std::pair<int,int>& mp; };
    S a { 1, {2,3} };
    S* p = new S{ 1, {2,3} };   // Creates dangling reference
    
    end example
    ]
    [Note
    :
    This may introduce a dangling reference, and implementations are encouraged to issue a warning in such a case.
    end note
    ]
The destruction of a temporary whose lifetime is not extended by being bound to a reference is sequenced before the destruction of every temporary which is constructed earlier in the same full-expression.
If the lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries are destroyed at that point in the reverse order of the completion of their construction.
In addition, the destruction of temporaries bound to references shall take into account the ordering of destruction of objects with static, thread, or automatic storage duration ([basic.stc.static], [basic.stc.thread], [basic.stc.auto]); that is, if obj1 is an object with the same storage duration as the temporary and created before the temporary is created the temporary shall be destroyed before obj1 is destroyed; if obj2 is an object with the same storage duration as the temporary and created after the temporary is created the temporary shall be destroyed after obj2 is destroyed.
[Example
:
struct S {
  S();
  S(int);
  friend S operator+(const S&, const S&);
  ~S();
};
S obj1;
const S& cr = S(16)+S(23);
S obj2;
the expression S(16) + S(23) creates three temporaries: a first temporary T1 to hold the result of the expression S(16), a second temporary T2 to hold the result of the expression S(23), and a third temporary T3 to hold the result of the addition of these two expressions.
The temporary T3 is then bound to the reference cr.
It is unspecified whether T1 or T2 is created first.
On an implementation where T1 is created before T2, T2 shall be destroyed before T1.
The temporaries T1 and T2 are bound to the reference parameters of operator+; these temporaries are destroyed at the end of the full-expression containing the call to operator+.
The temporary T3 bound to the reference cr is destroyed at the end of cr's lifetime, that is, at the end of the program.
In addition, the order in which T3 is destroyed takes into account the destruction order of other objects with static storage duration.
That is, because obj1 is constructed before T3, and T3 is constructed before obj2, obj2 shall be destroyed before T3, and T3 shall be destroyed before obj1.
end example
]
The same rules apply to initialization of an initializer_­list object ([dcl.init.list]) with its underlying temporary array.

15.3 Conversions [class.conv]

Type conversions of class objects can be specified by constructors and by conversion functions.
These conversions are called user-defined conversions and are used for implicit type conversions (Clause [conv]), for initialization ([dcl.init]), and for explicit type conversions ([expr.cast], [expr.static.cast]).
User-defined conversions are applied only where they are unambiguous ([class.member.lookup], [class.conv.fct]).
Conversions obey the access control rules (Clause [class.access]).
Access control is applied after ambiguity resolution ([basic.lookup]).
[Note
:
See [over.match] for a discussion of the use of conversions in function calls as well as examples below.
end note
]
At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.
[Example
:
struct X {
  operator int();
};

struct Y {
  operator X();
};

Y a;
int b = a;          // error, a.operator X().operator int() not tried
int c = X(a);       // OK: a.operator X().operator int()
end example
]
User-defined conversions are used implicitly only if they are unambiguous.
A conversion function in a derived class does not hide a conversion function in a base class unless the two functions convert to the same type.
Function overload resolution ([over.match.best]) selects the best conversion function to perform the conversion.
[Example
:
struct X {
  operator int();
};

struct Y : X {
    operator char();
};

void f(Y& a) {
  if (a) {          // ill-formed: X​::​operator int() or Y​::​operator char()
  }
}
end example
]

15.3.1 Conversion by constructor [class.conv.ctor]

A constructor declared without the function-specifier explicit specifies a conversion from the types of its parameters (if any) to the type of its class.
Such a constructor is called a converting constructor.
[Example
:
struct X {
    X(int);
    X(const char*, int =0);
    X(int, int);
};

void f(X arg) {
  X a = 1;          // a = X(1)
  X b = "Jessie";   // b = X("Jessie",0)
  a = 2;            // a = X(2)
  f(3);             // f(X(3))
  f({1, 2});        // f(X(1,2))
}
end example
]
[Note
:
An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax ([dcl.init]) or where casts ([expr.static.cast], [expr.cast]) are explicitly used; see also [over.match.copy].
A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value-initialization ([dcl.init]).
[Example
:
struct Z {
  explicit Z();
  explicit Z(int);
  explicit Z(int, int);
};

Z a;                            // OK: default-initialization performed
Z b{};                          // OK: direct initialization syntax used
Z c = {};                       // error: copy-list-initialization
Z a1 = 1;                       // error: no implicit conversion
Z a3 = Z(1);                    // OK: direct initialization syntax used
Z a2(1);                        // OK: direct initialization syntax used
Z* p = new Z(1);                // OK: direct initialization syntax used
Z a4 = (Z)1;                    // OK: explicit cast used
Z a5 = static_cast<Z>(1);       // OK: explicit cast used
Z a6 = { 3, 4 };                // error: no implicit conversion
end example
]
end note
]
A non-explicit copy/move constructor ([class.copy]) is a converting constructor.
[Note
:
An implicitly-declared copy/move constructor is not an explicit constructor; it may be called for implicit type conversions.
end note
]

15.3.2 Conversion functions [class.conv.fct]

A member function of a class X having no parameters with a name of the form
Such functions are called conversion functions.
A decl-specifier in the decl-specifier-seq of a conversion function (if any) shall be neither a defining-type-specifier nor static.
The type of the conversion function ([dcl.fct]) is “function taking no parameter returning conversion-type-id.
A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.117
[Example
:
struct X {
  operator int();
  operator auto() -> short;     // error: trailing return type
};

void f(X a) {
  int i = int(a);
  i = (int)a;
  i = a;
}
In all three cases the value assigned will be converted by X​::​operator int().
end example
]
A conversion function may be explicit ([dcl.fct.spec]), in which case it is only considered as a user-defined conversion for direct-initialization ([dcl.init]).
Otherwise, user-defined conversions are not restricted to use in assignments and initializations.
[Example
:
class Y { };
struct Z {
  explicit operator Y() const;
};

void h(Z z) {
  Y y1(z);          // OK: direct-initialization
  Y y2 = z;         // ill-formed: copy-initialization
  Y y3 = (Y)z;      // OK: cast notation
}

void g(X a, X b) {
  int i = (a) ? 1+a : 0;
  int j = (a&&b) ? a+b : i;
  if (a) {
  }
}
end example
]
The conversion-type-id shall not represent a function type nor an array type.
The conversion-type-id in a conversion-function-id is the longest sequence of tokens that could possibly form a conversion-type-id.
[Note
:
This prevents ambiguities between the declarator operator * and its expression counterparts.
[Example
:
&ac.operator int*i; // syntax error:
                    // parsed as: &(ac.operator int *)i
                    // not as: &(ac.operator int)*i
The * is the pointer declarator and not the multiplication operator.
end example
]
This rule also prevents ambiguities for attributes.
[Example
:
operator int [[noreturn]] ();   // error: noreturn attribute applied to a type
end example
]
end note
]
Conversion functions are inherited.
Conversion functions can be virtual.
A conversion function template shall not have a deduced return type ([dcl.spec.auto]).
[Example
:
struct S {
  operator auto() const { return 10; }      // OK
  template<class T>
  operator auto() const { return 1.2; }     // error: conversion function template
};
end example
]
These conversions are considered as standard conversions for the purposes of overload resolution ([over.best.ics], [over.ics.ref]) and therefore initialization ([dcl.init]) and explicit casts ([expr.static.cast]).
A conversion to void does not invoke any conversion function ([expr.static.cast]).
Even though never directly called to perform a conversion, such conversion functions can be declared and can potentially be reached through a call to a virtual conversion function in a base class.

15.4 Destructors [class.dtor]

In a declaration of a destructor, the declarator is a function declarator ([dcl.fct]) of the form
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:
The class-name shall not be a typedef-name.
A destructor shall take no arguments ([dcl.fct]).
Each decl-specifier of the decl-specifier-seq of a destructor declaration (if any) shall be friend, inline, or virtual.
A destructor is used to destroy objects of its class type.
The address of a destructor shall not be taken.
A destructor can be invoked for a const, volatile or const volatile object.
const and volatile semantics ([dcl.type.cv]) are not applied on an object under destruction.
They stop being in effect when the destructor for the most derived object ([intro.object]) starts.
[Note
:
A declaration of a destructor that does not have a noexcept-specifier has the same exception specification as if had been implicitly declared ([except.spec]).
end note
]
If a class has no user-declared destructor, a destructor is implicitly declared as defaulted ([dcl.fct.def]).
An implicitly-declared destructor is an inline public member of its class.
A defaulted destructor for a class X is defined as deleted if:
  • X is a union-like class that has a variant member with a non-trivial destructor,
  • any potentially constructed subobject has class type M (or array thereof) and M has a deleted destructor or a destructor that is inaccessible from the defaulted destructor,
  • or, for a virtual destructor, lookup of the non-array deallocation function results in an ambiguity or in a function that is deleted or inaccessible from the defaulted destructor.
A destructor is trivial if it is not user-provided and if:
  • the destructor is not virtual,
  • all of the direct base classes of its class have trivial destructors, and
  • for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
Otherwise, the destructor is non-trivial.
A destructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) or when it is explicitly defaulted after its first declaration.
Before the defaulted destructor for a class is implicitly defined, all the non-user-provided destructors for its base classes and its non-static data members shall have been implicitly defined.
After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X's direct non-variant non-static data members, the destructors for X's non-virtual direct base classes and, if X is the type of the most derived class ([class.base.init]), its destructor calls the destructors for X's virtual base classes.
All destructors are called as if they were referenced with a qualified name, that is, ignoring any possible virtual overriding destructors in more derived classes.
Bases and members are destroyed in the reverse order of the completion of their constructor (see [class.base.init]).
A return statement ([stmt.return]) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for the members and bases are called.
Destructors for elements of an array are called in reverse order of their construction (see [class.init]).
A destructor can be declared virtual ([class.virtual]) or pure virtual ([class.abstract]); if any objects of that class or any derived class are created in the program, the destructor shall be defined.
If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.
[Note
:
Some language constructs have special semantics when used during destruction; see [class.cdtor].
end note
]
A destructor is invoked implicitly
In each case, the context of the invocation is the context of the construction of the object.
A destructor is also invoked implicitly through use of a delete-expression for a constructed object allocated by a new-expression; the context of the invocation is the delete-expression.
[Note
:
An array of class type contains several subobjects for each of which the destructor is invoked.
end note
]
A destructor can also be invoked explicitly.
A destructor is potentially invoked if it is invoked or as specified in [expr.new], [class.base.init], and [except.throw].
A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation.
At the point of definition of a virtual destructor (including an implicit definition ([class.copy])), the non-array deallocation function is determined as if for the expression delete this appearing in a non-virtual destructor of the destructor's class (see [expr.delete]).
If the lookup fails or if the deallocation function has a deleted definition ([dcl.fct.def]), the program is ill-formed.
[Note
:
This assures that a deallocation function corresponding to the dynamic type of an object is available for the delete-expression ([class.free]).
end note
]
In an explicit destructor call, the destructor is specified by a ~ followed by a type-name or decltype-specifier that denotes the destructor's class type.
The invocation of a destructor is subject to the usual rules for member functions ([class.mfct]); that is, if the object is not of the destructor's class type and not of a class derived from the destructor's class type (including when the destructor is invoked via a null pointer value), the program has undefined behavior.
[Note
:
Invoking delete on a null pointer does not call the destructor; see [expr.delete].
end note
]
[Example
:
struct B {
  virtual ~B() { }
};
struct D : B {
  ~D() { }
};

D D_object;
typedef B B_alias;
B* B_ptr = &D_object;

void f() {
  D_object.B::~B();             // calls B's destructor
  B_ptr->~B();                  // calls D's destructor
  B_ptr->~B_alias();            // calls D's destructor
  B_ptr->B_alias::~B();         // calls B's destructor
  B_ptr->B_alias::~B_alias();   // calls B's destructor
}
end example
]
[Note
:
An explicit destructor call must always be written using a member access operator ([expr.ref]) or a qualified-id ([expr.prim]); in particular, the unary-expression ~X() in a member function is not an explicit destructor call ([expr.unary.op]).
end note
]
[Note
:
Explicit calls of destructors are rarely needed.
One use of such calls is for objects placed at specific addresses using a placement new-expression.
Such use of explicit placement and destruction of objects can be necessary to cope with dedicated hardware resources and for writing memory management facilities.
For example,
void* operator new(std::size_t, void* p) { return p; }
struct X {
  X(int);
  ~X();
};
void f(X* p);

void g() {                      // rare, specialized use:
  char* buf = new char[sizeof(X)];
  X* p = new(buf) X(222);       // use buf[] and initialize
  f(p);
  p->X::~X();                   // cleanup
}
end note
]
Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended ([basic.life]).
[Example
:
If the destructor for an automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily invoke implicit destruction of the object, the behavior is undefined.
end example
]
[Note
:
The notation for explicit call of a destructor can be used for any scalar type name ([expr.pseudo]).
Allowing this makes it possible to write code without having to know if a destructor exists for a given type.
For example:
typedef int I;
I* p;
p->I::~I();
end note
]

15.5 Free store [class.free]

Any allocation function for a class T is a static member (even if not explicitly declared static).
[Example
:
class Arena;
struct B {
  void* operator new(std::size_t, Arena*);
};
struct D1 : B {
};

Arena*  ap;
void foo(int i) {
  new (ap) D1;      // calls B​::​operator new(std​::​size_­t, Arena*)
  new D1[i];        // calls ​::​operator new[](std​::​size_­t)
  new D1;           // ill-formed: ​::​operator new(std​::​size_­t) hidden
}
end example
]
When an object is deleted with a delete-expression, a deallocation function (operator delete() for non-array objects or operator delete[]() for arrays) is (implicitly) called to reclaim the storage occupied by the object ([basic.stc.dynamic.deallocation]).
Class-specific deallocation function lookup is a part of general deallocation function lookup ([expr.delete]) and occurs as follows.
If the delete-expression is used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one selected at the point of definition of the dynamic type's virtual destructor ([class.dtor]).118
Otherwise, if the delete-expression is used to deallocate an object of class T or array thereof, the static and dynamic types of the object shall be identical and the deallocation function's name is looked up in the scope of T.
If this lookup fails to find the name, general deallocation function lookup ([expr.delete]) continues.
If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a placement deallocation function, the program is ill-formed.
Any deallocation function for a class X is a static member (even if not explicitly declared static).
[Example
:
class X {
  void operator delete(void*);
  void operator delete[](void*, std::size_t);
};

class Y {
  void operator delete(void*, std::size_t);
  void operator delete[](void*);
};
end example
]
Since member allocation and deallocation functions are static they cannot be virtual.
[Note
:
However, when the cast-expression of a delete-expression refers to an object of class type, because the deallocation function actually called is looked up in the scope of the class that is the dynamic type of the object, if the destructor is virtual, the effect is the same.
For example,
struct B {
  virtual ~B();
  void operator delete(void*, std::size_t);
};

struct D : B {
  void operator delete(void*);
};

void f() {
  B* bp = new D;
  delete bp;        // 1: uses D​::​operator delete(void*)
}
Here, storage for the non-array object of class D is deallocated by D​::​operator delete(), due to the virtual destructor.
end note
]
[Note
:
Virtual destructors have no effect on the deallocation function actually called when the cast-expression of a delete-expression refers to an array of objects of class type.
For example,
struct B {
  virtual ~B();
  void operator delete[](void*, std::size_t);
};

struct D : B {
  void operator delete[](void*, std::size_t);
};

void f(int i) {
  D* dp = new D[i];
  delete [] dp;     // uses D​::​operator delete[](void*, std​::​size_­t)
  B* bp = new D[i];
  delete[] bp;      // undefined behavior
}
end note
]
Access to the deallocation function is checked statically.
Hence, even though a different one might actually be executed, the statically visible deallocation function is required to be accessible.
[Example
:
For the call on line “// 1” above, if B​::​operator delete() had been private, the delete expression would have been ill-formed.
end example
]
[Note
:
If a deallocation function has no explicit noexcept-specifier, it has a non-throwing exception specification ([except.spec]).
end note
]
A similar provision is not needed for the array version of operator delete because [expr.delete] requires that in this situation, the static type of the object to be deleted be the same as its dynamic type.

15.6 Initialization [class.init]

When no initializer is specified for an object of (possibly cv-qualified) class type (or array thereof), or the initializer has the form (), the object is initialized as specified in [dcl.init].
An object of class type (or array thereof) can be explicitly initialized; see [class.expl.init] and [class.base.init].
When an array of class objects is initialized (either explicitly or implicitly) and the elements are initialized by constructor, the constructor shall be called for each element of the array, following the subscript order; see [dcl.array].
[Note
:
Destructors for the array elements are called in reverse order of their construction.
end note
]

15.6.1 Explicit initialization [class.expl.init]

An object of class type can be initialized with a parenthesized expression-list, where the expression-list is construed as an argument list for a constructor that is called to initialize the object.
Alternatively, a single assignment-expression can be specified as an initializer using the = form of initialization.
Either direct-initialization semantics or copy-initialization semantics apply; see [dcl.init].
[Example
:
struct complex {
  complex();
  complex(double);
  complex(double,double);
};

complex sqrt(complex,complex);

complex a(1);                   // initialize by a call of complex(double)
complex b = a;                  // initialize by a copy of a
complex c = complex(1,2);       // construct complex(1,2) using complex(double,double),
                                // copy/move it into c
complex d = sqrt(b,c);          // call sqrt(complex,complex) and copy/move the result into d
complex e;                      // initialize by a call of complex()
complex f = 3;                  // construct complex(3) using complex(double), copy/move it into f
complex g = { 1, 2 };           // initialize by a call of complex(double, double)
end example
]
[Note
:
Overloading of the assignment operator ([over.ass]) has no effect on initialization.
end note
]
An object of class type can also be initialized by a braced-init-list.
List-initialization semantics apply; see [dcl.init] and [dcl.init.list].
[Example
:
complex v[6] = { 1, complex(1,2), complex(), 2 };
Here, complex​::​complex(double) is called for the initialization of v[0] and v[3], complex​::​complex(​double, double) is called for the initialization of v[1], complex​::​complex() is called for the initialization v[2], v[4], and v[5].
For another example,
struct X {
  int i;
  float f;
  complex c;
} x = { 99, 88.8, 77.7 };
Here, x.i is initialized with 99, x.f is initialized with 88.
8, and complex​::​complex(double) is called for the initialization of x.c.
end example
]
[Note
:
Braces can be elided in the initializer-list for any aggregate, even if the aggregate has members of a class type with user-defined type conversions; see [dcl.init.aggr].
end note
]
[Note
:
If T is a class type with no default constructor, any declaration of an object of type T (or array thereof) is ill-formed if no initializer is explicitly specified (see [class.init] and [dcl.init]).
end note
]
[Note
:
The order in which objects with static or thread storage duration are initialized is described in [basic.start.dynamic] and [stmt.dcl].
end note
]

15.6.2 Initializing bases and members [class.base.init]

In the definition of a constructor for a class, initializers for direct and virtual base class subobjects and non-static data members can be specified by a ctor-initializer, which has the form
In a mem-initializer-id an initial unqualified identifier is looked up in the scope of the constructor's class and, if not found in that scope, it is looked up in the scope containing the constructor's definition.
[Note
:
If the constructor's class contains a member with the same name as a direct or virtual base class of the class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to the class member.
A mem-initializer-id for the hidden base class may be specified using a qualified name.
end note
]
Unless the mem-initializer-id names the constructor's class, a non-static data member of the constructor's class, or a direct or virtual base of that class, the mem-initializer is ill-formed.
A mem-initializer-list can initialize a base class using any class-or-decltype that denotes that base class type.
[Example
:
struct A { A(); };
typedef A global_A;
struct B { };
struct C: public A, public B { C(); };
C::C(): global_A() { }          // mem-initializer for base A
end example
]
If a mem-initializer-id is ambiguous because it designates both a direct non-virtual base class and an inherited virtual base class, the mem-initializer is ill-formed.
[Example
:
struct A { A(); };
struct B: public virtual A { };
struct C: public A, public B { C(); };
C::C(): A() { }                 // ill-formed: which A?
end example
]
A ctor-initializer may initialize a variant member of the constructor's class.
If a ctor-initializer specifies more than one mem-initializer for the same member or for the same base class, the ctor-initializer is ill-formed.
A mem-initializer-list can delegate to another constructor of the constructor's class using any class-or-decltype that denotes the constructor's class itself.
If a mem-initializer-id designates the constructor's class, it shall be the only mem-initializer; the constructor is a delegating constructor, and the constructor selected by the mem-initializer is the target constructor.
The target constructor is selected by overload resolution.
Once the target constructor returns, the body of the delegating constructor is executed.
If a constructor delegates to itself directly or indirectly, the program is ill-formed, no diagnostic required.
[Example
:
struct C {
  C( int ) { }                  // #1: non-delegating constructor
  C(): C(42) { }                // #2: delegates to #1
  C( char c ) : C(42.0) { }     // #3: ill-formed due to recursion with #4
  C( double d ) : C('a') { }    // #4: ill-formed due to recursion with #3
};
end example
]
The expression-list or braced-init-list in a mem-initializer is used to initialize the designated subobject (or, in the case of a delegating constructor, the complete class object) according to the initialization rules of [dcl.init] for direct-initialization.
[Example
:
struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
  D(int);
  B1 b;
  const int c;
};

D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ }
D d(10);
end example
]
[Note
:
The initialization performed by each mem-initializer constitutes a full-expression ([intro.execution]).
Any expression in a mem-initializer is evaluated as part of the full-expression that performs the initialization.
end note
]
A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of a constructor of any class that is not the most derived class.
A temporary expression bound to a reference member in a mem-initializer is ill-formed.
[Example
:
struct A {
  A() : v(42) { }   // error
  const int& v;
};
end example
]
In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
  • if the entity is a non-static data member that has a default member initializer ([class.mem]) and either
    the entity is initialized from its default member initializer as specified in [dcl.init];
  • otherwise, if the entity is an anonymous union or a variant member ([class.union.anon]), no initialization is performed;
  • otherwise, the entity is default-initialized ([dcl.init]).
[Note
:
An abstract class ([class.abstract]) is never a most derived class, thus its constructors never initialize virtual base classes, therefore the corresponding mem-initializers may be omitted.
end note
]
An attempt to initialize more than one non-static data member of a union renders the program ill-formed.
[Note
:
After the call to a constructor for class X for an object with automatic or dynamic storage duration has completed, if the constructor was not invoked as part of value-initialization and a member of X is neither initialized nor given a value during execution of the compound-statement of the body of the constructor, the member has an indeterminate value.
end note
]
[Example
:
struct A {
  A();
};

struct B {
  B(int);
};

struct C {
  C() { }               // initializes members as follows:
  A a;                  // OK: calls A​::​A()
  const B b;            // error: B has no default constructor
  int i;                // OK: i has indeterminate value
  int j = 5;            // OK: j has the value 5
};
end example
]
If a given non-static data member has both a default member initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member's default member initializer is ignored.
[Example
:
Given
struct A {
  int i = /* some integer expression with side effects */ ;
  A(int arg) : i(arg) { }
  // ...
};
the A(int) constructor will simply initialize i to the value of arg, and the side effects in i's default member initializer will not take place.
end example
]
A temporary expression bound to a reference member from a default member initializer is ill-formed.
[Example
:
struct A {
  A() = default;        // OK
  A(int v) : v(v) { }   // OK
  const int& v = 42;    // OK
};
A a1;                   // error: ill-formed binding of temporary to reference
A a2(1);                // OK, unfortunately
end example
]
In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked ([class.dtor]).
[Note
:
This provision ensures that destructors can be called for fully-constructed subobjects in case an exception is thrown ([except.ctor]).
end note
]
In a non-delegating constructor, initialization proceeds in the following order:
  • First, and only for the constructor of the most derived class ([intro.object]), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
  • Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
  • Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
  • Finally, the compound-statement of the constructor body is executed.
[Note
:
The declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization.
end note
]
[Example
:
struct V {
  V();
  V(int);
};

struct A : virtual V {
  A();
  A(int);
};

struct B : virtual V {
  B();
  B(int);
};

struct C : A, B, virtual V {
  C();
  C(int);
};

A::A(int i) : V(i) { /* ... */ }
B::B(int i) { /* ... */ }
C::C(int i) { /* ... */ }

V v(1);             // use V(int)
A a(2);             // use V(int)
B b(3);             // use V()
C c(4);             // use V()
end example
]
Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified.
[Example
:
class X {
  int a;
  int b;
  int i;
  int j;
public:
  const int& r;
  X(int i): r(a), b(i), i(i), j(this->i) { }
};
initializes X​::​r to refer to X​::​a, initializes X​::​b with the value of the constructor parameter i, initializes X​::​i with the value of the constructor parameter i, and initializes X​::​j with the value of X​::​i; this takes place each time an object of class X is created.
end example
]
[Note
:
Because the mem-initializer are evaluated in the scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer to refer to the object being initialized.
end note
]
Member functions (including virtual member functions, [class.virtual]) can be called for an object under construction.
Similarly, an object under construction can be the operand of the typeid operator ([expr.typeid]) or of a dynamic_­cast ([expr.dynamic.cast]).
However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the program has undefined behavior.
[Example
:
class A {
public:
  A(int);
};

class B : public A {
  int j;
public:
  int f();
  B() : A(f()),     // undefined: calls member function but base A not yet initialized
  j(f()) { }        // well-defined: bases are all initialized
};

class C {
public:
  C(int);
};

class D : public B, C {
  int i;
public:
  D() : C(f()),     // undefined: calls member function but base C not yet initialized
  i(f()) { }        // well-defined: bases are all initialized
};
end example
]
[Note
:
[class.cdtor] describes the result of virtual function calls, typeid and dynamic_­casts during construction for the well-defined cases; that is, describes the polymorphic behavior of an object under construction.
end note
]
A mem-initializer followed by an ellipsis is a pack expansion ([temp.variadic]) that initializes the base classes specified by a pack expansion in the base-specifier-list for the class.
[Example
:
template<class... Mixins>
class X : public Mixins... {
public:
  X(const Mixins&... mixins) : Mixins(mixins)... { }
};
end example
]

15.6.3 Initialization by inherited constructor [class.inhctor.init]

When a constructor for type B is invoked to initialize an object of a different type D (that is, when the constructor was inherited ([namespace.udecl])), initialization proceeds as if a defaulted default constructor were used to initialize the D object and each base class subobject from which the constructor was inherited, except that the B subobject is initialized by the invocation of the inherited constructor.
The complete initialization is considered to be a single function call; in particular, the initialization of the inherited constructor's parameters is sequenced before the initialization of any part of the D object.
[Example
:
struct B1 {
  B1(int, ...) { }
};

struct B2 {
  B2(double) { }
};

int get();

struct D1 : B1 {
  using B1::B1;     // inherits B1(int, ...)
  int x;
  int y = get();
};

void test() {
  D1 d(2, 3, 4);    // OK: B1 is initialized by calling B1(2, 3, 4),
                    // then d.x is default-initialized (no initialization is performed),
                    // then d.y is initialized by calling get()
  D1 e;             // error: D1 has a deleted default constructor
}

struct D2 : B2 {
  using B2::B2;
  B1 b;
};

D2 f(1.0);          // error: B1 has a deleted default constructor

struct W { W(int); };
struct X : virtual W { using W::W; X() = delete; };
struct Y : X { using X::X; };
struct Z : Y, virtual W { using Y::Y; };
Z z(0);             // OK: initialization of Y does not invoke default constructor of X

template<class T> struct Log : T {
  using T::T;       // inherits all constructors from class T
  ~Log() { std::clog << "Destroying wrapper" << std::endl; }
};
Class template Log wraps any class and forwards all of its constructors, while writing a message to the standard log whenever an object of class Log is destroyed.
end example
]
If the constructor was inherited from multiple base class subobjects of type B, the program is ill-formed.
[Example
:
struct A { A(int); };
struct B : A { using A::A; };

struct C1 : B { using B::B; };
struct C2 : B { using B::B; };

struct D1 : C1, C2 {
  using C1::C1;
  using C2::C2;
};

struct V1 : virtual B { using B::B; };
struct V2 : virtual B { using B::B; };

struct D2 : V1, V2 {
  using V1::V1;
  using V2::V2;
};

D1 d1(0);           // ill-formed: ambiguous
D2 d2(0);           // OK: initializes virtual B base class, which initializes the A base class
                    // then initializes the V1 and V2 base classes as if by a defaulted default constructor

struct M { M(); M(int); };
struct N : M { using M::M; };
struct O : M {};
struct P : N, O { using N::N; using O::O; };
P p(0);             // OK: use M(0) to initialize N's base class,
                    // use M() to initialize O's base class
end example
]
When an object is initialized by an inherited constructor, initialization of the object is complete when the initialization of all subobjects is complete.

15.7 Construction and destruction [class.cdtor]

For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior.
For an object with a non-trivial destructor, referring to any non-static member or base class of the object after the destructor finishes execution results in undefined behavior.
[Example
:
struct X { int i; };
struct Y : X { Y(); };                  // non-trivial
struct A { int a; };
struct B : public A { int j; Y y; };    // non-trivial

extern B bobj;
B* pb = &bobj;                          // OK
int* p1 = &bobj.a;                      // undefined, refers to base class member
int* p2 = &bobj.y.i;                    // undefined, refers to member's member

A* pa = &bobj;                          // undefined, upcast to a base class type
B bobj;                                 // definition of bobj

extern X xobj;
int* p3 = &xobj.i;                      // OK, X is a trivial class
X xobj;
For another example,
struct W { int j; };
struct X : public virtual W { };
struct Y {
  int* p;
  X x;
  Y() : p(&x.j) {   // undefined, x is not yet constructed
    }
};
end example
]
To explicitly or implicitly convert a pointer (a glvalue) referring to an object of class X to a pointer (reference) to a direct or indirect base class B of X, the construction of X and the construction of all of its direct or indirect bases that directly or indirectly derive from B shall have started and the destruction of these classes shall not have completed, otherwise the conversion results in undefined behavior.
To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member value) results in undefined behavior.
[Example
:
struct A { };
struct B : virtual A { };
struct C : B { };
struct D : virtual A { D(A*); };
struct X { X(A*); };

struct E : C, D, X {
  E() : D(this),    // undefined: upcast from E* to A* might use path E*  D*  A*
                    // but D is not constructed

                    // “D((C*)this)” would be defined: E*  C* is defined because E() has started,
                    // and C*  A* is defined because C is fully constructed

  X(this) {}        // defined: upon construction of X, C/B/D/A sublattice is fully constructed
};
end example
]
Member functions, including virtual functions ([class.virtual]), can be called during construction or destruction ([class.base.init]).
When a virtual function is called directly or indirectly from a constructor or from a destructor, including during the construction or destruction of the class's non-static data members, and the object to which the call applies is the object (call it x) under construction or destruction, the function called is the final overrider in the constructor's or destructor's class and not one overriding it in a more-derived class.
If the virtual function call uses an explicit class member access ([expr.ref]) and the object expression refers to the complete object of x or one of that object's base class subobjects but not x or one of its base class subobjects, the behavior is undefined.
[Example
:
struct V {
  virtual void f();
  virtual void g();
};

struct A : virtual V {
  virtual void f();
};

struct B : virtual V {
  virtual void g();
  B(V*, A*);
};

struct D : A, B {
  virtual void f();
  virtual void g();
  D() : B((A*)this, this) { }
};

B::B(V* v, A* a) {
  f();              // calls V​::​f, not A​::​f
  g();              // calls B​::​g, not D​::​g
  v->g();           // v is base of B, the call is well-defined, calls B​::​g
  a->f();           // undefined behavior, a's type not a base of B
}
end example
]
The typeid operator ([expr.typeid]) can be used during construction or destruction ([class.base.init]).
When typeid is used in a constructor (including the mem-initializer or default member initializer ([class.mem]) for a non-static data member) or in a destructor, or used in a function called (directly or indirectly) from a constructor or destructor, if the operand of typeid refers to the object under construction or destruction, typeid yields the std​::​type_­info object representing the constructor or destructor's class.
If the operand of typeid refers to the object under construction or destruction and the static type of the operand is neither the constructor or destructor's class nor one of its bases, the behavior is undefined.
dynamic_­casts ([expr.dynamic.cast]) can be used during construction or destruction ([class.base.init]).
When a dynamic_­cast is used in a constructor (including the mem-initializer or default member initializer for a non-static data member) or in a destructor, or used in a function called (directly or indirectly) from a constructor or destructor, if the operand of the dynamic_­cast refers to the object under construction or destruction, this object is considered to be a most derived object that has the type of the constructor or destructor's class.
If the operand of the dynamic_­cast refers to the object under construction or destruction and the static type of the operand is not a pointer to or object of the constructor or destructor's own class or one of its bases, the dynamic_­cast results in undefined behavior.
[Example
:
struct V {
  virtual void f();
};

struct A : virtual V { };

struct B : virtual V {
  B(V*, A*);
};

struct D : A, B {
  D() : B((A*)this, this) { }
};

B::B(V* v, A* a) {
  typeid(*this);                // type_­info for B
  typeid(*v);                   // well-defined: *v has type V, a base of B yields type_­info for B
  typeid(*a);                   // undefined behavior: type A not a base of B
  dynamic_cast<B*>(v);          // well-defined: v of type V*, V base of B results in B*
  dynamic_cast<B*>(a);          // undefined behavior, a has type A*, A not a base of B
}
end example
]

15.8 Copying and moving class objects [class.copy]

A class object can be copied or moved in two ways: by initialization ([class.ctor], [dcl.init]), including for function argument passing ([expr.call]) and for function value return ([stmt.return]); and by assignment ([expr.ass]).
Conceptually, these two operations are implemented by a copy/move constructor ([class.ctor]) and copy/move assignment operator ([over.ass]).
A program is ill-formed if the copy/move constructor or the copy/move assignment operator for an object is implicitly odr-used and the special member function is not accessible (Clause [class.access]).
[Note
:
Copying/moving one object into another using the copy/move constructor or the copy/move assignment operator does not change the layout or size of either object.
end note
]

15.8.1 Copy/move constructors [class.copy.ctor]

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments ([dcl.fct.default]).
[Example
:
X​::​X(const X&) and X​::​X(X&,int=1) are copy constructors.
struct X {
  X(int);
  X(const X&, int = 1);
};
X a(1);             // calls X(int);
X b(a, 0);          // calls X(const X&, int);
X c = b;            // calls X(const X&, int);
end example
]
A non-template constructor for class X is a move constructor if its first parameter is of type X&&, const X&&, volatile X&&, or const volatile X&&, and either there are no other parameters or else all other parameters have default arguments ([dcl.fct.default]).
[Example
:
Y​::​Y(Y&&) is a move constructor.
struct Y {
  Y(const Y&);
  Y(Y&&);
};
extern Y f(int);
Y d(f(1));          // calls Y(Y&&)
Y e = d;            // calls Y(const Y&)
end example
]
[Note
:
All forms of copy/move constructor may be declared for a class.
[Example
:
struct X {
  X(const X&);
  X(X&);            // OK
  X(X&&);
  X(const X&&);     // OK, but possibly not sensible
};
end example
]
end note
]
[Note
:
If a class X only has a copy constructor with a parameter of type X&, an initializer of type const X or volatile X cannot initialize an object of type (possibly cv-qualified) X.
[Example
:
struct X {
  X();              // default constructor
  X(X&);            // copy constructor with a non-const parameter
};
const X cx;
X x = cx;           // error: X​::​X(X&) cannot copy cx into x
end example
]
end note
]
A declaration of a constructor for a class X is ill-formed if its first parameter is of type (optionally cv-qualified) X and either there are no other parameters or else all other parameters have default arguments.
A member function template is never instantiated to produce such a constructor signature.
[Example
:
struct S {
  template<typename T> S(T);
  S();
};

S g;

void h() {
  S a(g);           // does not instantiate the member template to produce S​::​S<S>(S);
                    // uses the implicitly declared copy constructor
}
end example
]
If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted ([dcl.fct.def]).
The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.
The implicitly-declared copy constructor for a class X will have the form
X::X(const X&)
if each potentially constructed subobject of a class type M (or array thereof) has a copy constructor whose first parameter is of type const M& or const volatile M&.119
Otherwise, the implicitly-declared copy constructor will have the form
X::X(X&)
If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if
  • X does not have a user-declared copy constructor,
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared move assignment operator, and
  • X does not have a user-declared destructor.
[Note
:
When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor.
end note
]
The implicitly-declared move constructor for class X will have the form
X::X(X&&)
An implicitly-declared copy/move constructor is an inline public member of its class.
A defaulted copy/​move constructor for a class X is defined as deleted ([dcl.fct.def.delete]) if X has:
  • a variant member with a non-trivial corresponding constructor and X is a union-like class,
  • a potentially constructed subobject type M (or array thereof) that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,
  • any potentially constructed subobject of a type with a destructor that is deleted or inaccessible from the defaulted constructor, or,
  • for the copy constructor, a non-static data member of rvalue reference type.
A defaulted move constructor that is defined as deleted is ignored by overload resolution ([over.match], [over.over]).
[Note
:
A deleted move constructor would otherwise interfere with initialization from an rvalue which can use the copy constructor instead.
end note
]
A copy/move constructor for class X is trivial if it is not user-provided and if:
  • class X has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]), and
  • the constructor selected to copy/move each direct base class subobject is trivial, and
  • for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;
otherwise the copy/move constructor is non-trivial.
A copy/move constructor that is defaulted and not defined as deleted is implicitly defined if it is odr-used ([basic.def.odr]) or when it is explicitly defaulted after its first declaration.
[Note
:
The copy/move constructor is implicitly defined even if the implementation elided its odr-use ([basic.def.odr], [class.temporary]).
end note
]
If the implicitly-defined constructor would satisfy the requirements of a constexpr constructor ([dcl.constexpr]), the implicitly-defined constructor is constexpr.
Before the defaulted copy/move constructor for a class is implicitly defined, all non-user-provided copy/move constructors for its potentially constructed subobjects shall have been implicitly defined.
[Note
:
An implicitly-declared copy/move constructor has an implied exception specification ([except.spec]).
end note
]
The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members.
[Note
:
Default member initializers of non-static data members are ignored.
See also the example in [class.base.init].
end note
]
The order of initialization is the same as the order of initialization of bases and members in a user-defined constructor (see [class.base.init]).
Let x be either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter.
Each base or non-static data member is copied/moved in the manner appropriate to its type:
  • if the member is an array, each element is direct-initialized with the corresponding subobject of x;
  • if a member m has rvalue reference type T&&, it is direct-initialized with static_­cast<T&&>(x.m);
  • otherwise, the base or member is direct-initialized with the corresponding base or member of x.
Virtual base class subobjects shall be initialized only once by the implicitly-defined copy/move constructor (see [class.base.init]).
The implicitly-defined copy/move constructor for a union X copies the object representation ([basic.types]) of X.
This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue; see [diff.special].

15.8.2 Copy/move assignment operator [class.copy.assign]

A user-declared copy assignment operator X​::​operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.120
[Note
:
An overloaded assignment operator must be declared to have only one parameter; see [over.ass].
end note
]
[Note
:
More than one form of copy assignment operator may be declared for a class.
end note
]
[Note
:
If a class X only has a copy assignment operator with a parameter of type X&, an expression of type const X cannot be assigned to an object of type X.
[Example
:
struct X {
  X();
  X& operator=(X&);
};
const X cx;
X x;
void f() {
  x = cx;           // error: X​::​operator=(X&) cannot assign cx into x
}
end example
]
end note
]
If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted ([dcl.fct.def]).
The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor.
The implicitly-declared copy assignment operator for a class X will have the form
X& X::operator=(const X&)
if
  • each direct base class B of X has a copy assignment operator whose parameter is of type const B&, const volatile B& or B, and
  • for all the non-static data members of X that are of a class type M (or array thereof), each such class type has a copy assignment operator whose parameter is of type const M&, const volatile M& or M.121
Otherwise, the implicitly-declared copy assignment operator will have the form
X& X::operator=(X&)
A user-declared move assignment operator X​::​operator= is a non-static non-template member function of class X with exactly one parameter of type X&&, const X&&, volatile X&&, or const volatile X&&.
[Note
:
An overloaded assignment operator must be declared to have only one parameter; see [over.ass].
end note
]
[Note
:
More than one form of move assignment operator may be declared for a class.
end note
]
If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if
  • X does not have a user-declared copy constructor,
  • X does not have a user-declared move constructor,
  • X does not have a user-declared copy assignment operator, and
  • X does not have a user-declared destructor.
[Example
:
The class definition
struct S {
  int a;
  S& operator=(const S&) = default;
};
will not have a default move assignment operator implicitly declared because the copy assignment operator has been user-declared.
The move assignment operator may be explicitly defaulted.
struct S {
  int a;
  S& operator=(const S&) = default;
  S& operator=(S&&) = default;
};
end example
]
The implicitly-declared move assignment operator for a class X will have the form
X& X::operator=(X&&);
The implicitly-declared copy/move assignment operator for class X has the return type X&; it returns the object for which the assignment operator is invoked, that is, the object assigned to.
An implicitly-declared copy/move assignment operator is an inline public member of its class.
A defaulted copy/move assignment operator for class X is defined as deleted if X has:
  • a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
  • a non-static data member of const non-class type (or array thereof), or
  • a non-static data member of reference type, or
  • a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.
A defaulted move assignment operator that is defined as deleted is ignored by overload resolution ([over.match], [over.over]).
Because a copy/move assignment operator is implicitly declared for a class if not declared by the user, a base class copy/move assignment operator is always hidden by the corresponding assignment operator of a derived class ([over.ass]).
A using-declaration that brings in from a base class an assignment operator with a parameter type that could be that of a copy/move assignment operator for the derived class is not considered an explicit declaration of such an operator and does not suppress the implicit declaration of the derived class operator; the operator introduced by the using-declaration is hidden by the implicitly-declared operator in the derived class.
A copy/move assignment operator for class X is trivial if it is not user-provided and if:
  • class X has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]), and
  • the assignment operator selected to copy/move each direct base class subobject is trivial, and
  • for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial;
otherwise the copy/move assignment operator is non-trivial.
A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) (e.g., when it is selected by overload resolution to assign to an object of its class type) or when it is explicitly defaulted after its first declaration. The implicitly-defined copy/move assignment operator is constexpr if
  • X is a literal type, and
  • the assignment operator selected to copy/move each direct base class subobject is a constexpr function, and
  • for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is a constexpr function.
Before the defaulted copy/move assignment operator for a class is implicitly defined, all non-user-provided copy/move assignment operators for its direct base classes and its non-static data members shall have been implicitly defined.
[Note
:
An implicitly-declared copy/move assignment operator has an implied exception specification ([except.spec]).
end note
]
The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy/move assignment of its subobjects.
The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition.
Let x be either the parameter of the function or, for the move operator, an xvalue referring to the parameter.
Each subobject is assigned in the manner appropriate to its type:
  • if the subobject is of class type, as if by a call to operator= with the subobject as the object expression and the corresponding subobject of x as a single function argument (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes);
  • if the subobject is an array, each element is assigned, in the manner appropriate to the element type;
  • if the subobject is of scalar type, the built-in assignment operator is used.
It is unspecified whether subobjects representing virtual base classes are assigned more than once by the implicitly-defined copy/move assignment operator.
[Example
:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
It is unspecified whether the virtual base class subobject V is assigned twice by the implicitly-defined copy/move assignment operator for C.
end example
]
The implicitly-defined copy assignment operator for a union X copies the object representation ([basic.types]) of X.
Because a template assignment operator or an assignment operator taking an rvalue reference parameter is never a copy assignment operator, the presence of such an assignment operator does not suppress the implicit declaration of a copy assignment operator.
Such assignment operators participate in overload resolution with other assignment operators, including copy assignment operators, and, if selected, will be used to assign an object.
This implies that the reference parameter of the implicitly-declared copy assignment operator cannot bind to a volatile lvalue; see [diff.special].

15.8.3 Copy/move elision [class.copy.elision]

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects.
In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object.
If the first parameter of the selected constructor is an rvalue reference to the object's type, the destruction of that object occurs when the target would have been destroyed; otherwise, the destruction occurs at the later of the times when the two objects would have been destroyed without the optimization.122
This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
  • in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function parameter or a variable introduced by the exception-declaration of a handler ([except.handle])) with the same type (ignoring cv-qualification) as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function call's return object
  • in a throw-expression, when the operand is the name of a non-volatile automatic object (other than a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one), the copy/move operation from the operand to the exception object ([except.throw]) can be omitted by constructing the automatic object directly into the exception object
  • when the exception-declaration of an exception handler (Clause [except]) declares an object of the same type (except for cv-qualification) as the exception object ([except.throw]), the copy operation can be omitted by treating the exception-declaration as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the exception-declaration.
    [Note
    :
    There cannot be a move from the exception object because it is always an lvalue.
    end note
    ]
Copy elision is required where an expression is evaluated in a context requiring a constant expression ([expr.const]) and in constant initialization ([basic.start.static]).
[Note
:
Copy elision might not be performed if the same expression is evaluated in another context.
end note
]
[Example
:
class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};

Thing f() {
  Thing t;
  return t;
}

Thing t2 = f();

struct A {
  void *p;
  constexpr A(): p(this) {}
};

constexpr A g() {
  A a;
  return a;
}

constexpr A a;          // well-formed, a.p points to a
constexpr A b = g();    // well-formed, b.p points to b

void g() {
  A c = g();            // well-formed, c.p may point to c or to an ephemeral temporary
}
Here the criteria for elision can eliminate the copying of the local automatic object t into the result object for the function call f(), which is the global object t2.
Effectively, the construction of the local object t can be viewed as directly initializing the global object t2, and that object's destruction will occur at program exit.
Adding a move constructor to Thing has the same effect, but it is the move construction from the local automatic object to t2 that is elided.
end example
]
In the following copy-initialization contexts, a move operation might be used instead of a copy operation: overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
If the first overload resolution fails or was not performed, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object's type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue.
[Note
:
This two-stage overload resolution must be performed regardless of whether copy elision will occur.
It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided.
end note
]
[Example
:
class Thing {
public:
  Thing();
  ~Thing();
  Thing(Thing&&);
private:
  Thing(const Thing&);
};

Thing f(bool b) {
  Thing t;
  if (b)
    throw t;            // OK: Thing(Thing&&) used (or elided) to throw t
  return t;             // OK: Thing(Thing&&) used (or elided) to return t
}

Thing t2 = f(false);    // OK: no extra copy/move performed, t2 constructed by call to f

struct Weird {
  Weird();
  Weird(Weird&);
};

Weird g() {
  Weird w;
  return w;             // OK: first overload resolution fails, second overload resolution selects Weird(Weird&)
}
end example
]
Because only one object is destroyed instead of two, and one copy/move constructor is not executed, there is still one object destroyed for each one constructed.

16 Overloading [over]

When two or more different declarations are specified for a single name in the same scope, that name is said to be overloaded.
By extension, two declarations in the same scope that declare the same name but with different types are called overloaded declarations.
Only function and function template declarations can be overloaded; variable and type declarations cannot be overloaded.
When an overloaded function name is used in a call, which overloaded function declaration is being referenced is determined by comparing the types of the arguments at the point of use with the types of the parameters in the overloaded declarations that are visible at the point of use.
This function selection process is called overload resolution and is defined in [over.match].
[Example
:
double abs(double);
int abs(int);

abs(1);             // calls abs(int);
abs(1.0);           // calls abs(double);
end example
]

16.1 Overloadable declarations [over.load]

Not all function declarations can be overloaded.
Those that cannot be overloaded are specified here.
A program is ill-formed if it contains two such non-overloadable declarations in the same scope.
[Note
:
This restriction applies to explicit declarations in a scope, and between such declarations and declarations made through a using-declaration ([namespace.udecl]).
It does not apply to sets of functions fabricated as a result of name lookup (e.g., because of using-directives) or overload resolution (e.g., for operator functions).
end note
]
Certain function declarations cannot be overloaded:
  • Function declarations that differ only in the return type, the exception specification ([except.spec]), or both cannot be overloaded.
  • Member function declarations with the same name and the same parameter-type-list ([dcl.fct]) cannot be overloaded if any of them is a static member function declaration ([class.static]).
    Likewise, member function template declarations with the same name, the same parameter-type-list, and the same template parameter lists cannot be overloaded if any of them is a static member function template declaration.
    The types of the implicit object parameters constructed for the member functions for the purpose of overload resolution ([over.match.funcs]) are not considered when comparing parameter-type-lists for enforcement of this rule.
    In contrast, if there is no static member function declaration among a set of member function declarations with the same name and the same parameter-type-list, then these member function declarations can be overloaded if they differ in the type of their implicit object parameter.
    [Example
    :
    The following illustrates this distinction:
    class X {
      static void f();
      void f();                     // ill-formed
      void f() const;               // ill-formed
      void f() const volatile;      // ill-formed
      void g();
      void g() const;               // OK: no static g
      void g() const volatile;      // OK: no static g
    };
    end example
    ]
  • Member function declarations with the same name and the same parameter-type-list ([dcl.fct]) as well as member function template declarations with the same name, the same parameter-type-list, and the same template parameter lists cannot be overloaded if any of them, but not all, have a ref-qualifier ([dcl.fct]).
    [Example
    :
    class Y {
      void h() &;
      void h() const &;             // OK
      void h() &&;                  // OK, all declarations have a ref-qualifier
      void i() &;
      void i() const;               // ill-formed, prior declaration of i
                                    // has a ref-qualifier
    };
    end example
    ]
[Note
:
As specified in [dcl.fct], function declarations that have equivalent parameter declarations declare the same function and therefore cannot be overloaded:
  • Parameter declarations that differ only in the use of equivalent typedef “types” are equivalent.
    A typedef is not a separate type, but only a synonym for another type ([dcl.typedef]).
    [Example
    :
    typedef int Int;
    
    void f(int i);
    void f(Int i);                  // OK: redeclaration of f(int)
    void f(int i) { /* ... */ }
    void f(Int i) { /* ... */ }     // error: redefinition of f(int)
    
    end example
    ]
    Enumerations, on the other hand, are distinct types and can be used to distinguish overloaded function declarations.
    [Example
    :
    enum E { a };
    
    void f(int i) { /* ... */ }
    void f(E i)   { /* ... */ }
    end example
    ]
  • Parameter declarations that differ only in a pointer * versus an array [] are equivalent.
    That is, the array declaration is adjusted to become a pointer declaration ([dcl.fct]).
    Only the second and subsequent array dimensions are significant in parameter types ([dcl.array]).
    [Example
    :
    int f(char*);
    int f(char[]);                  // same as f(char*);
    int f(char[7]);                 // same as f(char*);
    int f(char[9]);                 // same as f(char*);
    
    int g(char(*)[10]);
    int g(char[5][10]);             // same as g(char(*)[10]);
    int g(char[7][10]);             // same as g(char(*)[10]);
    int g(char(*)[20]);             // different from g(char(*)[10]);
    
    end example
    ]
  • Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent.
    That is, the function type is adjusted to become a pointer to function type ([dcl.fct]).
    [Example
    :
    void h(int());
    void h(int (*)());              // redeclaration of h(int())
    void h(int x()) { }             // definition of h(int())
    void h(int (*x)()) { }          // ill-formed: redefinition of h(int())
    
    end example
    ]
  • Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent.
    That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.
    [Example
    :
    typedef const int cInt;
    
    int f (int);
    int f (const int);              // redeclaration of f(int)
    int f (int) { /* ... */ }       // definition of f(int)
    int f (cInt) { /* ... */ }      // error: redefinition of f(int)
    
    end example
    ]
    Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations.123
    In particular, for any type T, “pointer to T”, “pointer to const T”, and “pointer to volatile T” are considered distinct parameter types, as are “reference to T”, “reference to const T”, and “reference to volatile T.
  • Two parameter declarations that differ only in their default arguments are equivalent.
    [Example
    :
    Consider the following:
    void f (int i, int j);
    void f (int i, int j = 99);     // OK: redeclaration of f(int, int)
    void f (int i = 88, int j);     // OK: redeclaration of f(int, int)
    void f ();                      // OK: overloaded declaration of f
    
    void prog () {
        f (1, 2);                   // OK: call f(int, int)
        f (1);                      // OK: call f(int, int)
        f ();                       // Error: f(int, int) or f()?
    }
    end example
    ]
end note
]
When a parameter type includes a function type, such as in the case of a parameter type that is a pointer to function, the const and volatile type-specifiers at the outermost level of the parameter type specifications for the inner function type are also ignored.

16.2 Declaration matching [over.dcl]

Two function declarations of the same name refer to the same function if they are in the same scope and have equivalent parameter declarations ([over.load]).
A function member of a derived class is not in the same scope as a function member of the same name in a base class.
[Example
:
struct B {
  int f(int);
};

struct D : B {
  int f(const char*);
};
Here D​::​f(const char*) hides B​::​f(int) rather than overloading it.
void h(D* pd) {
  pd->f(1);                     // error:
                                // D​::​f(const char*) hides B​::​f(int)
  pd->B::f(1);                  // OK
  pd->f("Ben");                 // OK, calls D​::​f
}
end example
]
A locally declared function is not in the same scope as a function in a containing scope.
[Example
:
void f(const char*);
void g() {
  extern void f(int);
  f("asdf");                    // error: f(int) hides f(const char*)
                                // so there is no f(const char*) in this scope
}

void caller () {
  extern void callee(int, int);
  {
    extern void callee(int);    // hides callee(int, int)
    callee(88, 99);             // error: only callee(int) in scope
  }
}
end example
]
Different versions of an overloaded member function can be given different access rules.
[Example
:
class buffer {
private:
    char* p;
    int size;
protected:
    buffer(int s, char* store) { size = s; p = store; }
public:
    buffer(int s) { p = new char[size = s]; }
};
end example
]

16.3 Overload resolution [over.match]

Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are to be the arguments of the call and a set of candidate functions that can be called based on the context of the call.
The selection criteria for the best function are the number of arguments, how well the arguments match the parameter-type-list of the candidate function, how well (for non-static member functions) the object matches the implicit object parameter, and certain other properties of the candidate function.
[Note
:
The function selected by overload resolution is not guaranteed to be appropriate for the context.
Other restrictions, such as the accessibility of the function, can make its use in the calling context ill-formed.
end note
]
Overload resolution selects the function to call in seven distinct contexts within the language:
  • invocation of a function named in the function call syntax ([over.call.func]);
  • invocation of a function call operator, a pointer-to-function conversion function, a reference-to-pointer-to-function conversion function, or a reference-to-function conversion function on a class object named in the function call syntax ([over.call.object]);
  • invocation of the operator referenced in an expression ([over.match.oper]);
  • invocation of a constructor for default- or direct-initialization ([dcl.init]) of a class object ([over.match.ctor]);
  • invocation of a user-defined conversion for copy-initialization ([dcl.init]) of a class object ([over.match.copy]);
  • invocation of a conversion function for initialization of an object of a non-class type from an expression of class type ([over.match.conv]); and
  • invocation of a conversion function for conversion to a glvalue or class prvalue to which a reference ([dcl.init.ref]) will be directly bound ([over.match.ref]).
Each of these contexts defines the set of candidate functions and the list of arguments in its own unique way.
But, once the candidate functions and argument lists have been identified, the selection of the best function is the same in all cases:
  • First, a subset of the candidate functions (those that have the proper number of arguments and meet certain other conditions) is selected to form a set of viable functions ([over.match.viable]).
  • Then the best viable function is selected based on the implicit conversion sequences ([over.best.ics]) needed to match each argument to the corresponding parameter of each viable function.
If a best viable function exists and is unique, overload resolution succeeds and produces it as the result.
Otherwise overload resolution fails and the invocation is ill-formed.
When overload resolution succeeds, and the best viable function is not accessible (Clause [class.access]) in the context in which it is used, the program is ill-formed.

16.3.1 Candidate functions and argument lists [over.match.funcs]

The subclauses of [over.match.funcs] describe the set of candidate functions and the argument list submitted to overload resolution in each of the seven contexts in which overload resolution is used.
The source transformations and constructions defined in these subclauses are only for the purpose of describing the overload resolution process.
An implementation is not required to use such transformations and constructions.
The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list.
So that argument and parameter lists are comparable within this heterogeneous set, a member function is considered to have an extra parameter, called the implicit object parameter, which represents the object for which the member function has been called.
For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.
Similarly, when appropriate, the context can construct an argument list that contains an implied object argument to denote the object to be operated on.
Since arguments and parameters are associated by position within their respective lists, the convention is that the implicit object parameter, if present, is always the first parameter and the implied object argument, if present, is always the first argument.
For non-static member functions, the type of the implicit object parameter is
where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration.
[Example
:
For a const member function of class X, the extra parameter is assumed to have type “reference to const X.
end example
]
For conversion functions, the function is considered to be a member of the class of the implied object argument for the purpose of defining the type of the implicit object parameter.
For non-conversion functions introduced by a using-declaration into a derived class, the function is considered to be a member of the derived class for the purpose of defining the type of the implicit object parameter.
For static member functions, the implicit object parameter is considered to match any object (since if the function is selected, the object is discarded).
[Note
:
No actual type is established for the implicit object parameter of a static member function, and no attempt will be made to determine a conversion sequence for that parameter ([over.match.best]).
end note
]
During overload resolution, the implied object argument is indistinguishable from other arguments.
The implicit object parameter, however, retains its identity since no user-defined conversions can be applied to achieve a type match with it.
For non-static member functions declared without a ref-qualifier, an additional rule applies:
  • even if the implicit object parameter is not const-qualified, an rvalue can be bound to the parameter as long as in all other respects the argument can be converted to the type of the implicit object parameter.
    [Note
    :
    The fact that such an argument is an rvalue does not affect the ranking of implicit conversion sequences ([over.ics.rank]).
    end note
    ]
Because other than in list-initialization only one user-defined conversion is allowed in an implicit conversion sequence, special rules apply when selecting the best user-defined conversion ([over.match.best], [over.best.ics]).
[Example
:
class T {
public:
  T();
};

class C : T {
public:
  C(int);
};
T a = 1;            // ill-formed: T(C(1)) not tried
end example
]
In each case where a candidate is a function template, candidate function template specializations are generated using template argument deduction ([temp.over], [temp.deduct]).
Those candidates are then handled as candidate functions in the usual way.124
A given name can refer to one or more function templates and also to a set of overloaded non-template functions.
In such a case, the candidate functions generated from each function template are combined with the set of non-template candidate functions.
A defaulted move constructor or assignment operator ([class.copy]) that is defined as deleted is excluded from the set of candidate functions in all contexts.
The process of argument deduction fully determines the parameter types of the function template specializations, i.e., the parameters of function template specializations contain no template parameter types. Therefore, except where specified otherwise, function template specializations and non-template functions ([dcl.fct]) are treated equivalently for the remainder of overload resolution.

16.3.1.1 Function call syntax [over.match.call]

In a function call ([expr.call])
postfix-expression ( expression-list )
if the postfix-expression denotes a set of overloaded functions and/or function templates, overload resolution is applied as specified in [over.call.func].
If the postfix-expression denotes an object of class type, overload resolution is applied as specified in [over.call.object].
If the postfix-expression denotes the address of a set of overloaded functions and/or function templates, overload resolution is applied using that set as described above.
If the function selected by overload resolution is a non-static member function, the program is ill-formed.
[Note
:
The resolution of the address of an overload set in other contexts is described in [over.over].
end note
]

16.3.1.1.1 Call to named function [over.call.func]

Of interest in [over.call.func] are only those function calls in which the postfix-expression ultimately contains a name that denotes one or more functions that might be called.
Such a postfix-expression, perhaps nested arbitrarily deep in parentheses, has one of the following forms:
postfix-expression:
	postfix-expression . id-expression
	postfix-expression -> id-expression
	primary-expression
These represent two syntactic subcategories of function calls: qualified function calls and unqualified function calls.
In qualified function calls, the name to be resolved is an id-expression and is preceded by an -> or . operator.
Since the construct A->B is generally equivalent to (*A).B, the rest of Clause [over] assumes, without loss of generality, that all member function calls have been normalized to the form that uses an object and the . operator.
Furthermore, Clause [over] assumes that the postfix-expression that is the left operand of the . operator has type “cv T” where T denotes a class125.
Under this assumption, the id-expression in the call is looked up as a member function of T following the rules for looking up names in classes ([class.member.lookup]).
The function declarations found by that lookup constitute the set of candidate functions.
The argument list is the expression-list in the call augmented by the addition of the left operand of the . operator in the normalized member function call as the implied object argument ([over.match.funcs]).
In unqualified function calls, the name is not qualified by an -> or . operator and has the more general form of a primary-expression.
The name is looked up in the context of the function call following the normal rules for name lookup in function calls ([basic.lookup]).
The function declarations found by that lookup constitute the set of candidate functions.
Because of the rules for name lookup, the set of candidate functions consists (1) entirely of non-member functions or (2) entirely of member functions of some class T.
In case (1), the argument list is the same as the expression-list in the call.
In case (2), the argument list is the expression-list in the call augmented by the addition of an implied object argument as in a qualified function call.
If the keyword this ([class.this]) is in scope and refers to class T, or a derived class of T, then the implied object argument is (*this).
If the keyword this is not in scope or refers to another class, then a contrived object of type T becomes the implied object argument126.
If the argument list is augmented by a contrived object and overload resolution selects one of the non-static member functions of T, the call is ill-formed.
Note that cv-qualifiers on the type of objects are significant in overload resolution for both glvalue and class prvalue objects.
An implied object argument must be contrived to correspond to the implicit object parameter attributed to member functions during overload resolution.
It is not used in the call to the selected function.
Since the member functions all have the same implicit object parameter, the contrived object will not be the cause to select or reject a function.

16.3.1.1.2 Call to object of class type [over.call.object]

If the primary-expression E in the function call syntax evaluates to a class object of type “cv T”, then the set of candidate functions includes at least the function call operators of T.
The function call operators of T are obtained by ordinary lookup of the name operator() in the context of (E).operator().
In addition, for each non-explicit conversion function declared in T of the form
operator conversion-type-id () cv-qualifier ref-qualifier noexcept-specifier attribute-specifier-seq ;
where cv-qualifier is the same cv-qualification as, or a greater cv-qualification than, cv, and where conversion-type-id denotes the type “pointer to function of () returning R”, or the type “reference to pointer to function of () returning R”, or the type “reference to function of () returning R”, a surrogate call function with the unique name call-function and having the form
R call-function ( conversion-type-id  F, P a, , P a) { return F (a, , a); }
is also considered as a candidate function.
Similarly, surrogate call functions are added to the set of candidate functions for each non-explicit conversion function declared in a base class of T provided the function is not hidden within T by another intervening declaration127.
If such a surrogate call function is selected by overload resolution, the corresponding conversion function will be called to convert E to the appropriate function pointer or reference, and the function will then be invoked with the arguments of the call.
If the conversion function cannot be called (e.g., because of an ambiguity), the program is ill-formed.
The argument list submitted to overload resolution consists of the argument expressions present in the function call syntax preceded by the implied object argument (E).
[Note
:
When comparing the call against the function call operators, the implied object argument is compared against the implicit object parameter of the function call operator.
When comparing the call against a surrogate call function, the implied object argument is compared against the first parameter of the surrogate call function.
The conversion function from which the surrogate call function was derived will be used in the conversion sequence for that parameter since it converts the implied object argument to the appropriate function pointer or reference required by that first parameter.
end note
]
[Example
:
int f1(int);
int f2(float);
typedef int (*fp1)(int);
typedef int (*fp2)(float);
struct A {
  operator fp1() { return f1; }
  operator fp2() { return f2; }
} a;
int i = a(1);                   // calls f1 via pointer returned from conversion function
end example
]
Note that this construction can yield candidate call functions that cannot be differentiated one from the other by overload resolution because they have identical declarations or differ only in their return type.
The call will be ambiguous if overload resolution cannot select a match to the call that is uniquely better than such undifferentiable functions.

16.3.1.2 Operators in expressions [over.match.oper]

If no operand of an operator in an expression has a type that is a class or an enumeration, the operator is assumed to be a built-in operator and interpreted according to Clause [expr].
[Note
:
Because ., .*, and ​::​ cannot be overloaded, these operators are always built-in operators interpreted according to Clause [expr].
?: cannot be overloaded, but the rules in this subclause are used to determine the conversions to be applied to the second and third operands when they have class or enumeration type ([expr.cond]).
end note
]
[Example
:
struct String {
  String (const String&);
  String (const char*);
  operator const char* ();
};
String operator + (const String&, const String&);

void f() {
 const char* p= "one" + "two";  // ill-formed because neither operand has class or enumeration type
 int I = 1 + 1;                 // always evaluates to 2 even if class or enumeration types exist
                                // that would perform the operation.
}
end example
]
If either operand has a type that is a class or an enumeration, a user-defined operator function might be declared that implements this operator or a user-defined conversion can be necessary to convert the operand to a type that is appropriate for a built-in operator.
In this case, overload resolution is used to determine which operator function or built-in operator is to be invoked to implement the operator.
Therefore, the operator notation is first transformed to the equivalent function-call notation as summarized in Table 12 (where @ denotes one of the operators covered in the specified subclause).
However, the operands are sequenced in the order prescribed for the built-in operator (Clause [expr]).
Table 12 — Relationship between operator and function call notation
Subclause
Expression
As member function
As non-member function
@a
(a).operator@ ()
operator@(a)
a@b
(a).operator@ (b)
operator@(a, b)
a=b
(a).operator= (b)
a[b]
(a).operator[](b)
a->
(a).operator->()
a@
(a).operator@ (0)
operator@(a, 0)
For a unary operator @ with an operand of a type whose cv-unqualified version is T1, and for a binary operator @ with a left operand of a type whose cv-unqualified version is T1 and a right operand of a type whose cv-unqualified version is T2, three sets of candidate functions, designated member candidates, non-member candidates and built-in candidates, are constructed as follows:
  • If T1 is a complete class type or a class currently being defined, the set of member candidates is the result of the qualified lookup of T1​::​operator@ ([over.call.func]); otherwise, the set of member candidates is empty.
  • The set of non-member candidates is the result of the unqualified lookup of operator@ in the context of the expression according to the usual rules for name lookup in unqualified function calls ([basic.lookup.argdep]) except that all member functions are ignored.
    However, if no operand has a class type, only those non-member functions in the lookup set that have a first parameter of type T1 or “reference to cv T1”, when T1 is an enumeration type, or (if there is a right operand) a second parameter of type T2 or “reference to cv T2”, when T2 is an enumeration type, are candidate functions.
  • For the operator ,, the unary operator &, or the operator ->, the built-in candidates set is empty.
    For all other operators, the built-in candidates include all of the candidate operator functions defined in [over.built] that, compared to the given operator,
    • have the same operator name, and
    • accept the same number of operands, and
    • accept operand types to which the given operand or operands can be converted according to [over.best.ics], and
    • do not have the same parameter-type-list as any non-member candidate that is not a function template specialization.
For the built-in assignment operators, conversions of the left operand are restricted as follows:
  • no temporaries are introduced to hold the left operand, and
  • no user-defined conversions are applied to the left operand to achieve a type match with the left-most parameter of a built-in candidate.
For all other operators, no such restrictions apply.
The set of candidate functions for overload resolution is the union of the member candidates, the non-member candidates, and the built-in candidates.
The argument list contains all of the operands of the operator.
The best function from the set of candidate functions is selected according to [over.match.viable] and [over.match.best].128
[Example
:
struct A {
  operator int();
};
A operator+(const A&, const A&);
void m() {
  A a, b;
  a + b;                        // operator+(a, b) chosen over int(a) + int(b)
}
end example
]
If a built-in candidate is selected by overload resolution, the operands of class type are converted to the types of the corresponding parameters of the selected operation function, except that the second standard conversion sequence of a user-defined conversion sequence ([over.ics.user]) is not applied.
Then the operator is treated as the corresponding built-in operator and interpreted according to Clause [expr].
[Example
:
struct X {
  operator double();
};

struct Y {
  operator int*();
};

int *a = Y() + 100.0;           // error: pointer arithmetic requires integral operand
int *b = Y() + X();             // error: pointer arithmetic requires integral operand
end example
]
The second operand of operator -> is ignored in selecting an operator-> function, and is not an argument when the operator-> function is called.
When operator-> returns, the operator -> is applied to the value returned, with the original second operand.129
If the operator is the operator ,, the unary operator &, or the operator ->, and there are no viable functions, then the operator is assumed to be the built-in operator and interpreted according to Clause [expr].
[Note
:
The lookup rules for operators in expressions are different than the lookup rules for operator function names in a function call, as shown in the following example:
struct A { };
void operator + (A, A);

struct B {
  void operator + (B);
  void f ();
};

A a;

void B::f() {
  operator+ (a,a);              // error: global operator hidden by member
  a + a;                        // OK: calls global operator+
}
end note
]
If the set of candidate functions is empty, overload resolution is unsuccessful.
If the value returned by the operator-> function has class type, this may result in selecting and calling another operator-> function.
The process repeats until an operator-> function returns a value of non-class type.

16.3.1.3 Initialization by constructor [over.match.ctor]

When objects of class type are direct-initialized ([dcl.init]), copy-initialized from an expression of the same or a derived class type ([dcl.init]), or default-initialized ([dcl.init]), overload resolution selects the constructor.
For direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate functions are all the constructors of the class of the object being initialized.
For copy-initialization, the candidate functions are all the converting constructors ([class.conv.ctor]) of that class.
The argument list is the expression-list or assignment-expression of the initializer.

16.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]

Under the conditions specified in [dcl.init], as part of a copy-initialization of an object of class type, a user-defined conversion can be invoked to convert an initializer expression to the type of the object being initialized.
Overload resolution is used to select the user-defined conversion to be invoked.
[Note
:
The conversion performed for indirect binding to a reference to a possibly cv-qualified class type is determined in terms of a corresponding non-reference copy-initialization.
end note
]
Assuming that “cv1 T” is the type of the object being initialized, with T a class type, the candidate functions are selected as follows:
  • The converting constructors ([class.conv.ctor]) of T are candidate functions.
  • When the type of the initializer expression is a class type “cv S”, the non-explicit conversion functions of S and its base classes are considered.
    When initializing a temporary to be bound to the first parameter of a constructor where the parameter is of type “reference to possibly cv-qualified T” and the constructor is called with a single argument in the context of direct-initialization of an object of type “cv2 T”, explicit conversion functions are also considered.
    Those that are not hidden within S and yield a type whose cv-unqualified version is the same type as T or is a derived class thereof are candidate functions.
    Conversion functions that return “reference to X” return lvalues or xvalues, depending on the type of reference, of type X and are therefore considered to yield X for this process of selecting candidate functions.
In both cases, the argument list has one argument, which is the initializer expression.
[Note
:
This argument will be compared against the first parameter of the constructors and against the implicit object parameter of the conversion functions.
end note
]

16.3.1.5 Initialization by conversion function [over.match.conv]

Under the conditions specified in [dcl.init], as part of an initialization of an object of non-class type, a conversion function can be invoked to convert an initializer expression of class type to the type of the object being initialized.
Overload resolution is used to select the conversion function to be invoked.
Assuming that “cv1 T” is the type of the object being initialized, and “cv S” is the type of the initializer expression, with S a class type, the candidate functions are selected as follows:
  • The conversion functions of S and its base classes are considered.
    Those non-explicit conversion functions that are not hidden within S and yield type T or a type that can be converted to type T via a standard conversion sequence ([over.ics.scs]) are candidate functions.
    For direct-initialization, those explicit conversion functions that are not hidden within S and yield type T or a type that can be converted to type T with a qualification conversion ([conv.qual]) are also candidate functions.
    Conversion functions that return a cv-qualified type are considered to yield the cv-unqualified version of that type for this process of selecting candidate functions.
    Conversion functions that return “reference to cv2 X” return lvalues or xvalues, depending on the type of reference, of type “cv2 X” and are therefore considered to yield X for this process of selecting candidate functions.
The argument list has one argument, which is the initializer expression.
[Note
:
This argument will be compared against the implicit object parameter of the conversion functions.
end note
]

16.3.1.6 Initialization by conversion function for direct reference binding [over.match.ref]

Under the conditions specified in [dcl.init.ref], a reference can be bound directly to a glvalue or class prvalue that is the result of applying a conversion function to an initializer expression.
Overload resolution is used to select the conversion function to be invoked.
Assuming that “reference to cv1 T” is the type of the reference being initialized, and “cv S” is the type of the initializer expression, with S a class type, the candidate functions are selected as follows:
  • The conversion functions of S and its base classes are considered.
    Those non-explicit conversion functions that are not hidden within S and yield type “lvalue reference to cv2 T2” (when initializing an lvalue reference or an rvalue reference to function) or “cv2 T2” or “rvalue reference to cv2 T2” (when initializing an rvalue reference or an lvalue reference to function), where “cv1 T” is reference-compatible ([dcl.init.ref]) with “cv2 T2”, are candidate functions.
    For direct-initialization, those explicit conversion functions that are not hidden within S and yield type “lvalue reference to cv2 T2” or “cv2 T2” or “rvalue reference to cv2 T2”, respectively, where T2 is the same type as T or can be converted to type T with a qualification conversion ([conv.qual]), are also candidate functions.
The argument list has one argument, which is the initializer expression.
[Note
:
This argument will be compared against the implicit object parameter of the conversion functions.
end note
]

16.3.1.7 Initialization by list-initialization [over.match.list]

When objects of non-aggregate class type T are list-initialized such that [dcl.init.list] specifies that overload resolution is performed according to the rules in this section, overload resolution selects the constructor in two phases:
  • Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list consists of the initializer list as a single argument.
  • If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.
If the initializer list has no elements and T has a default constructor, the first phase is omitted.
In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed.
[Note
:
This differs from other situations ([over.match.ctor], [over.match.copy]), where only converting constructors are considered for copy-initialization.
This restriction only applies if this initialization is part of the final result of overload resolution.
end note
]

16.3.1.8 Class template argument deduction [over.match.class.deduct]

A set of functions and function templates is formed comprising:
  • For each constructor of the primary class template designated by the template-name, if the template is defined, a function template with the following properties:
    • The template parameters are the template parameters of the class template followed by the template parameters (including default template arguments) of the constructor, if any.
    • The types of the function parameters are those of the constructor.
    • The return type is the class template specialization designated by the template-name and template arguments corresponding to the template parameters obtained from the class template.
  • If the primary class template C is not defined or does not declare any constructors, an additional function template derived as above from a hypothetical constructor C().
  • An additional function template derived as above from a hypothetical constructor C(C), called the copy deduction candidate.
  • For each deduction-guide, a function or function template with the following properties:
Initialization and overload resolution are performed as described in [dcl.init] and [over.match.ctor], [over.match.copy], or [over.match.list] (as appropriate for the type of initialization performed) for an object of a hypothetical class type, where the selected functions and function templates are considered to be the constructors of that class type for the purpose of forming an overload set, and the initializer is provided by the context in which class template argument deduction was performed.
Each such notional constructor is considered to be explicit if the function or function template was generated from a constructor or deduction-guide that was declared explicit.
All such notional constructors are considered to be public members of the hypothetical class type.
[Example
:
template <class T> struct A {
  explicit A(const T&, ...) noexcept;  // #1
  A(T&&, ...);                         // #2
};

int i;
A a1 = { i, i };    // error: explicit constructor #1 selected in copy-list-initialization during deduction,
                    // cannot deduce from non-forwarding rvalue reference in #2

A a2{i, i};         // OK, #1 deduces to A<int> and also initializes
A a3{0, i};         // OK, #2 deduces to A<int> and also initializes
A a4 = {0, i};      // OK, #2 deduces to A<int> and also initializes

template <class T> A(const T&, const T&) -> A<T&>;  // #3
template <class T> explicit A(T&&, T&&) -> A<T>;    // #4

A a5 = {0, 1};      // error: explicit deduction guide #4 selected in copy-list-initialization during deduction
A a6{0,1};          // OK, #4 deduces to A<int> and #2 initializes
A a7 = {0, i};      // error: #3 deduces to A<int&>, #1 and #2 declare same constructor
A a8{0,i};          // error: #3 deduces to A<int&>, #1 and #2 declare same constructor

template <class T> struct B {
  template <class U> using TA = T;
  template <class U> B(U, TA<U>);
};

B b{(int*)0, (char*)0};         // OK, deduces B<char*>
end example
]

16.3.2 Viable functions [over.match.viable]

From the set of candidate functions constructed for a given context ([over.match.funcs]), a set of viable functions is chosen, from which the best function will be selected by comparing argument conversion sequences for the best fit ([over.match.best]).
The selection of viable functions considers relationships between arguments and function parameters other than the ranking of conversion sequences.
First, to be a viable function, a candidate function shall have enough parameters to agree in number with the arguments in the list.
  • If there are m arguments in the list, all candidate functions having exactly m parameters are viable.
  • A candidate function having fewer than m parameters is viable only if it has an ellipsis in its parameter list ([dcl.fct]).
    For the purposes of overload resolution, any argument for which there is no corresponding parameter is considered to “match the ellipsis” ([over.ics.ellipsis]) .
  • A candidate function having more than m parameters is viable only if the (m+1)-st parameter has a default argument ([dcl.fct.default]).130
    For the purposes of overload resolution, the parameter list is truncated on the right, so that there are exactly m parameters.
Second, for F to be a viable function, there shall exist for each argument an implicit conversion sequence ([over.best.ics]) that converts that argument to the corresponding parameter of F.
If the parameter has reference type, the implicit conversion sequence includes the operation of binding the reference, and the fact that an lvalue reference to non-const cannot be bound to an rvalue and that an rvalue reference cannot be bound to an lvalue can affect the viability of the function (see [over.ics.ref]).
According to [dcl.fct.default], parameters following the (m+1)-st parameter must also have default arguments.

16.3.3 Best viable function [over.match.best]

Define ICSi(F) as follows:
  • If F is a static member function, ICS1(F) is defined such that ICS1(F) is neither better nor worse than ICS1(G) for any function G, and, symmetrically, ICS1(G) is neither better nor worse than ICS1(F);131 otherwise,
  • let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the type of the i-th parameter of viable function F.
    [over.best.ics] defines the implicit conversion sequences and [over.ics.rank] defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
  • for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
  • the context is an initialization by user-defined conversion (see [dcl.init], [over.match.conv], and [over.match.ref]) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type
    [Example
    :
    struct A {
      A();
      operator int();
      operator double();
    } a;
    int i = a;          // a.operator int() followed by no conversion is better than
                        // a.operator double() followed by a conversion to int
    float x = a;        // ambiguous: both possibilities require conversions,
                        // and neither is better than the other
    
    end example
    ]
    or, if not that,
  • the context is an initialization by conversion function for direct reference binding ([over.match.ref]) of a reference to function type, the return type of F1 is the same kind of reference (i.e. lvalue or rvalue) as the reference being initialized, and the return type of F2 is not
    [Example
    :
    template <class T> struct A {
      operator T&();    // #1
      operator T&&();   // #2
    };
    typedef int Fn();
    A<Fn> a;
    Fn& lf = a;         // calls #1
    Fn&& rf = a;        // calls #2
    
    end example
    ]
    or, if not that,
  • F1 is not a function template specialization and F2 is a function template specialization, or, if not that,
  • F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in [temp.func.order], or, if not that,
  • F1 is generated from a deduction-guide ([over.match.class.deduct]) and F2 is not, or, if not that,
  • F1 is the copy deduction candidate ([over.match.class.deduct]) and F2 is not, or, if not that,
  • F1 is generated from a non-template constructor and F2 is generated from a constructor template.
    [Example
    :
    template <class T> struct A {
      using value_type = T;
      A(value_type);    // #1
      A(const A&);      // #2
      A(T, T, int);     // #3
      template<class U>
        A(int, T, U);   // #4
      // #5 is the copy deduction candidate, A(A)
    };
    
    A x(1, 2, 3);       // uses #3, generated from a non-template constructor
    
    template <class T>
    A(T) -> A<T>;       // #6, less specialized than #5
    
    A a(42);            // uses #6 to deduce A<int> and #1 to initialize
    A b = a;            // uses #5 to deduce A<int> and #2 to initialize
    
    template <class T>
    A(A<T>) -> A<A<T>>; // #7, as specialized as #5
    
    A b2 = a;           // uses #7 to deduce A<A<int>> and #1 to initialize
    
    end example
    ]
If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed.132
[Example
:
void Fcn(const int*,  short);
void Fcn(int*, int);

int i;
short s = 0;

void f() {
  Fcn(&i, s);       // is ambiguous because &i  int* is better than &i  const int*
                    // but s  short is also better than s  int

  Fcn(&i, 1L);      // calls Fcn(int*, int), because &i  int* is better than &i  const int*
                    // and 1L  short and 1L  int are indistinguishable

  Fcn(&i, 'c');     // calls Fcn(int*, int), because &i  int* is better than &i  const int*
                    // and c  int is better than c  short
}
end example
]
If the best viable function resolves to a function for which multiple declarations were found, and if at least two of these declarations — or the declarations they refer to in the case of using-declarations — specify a default argument that made the function viable, the program is ill-formed.
[Example
:
namespace A {
  extern "C" void f(int = 5);
}
namespace B {
  extern "C" void f(int = 5);
}

using A::f;
using B::f;

void use() {
  f(3);             // OK, default argument was not used for viability
  f();              // Error: found default argument twice
}
end example
]
If a function is a static member function, this definition means that the first argument, the implied object argument, has no effect in the determination of whether the function is better or worse than any other function.
The algorithm for selecting the best viable function is linear in the number of viable functions.
Run a simple tournament to find a function W that is not worse than any opponent it faced.
Although another function F that W did not face might be at least as good as W, F cannot be the best function because at some point in the tournament F encountered another function G such that F was not better than G.
Hence, W is either the best function or there is no best function.
So, make a second pass over the viable functions to verify that W is better than all other functions.

16.3.3.1 Implicit conversion sequences [over.best.ics]

An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called.
The sequence of conversions is an implicit conversion as defined in Clause [conv], which means it is governed by the rules for initialization of an object or reference by a single expression ([dcl.init], [dcl.init.ref]).
Implicit conversion sequences are concerned only with the type, cv-qualification, and value category of the argument and how these are converted to match the corresponding properties of the parameter.
Other properties, such as the lifetime, storage class, alignment, accessibility of the argument, whether the argument is a bit-field, and whether a function is deleted ([dcl.fct.def.delete]), are ignored.
So, although an implicit conversion sequence can be defined for a given argument-parameter pair, the conversion from the argument to the parameter might still be ill-formed in the final analysis.
However, if the target is
  • the first parameter of a constructor or
  • the implicit object parameter of a user-defined conversion function
and the constructor or user-defined conversion function is a candidate by user-defined conversion sequences are not considered.
[Note
:
These rules prevent more than one user-defined conversion from being applied during overload resolution, thereby avoiding infinite recursion.
end note
]
[Example
:
  struct Y { Y(int); };
  struct A { operator int(); };
  Y y1 = A();       // error: A​::​operator int() is not a candidate

  struct X { };
  struct B { operator X(); };
  B b;
  X x({b});         // error: B​::​operator X() is not a candidate
end example
]
For the case where the parameter type is a reference, see [over.ics.ref].
When the parameter type is not a reference, the implicit conversion sequence models a copy-initialization of the parameter from the argument expression.
The implicit conversion sequence is the one required to convert the argument expression to a prvalue of the type of the parameter.
[Note
:
When the parameter has a class type, this is a conceptual conversion defined for the purposes of Clause [over]; the actual initialization is defined in terms of constructors and is not a conversion.
end note
]
Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion.
[Example
:
A parameter of type A can be initialized from an argument of type const A.
The implicit conversion sequence for that case is the identity sequence; it contains no “conversion” from const A to A.
end example
]
When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion.
When the parameter has a class type and the argument expression has a derived class type, the implicit conversion sequence is a derived-to-base Conversion from the derived class to the base class.
[Note
:
There is no such standard conversion; this derived-to-base Conversion exists only in the description of implicit conversion sequences.
end note
]
A derived-to-base Conversion has Conversion rank ([over.ics.scs]).
In all contexts, when converting to the implicit object parameter or when converting to the left operand of an assignment operation only standard conversion sequences are allowed.
If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is the standard conversion sequence consisting of the identity conversion ([over.ics.scs]).
If no sequence of conversions can be found to convert an argument to a parameter type, an implicit conversion sequence cannot be formed.
If several different sequences of conversions exist that each convert the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the ambiguous conversion sequence.
For the purpose of ranking implicit conversion sequences as described in [over.ics.rank], the ambiguous conversion sequence is treated as a user-defined conversion sequence that is indistinguishable from any other user-defined conversion sequence.
[Note
:
This rule prevents a function from becoming non-viable because of an ambiguous conversion sequence for one of its parameters.
[Example
:
class B;
class A { A (B&);};
class B { operator A (); };
class C { C (B&); };
void f(A) { }
void f(C) { }
B b;
f(b);               // ill-formed: ambiguous because there is a conversion b  C (via constructor)
                    // and an (ambiguous) conversion b  A (via constructor or conversion function)
void f(B) { }
f(b);               // OK, unambiguous
end example
]
end note
]
If a function that uses the ambiguous conversion sequence is selected as the best viable function, the call will be ill-formed because the conversion of one of the arguments in the call is ambiguous.
The three forms of implicit conversion sequences mentioned above are defined in the following subclauses.

16.3.3.1.1 Standard conversion sequences [over.ics.scs]

Table 13 summarizes the conversions defined in Clause [conv] and partitions them into four disjoint categories: Lvalue Transformation, Qualification Adjustment, Promotion, and Conversion.
[Note
:
These categories are orthogonal with respect to value category, cv-qualification, and data representation: the Lvalue Transformations do not change the cv-qualification or data representation of the type; the Qualification Adjustments do not change the value category or data representation of the type; and the Promotions and Conversions do not change the value category or cv-qualification of the type.
end note
]
[Note
:
As described in Clause [conv], a standard conversion sequence is either the Identity conversion by itself (that is, no conversion) or consists of one to three conversions from the other four categories.
If there are two or more conversions in the sequence, the conversions are applied in the canonical order: Lvalue Transformation, Promotion or Conversion, Qualification Adjustment.
end note
]
Each conversion in Table 13 also has an associated rank (Exact Match, Promotion, or Conversion).
These are used to rank standard conversion sequences ([over.ics.rank]).
The rank of a conversion sequence is determined by considering the rank of each conversion in the sequence and the rank of any reference binding ([over.ics.ref]).
If any of those has Conversion rank, the sequence has Conversion rank; otherwise, if any of those has Promotion rank, the sequence has Promotion rank; otherwise, the sequence has Exact Match rank.
Table 13 — Conversions
Conversion
Category
Rank
Subclause
No conversions required
Identity
Lvalue-to-rvalue conversion
Array-to-pointer conversion
Lvalue Transformation
Function-to-pointer conversion
Exact Match
Qualification conversions
Function pointer conversion
Qualification Adjustment
Integral promotions
Floating-point promotion
Promotion
Promotion
Integral conversions
Floating-point conversions
Floating-integral conversions
Pointer conversions
Conversion
Conversion
Pointer to member conversions
Boolean conversions

16.3.3.1.2 User-defined conversion sequences [over.ics.user]

A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user-defined conversion ([class.conv]) followed by a second standard conversion sequence.
If the user-defined conversion is specified by a constructor ([class.conv.ctor]), the initial standard conversion sequence converts the source type to the type required by the argument of the constructor.
If the user-defined conversion is specified by a conversion function ([class.conv.fct]), the initial standard conversion sequence converts the source type to the implicit object parameter of the conversion function.
The second standard conversion sequence converts the result of the user-defined conversion to the target type for the sequence.
Since an implicit conversion sequence is an initialization, the special rules for initialization by user-defined conversion apply when selecting the best user-defined conversion for a user-defined conversion sequence (see [over.match.best] and [over.best.ics]).
If the user-defined conversion is specified by a specialization of a conversion function template, the second standard conversion sequence shall have exact match rank.
A conversion of an expression of class type to the same class type is given Exact Match rank, and a conversion of an expression of class type to a base class of that type is given Conversion rank, in spite of the fact that a constructor (i.e., a user-defined conversion function) is called for those cases.

16.3.3.1.3 Ellipsis conversion sequences [over.ics.ellipsis]

An ellipsis conversion sequence occurs when an argument in a function call is matched with the ellipsis parameter specification of the function called (see [expr.call]).

16.3.3.1.4 Reference binding [over.ics.ref]

When a parameter of reference type binds directly ([dcl.init.ref]) to an argument expression, the implicit conversion sequence is the identity conversion, unless the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base Conversion ([over.best.ics]).
[Example
:
struct A {};
struct B : public A {} b;
int f(A&);
int f(B&);
int i = f(b);       // calls f(B&), an exact match, rather than f(A&), a conversion
end example
]
If the parameter binds directly to the result of applying a conversion function to the argument expression, the implicit conversion sequence is a user-defined conversion sequence ([over.ics.user]), with the second standard conversion sequence either an identity conversion or, if the conversion function returns an entity of a type that is a derived class of the parameter type, a derived-to-base Conversion.
When a parameter of reference type is not bound directly to an argument expression, the conversion sequence is the one required to convert the argument expression to the referenced type according to [over.best.ics].
Conceptually, this conversion sequence corresponds to copy-initializing a temporary of the referenced type with the argument expression.
Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion.
Except for an implicit object parameter, for which see [over.match.funcs], a standard conversion sequence cannot be formed if it requires binding an lvalue reference other than a reference to a non-volatile const type to an rvalue or binding an rvalue reference to an lvalue other than a function lvalue.
[Note
:
This means, for example, that a candidate function cannot be a viable function if it has a non-const lvalue reference parameter (other than the implicit object parameter) and the corresponding argument would require a temporary to be created to initialize the lvalue reference (see [dcl.init.ref]).
end note
]
Other restrictions on binding a reference to a particular argument that are not based on the types of the reference and the argument do not affect the formation of a standard conversion sequence, however.
[Example
:
A function with an “lvalue reference to int” parameter can be a viable candidate even if the corresponding argument is an int bit-field.
The formation of implicit conversion sequences treats the int bit-field as an int lvalue and finds an exact match with the parameter.
If the function is selected by overload resolution, the call will nonetheless be ill-formed because of the prohibition on binding a non-const lvalue reference to a bit-field ([dcl.init.ref]).
end example
]

16.3.3.1.5 List-initialization sequence [over.ics.list]

When an argument is an initializer list ([dcl.init.list]), it is not an expression and special rules apply for converting it to a parameter type.
If the parameter type is an aggregate class X and the initializer list has a single element of type cv U, where U is X or a class derived from X, the implicit conversion sequence is the one required to convert the element to the parameter type.
Otherwise, if the parameter type is a character array133 and the initializer list has a single element that is an appropriately-typed string literal ([dcl.init.string]), the implicit conversion sequence is the identity conversion.
Otherwise, if the parameter type is std​::​initializer_­list<X> and all the elements of the initializer list can be implicitly converted to X, the implicit conversion sequence is the worst conversion necessary to convert an element of the list to X, or if the initializer list has no elements, the identity conversion.
This conversion can be a user-defined conversion even in the context of a call to an initializer-list constructor.
[Example
:
void f(std::initializer_list<int>);
f( {} );                // OK: f(initializer_­list<int>) identity conversion
f( {1,2,3} );           // OK: f(initializer_­list<int>) identity conversion
f( {'a','b'} );         // OK: f(initializer_­list<int>) integral promotion
f( {1.0} );             // error: narrowing

struct A {
  A(std::initializer_list<double>);             // #1
  A(std::initializer_list<complex<double>>);    // #2
  A(std::initializer_list<std::string>);        // #3
};
A a{ 1.0,2.0 };         // OK, uses #1

void g(A);
g({ "foo", "bar" });    // OK, uses #3

typedef int IA[3];
void h(const IA&);
h({ 1, 2, 3 });         // OK: identity conversion
end example
]
Otherwise, if the parameter type is “array of N X”, if there exists an implicit conversion sequence for each element of the array from the corresponding element of the initializer list (or from {} if there is no such element), the implicit conversion sequence is the worst such implicit conversion sequence.
Otherwise, if the parameter is a non-aggregate class X and overload resolution per [over.match.list] chooses a single best constructor C of X to perform the initialization of an object of type X from the argument initializer list:
  • If C is not an initializer-list constructor and the initializer list has a single element of type cv U, where U is X or a class derived from X, the implicit conversion sequence has Exact Match rank if U is X, or Conversion rank if U is derived from X.
  • Otherwise, the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.
If multiple constructors are viable but none is better than the others, the implicit conversion sequence is the ambiguous conversion sequence.
User-defined conversions are allowed for conversion of the initializer list elements to the constructor parameter types except as noted in [over.best.ics].
[Example
:
struct A {
  A(std::initializer_list<int>);
};
void f(A);
f( {'a', 'b'} );        // OK: f(A(std​::​initializer_­list<int>)) user-defined conversion

struct B {
  B(int, double);
};
void g(B);
g( {'a', 'b'} );        // OK: g(B(int, double)) user-defined conversion
g( {1.0, 1.0} );        // error: narrowing

void f(B);
f( {'a', 'b'} );        // error: ambiguous f(A) or f(B)

struct C {
  C(std::string);
};
void h(C);
h({"foo"});             // OK: h(C(std​::​string("foo")))

struct D {
  D(A, C);
};
void i(D);
i({ {1,2}, {"bar"} });  // OK: i(D(A(std​::​initializer_­list<int>{1,2}), C(std​::​string("bar"))))
end example
]
Otherwise, if the parameter has an aggregate type which can be initialized from the initializer list according to the rules for aggregate initialization ([dcl.init.aggr]), the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.
[Example
:
struct A {
  int m1;
  double m2;
};

void f(A);
f( {'a', 'b'} );        // OK: f(A(int,double)) user-defined conversion
f( {1.0} );             // error: narrowing
end example
]
Otherwise, if the parameter is a reference, see [over.ics.ref].
[Note
:
The rules in this section will apply for initializing the underlying temporary for the reference.
end note
]
[Example
:
struct A {
  int m1;
  double m2;
};

void f(const A&);
f( {'a', 'b'} );        // OK: f(A(int,double)) user-defined conversion
f( {1.0} );             // error: narrowing

void g(const double &);
g({1});                 // same conversion as int to double
end example
]
Otherwise, if the parameter type is not a class:
  • if the initializer list has one element that is not itself an initializer list, the implicit conversion sequence is the one required to convert the element to the parameter type;
    [Example
    :
    void f(int);
    f( {'a'} );             // OK: same conversion as char to int
    f( {1.0} );             // error: narrowing
    
    end example
    ]
  • if the initializer list has no elements, the implicit conversion sequence is the identity conversion.
    [Example
    :
    void f(int);
    f( { } );               // OK: identity conversion
    
    end example
    ]
In all cases other than those enumerated above, no conversion is possible.
Since there are no parameters of array type, this will only occur as the referenced type of a reference parameter.

16.3.3.2 Ranking implicit conversion sequences [over.ics.rank]

This subclause defines a partial ordering of implicit conversion sequences based on the relationships better conversion sequence and better conversion.
If an implicit conversion sequence S1 is defined by these rules to be a better conversion sequence than S2, then it is also the case that S2 is a worse conversion sequence than S1.
If conversion sequence S1 is neither better than nor worse than conversion sequence S2, S1 and S2 are said to be indistinguishable conversion sequences.
When comparing the basic forms of implicit conversion sequences (as defined in [over.best.ics])
  • a standard conversion sequence ([over.ics.scs]) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and
  • a user-defined conversion sequence ([over.ics.user]) is a better conversion sequence than an ellipsis conversion sequence ([over.ics.ellipsis]).
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:
  • List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if
    • L1 converts to std​::​initializer_­list<X> for some X and L2 does not, or, if not that,
    • L1 converts to type “array of N1 T”, L2 converts to type “array of N2 T”, and N1 is smaller than N2,
    even if one of the other rules in this paragraph would otherwise apply.
    [Example
    :
      void f1(int);                                 // #1
      void f1(std::initializer_list<long>);         // #2
      void g1() { f1({42}); }                       // chooses #2
    
      void f2(std::pair<const char*, const char*>); // #3
      void f2(std::initializer_list<std::string>);  // #4
      void g2() { f2({"foo","bar"}); }              // chooses #4
    
    end example
    ]
  • Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
    • S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by [over.ics.scs], excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or, if not that,
    • the rank of S1 is better than the rank of S2, or S1 and S2 have the same rank and are distinguishable by the rules in the paragraph below, or, if not that,
    • S1 and S2 are reference bindings ([dcl.init.ref]) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference
      [Example
      :
      int i;
      int f1();
      int&& f2();
      int g(const int&);
      int g(const int&&);
      int j = g(i);                   // calls g(const int&)
      int k = g(f1());                // calls g(const int&&)
      int l = g(f2());                // calls g(const int&&)
      
      struct A {
        A& operator<<(int);
        void p() &;
        void p() &&;
      };
      A& operator<<(A&&, char);
      A() << 1;                       // calls A​::​operator<<(int)
      A() << 'c';                     // calls operator<<(A&&, char)
      A a;
      a << 1;                         // calls A​::​operator<<(int)
      a << 'c';                       // calls A​::​operator<<(int)
      A().p();                        // calls A​::​p()&&
      a.p();                          // calls A​::​p()&
      
      end example
      ]
      or, if not that,
    • S1 and S2 are reference bindings ([dcl.init.ref]) and S1 binds an lvalue reference to a function lvalue and S2 binds an rvalue reference to a function lvalue
      [Example
      :
      int f(void(&)());               // #1
      int f(void(&&)());              // #2
      void g();
      int i1 = f(g);                  // calls #1
      
      end example
      ]
      or, if not that,
    • S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 ([conv.qual]), respectively, and the cv-qualification signature of type T1 is a proper subset of the cv-qualification signature of type T2
      [Example
      :
      int f(const volatile int *);
      int f(const int *);
      int i;
      int j = f(&i);                  // calls f(const int*)
      
      end example
      ]
      or, if not that,
    • S1 and S2 are reference bindings ([dcl.init.ref]), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers.
      [Example
      :
      int f(const int &);
      int f(int &);
      int g(const int &);
      int g(int);
      
      int i;
      int j = f(i);                   // calls f(int &)
      int k = g(i);                   // ambiguous
      
      struct X {
        void f() const;
        void f();
      };
      void g(const X& a, X b) {
        a.f();                        // calls X​::​f() const
        b.f();                        // calls X​::​f()
      }
      end example
      ]
  • User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or they initialize the same class in an aggregate initialization and in either case the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2.
    [Example
    :
    struct A {
      operator short();
    } a;
    int f(int);
    int f(float);
    int i = f(a);                   // calls f(int), because short  int is
                                    // better than short  float.
    
    end example
    ]
Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion.
Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies:
  • A conversion that does not convert a pointer, a pointer to member, or std​::​nullptr_­t to bool is better than one that does.
  • A conversion that promotes an enumeration whose underlying type is fixed to its underlying type is better than one that promotes to the promoted underlying type, if the two are different.
  • If class B is derived directly or indirectly from class A, conversion of B* to A* is better than conversion of B* to void*, and conversion of A* to void* is better than conversion of B* to void*.
  • If class B is derived directly or indirectly from class A and class C is derived directly or indirectly from B,
    • conversion of C* to B* is better than conversion of C* to A*,
      [Example
      :
      struct A {};
      struct B : public A {};
      struct C : public B {};
      C* pc;
      int f(A*);
      int f(B*);
      int i = f(pc);                  // calls f(B*)
      
      end example
      ]
    • binding of an expression of type C to a reference to type B is better than binding an expression of type C to a reference to type A,
    • conversion of A​::​* to B​::​* is better than conversion of A​::​* to C​::​*,
    • conversion of C to B is better than conversion of C to A,
    • conversion of B* to A* is better than conversion of C* to A*,
    • binding of an expression of type B to a reference to type A is better than binding an expression of type C to a reference to type A,
    • conversion of B​::​* to C​::​* is better than conversion of A​::​* to C​::​*, and
    • conversion of B to A is better than conversion of C to A.
    [Note
    :
    Compared conversion sequences will have different source types only in the context of comparing the second standard conversion sequence of an initialization by user-defined conversion (see [over.match.best]); in all other contexts, the source types will be the same and the target types will be different.
    end note
    ]

16.4 Address of overloaded function [over.over]

A use of an overloaded function name without arguments is resolved in certain contexts to a function, a pointer to function or a pointer to member function for a specific function from the overload set.
A function template name is considered to name a set of overloaded functions in such contexts.
A function with type F is selected for the function type FT of the target type required in the context if F (after possibly applying the function pointer conversion ([conv.fctptr])) is identical to FT.
[Note
:
That is, the class of which the function is a member is ignored when matching a pointer-to-member-function type.
end note
]
The target can be
The overloaded function name can be preceded by the & operator.
An overloaded function name shall not be used without arguments in contexts other than those listed.
[Note
:
Any redundant set of parentheses surrounding the overloaded function name is ignored ([expr.prim]).
end note
]
If the name is a function template, template argument deduction is done ([temp.deduct.funcaddr]), and if the argument deduction succeeds, the resulting template argument list is used to generate a single function template specialization, which is added to the set of overloaded functions considered.
[Note
:
As described in [temp.arg.explicit], if deduction fails and the function template name is followed by an explicit template argument list, the template-id is then examined to see whether it identifies a single function template specialization.
If it does, the template-id is considered to be an lvalue for that function template specialization.
The target type is not used in that determination.
end note
]
Non-member functions and static member functions match targets of function pointer type or reference to function type.
Non-static member functions match targets of pointer to member function type.
If a non-static member function is selected, the reference to the overloaded function name is required to have the form of a pointer to member as described in [expr.unary.op].
If more than one function is selected, any function template specializations in the set are eliminated if the set also contains a function that is not a function template specialization, and any given function template specialization F1 is eliminated if the set contains a second function template specialization whose function template is more specialized than the function template of F1 according to the partial ordering rules of [temp.func.order].
After such eliminations, if any, there shall remain exactly one selected function.
[Example
:
int f(double);
int f(int);
int (*pfd)(double) = &f;        // selects f(double)
int (*pfi)(int) = &f;           // selects f(int)
int (*pfe)(...) = &f;           // error: type mismatch
int (&rfi)(int) = f;            // selects f(int)
int (&rfd)(double) = f;         // selects f(double)
void g() {
  (int (*)(int))&f;             // cast expression as selector
}
The initialization of pfe is ill-formed because no f() with type int(...) has been declared, and not because of any ambiguity.
For another example,
struct X {
  int f(int);
  static int f(long);
};

int (X::*p1)(int)  = &X::f;     // OK
int    (*p2)(int)  = &X::f;     // error: mismatch
int    (*p3)(long) = &X::f;     // OK
int (X::*p4)(long) = &X::f;     // error: mismatch
int (X::*p5)(int)  = &(X::f);   // error: wrong syntax for
                                // pointer to member
int    (*p6)(long) = &(X::f);   // OK
end example
]
[Note
:
If f() and g() are both overloaded functions, the cross product of possibilities must be considered to resolve f(&g), or the equivalent expression f(g).
end note
]
[Note
:
Even if B is a public base of D, we have
D* f();
B* (*p1)() = &f;                // error

void g(D*);
void (*p2)(B*) = &g;            // error
end note
]

16.5 Overloaded operators [over.oper]

A function declaration having one of the following operator-function-ids as its name declares an operator function.
A function template declaration having one of the following operator-function-ids as its name declares an operator function template.
A specialization of an operator function template is also an operator function.
An operator function is said to implement the operator named in its operator-function-id.
operator-function-id:
	operator operator
operator: one of
	new	delete	new[]	delete[]
	+	-	*	/	%	^	&	|	~
	!	=	<	>	+=	-=	*=	/=	%=
	^=	&=	|=	<<	>>	>>=	<<=	==	!=
	<=	>=	&&	||	++	--	,	->*	->
	()	[]
[Note
:
The last two operators are function call ([expr.call]) and subscripting ([expr.sub]).
The operators new[], delete[], (), and [] are formed from more than one token.
end note
]
Both the unary and binary forms of
+    -    *     &
can be overloaded.
The following operators cannot be overloaded:
.    .*   ::    ?:
nor can the preprocessing symbols # and ## (Clause [cpp]).
Operator functions are usually not called directly; instead they are invoked to evaluate the operators they implement ([over.unary][over.inc]).
They can be explicitly called, however, using the operator-function-id as the name of the function in the function call syntax ([expr.call]).
[Example
:
complex z = a.operator+(b);     // complex z = a+b;
void* p = operator new(sizeof(int)*n);
end example
]
The allocation and deallocation functions, operator new, operator new[], operator delete and operator delete​[], are described completely in [basic.stc.dynamic].
The attributes and restrictions found in the rest of this subclause do not apply to them unless explicitly stated in [basic.stc.dynamic].
An operator function shall either be a non-static member function or be a non-member function that has at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration.
It is not possible to change the precedence, grouping, or number of operands of operators.
The meaning of the operators =, (unary) &, and , (comma), predefined for each type, can be changed for specific class and enumeration types by defining operator functions that implement these operators.
Operator functions are inherited in the same manner as other base class functions.
The identities among certain predefined operators applied to basic types (for example, ++a a+=1) need not hold for operator functions.
Some predefined operators, such as +=, require an operand to be an lvalue when applied to basic types; this is not required by operator functions.
An operator function cannot have default arguments ([dcl.fct.default]), except where explicitly stated below.
Operator functions cannot have more or fewer parameters than the number required for the corresponding operator, as described in the rest of this subclause.
Operators not mentioned explicitly in subclauses [over.ass] through [over.inc] act as ordinary unary and binary operators obeying the rules of [over.unary] or [over.binary].

16.5.1 Unary operators [over.unary]

A prefix unary operator shall be implemented by a non-static member function ([class.mfct]) with no parameters or a non-member function with one parameter.
Thus, for any prefix unary operator @, @x can be interpreted as either x.operator@() or operator@(x).
If both forms of the operator function have been declared, the rules in [over.match.oper] determine which, if any, interpretation is used.
See [over.inc] for an explanation of the postfix unary operators ++ and --.
The unary and binary forms of the same operator are considered to have the same name.
[Note
:
Consequently, a unary operator can hide a binary operator from an enclosing scope, and vice versa.
end note
]

16.5.2 Binary operators [over.binary]

A binary operator shall be implemented either by a non-static member function ([class.mfct]) with one parameter or by a non-member function with two parameters.
Thus, for any binary operator @, x@y can be interpreted as either x.operator@(y) or operator@(x,y).
If both forms of the operator function have been declared, the rules in [over.match.oper] determine which, if any, interpretation is used.

16.5.3 Assignment [over.ass]

An assignment operator shall be implemented by a non-static member function with exactly one parameter.
Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user ([class.copy]), a base class assignment operator is always hidden by the copy assignment operator of the derived class.
Any assignment operator, even the copy and move assignment operators, can be virtual.
[Note
:
For a derived class D with a base class B for which a virtual copy/move assignment has been declared, the copy/move assignment operator in D does not override B's virtual copy/move assignment operator.
[Example
:
struct B {
  virtual int operator= (int);
  virtual B& operator= (const B&);
};
struct D : B {
  virtual int operator= (int);
  virtual D& operator= (const B&);
};

D dobj1;
D dobj2;
B* bptr = &dobj1;
void f() {
  bptr->operator=(99);          // calls D​::​operator=(int)
  *bptr = 99;                   // ditto
  bptr->operator=(dobj2);       // calls D​::​operator=(const B&)
  *bptr = dobj2;                // ditto
  dobj1 = dobj2;                // calls implicitly-declared D​::​operator=(const D&)
}
end example
]
end note
]

16.5.4 Function call [over.call]

operator() shall be a non-static member function with an arbitrary number of parameters.
It can have default arguments.
It implements the function call syntax
postfix-expression ( expression-list )
where the postfix-expression evaluates to a class object and the possibly empty expression-list matches the parameter list of an operator() member function of the class.
Thus, a call x(arg1,...) is interpreted as x.operator()(arg1, ...) for a class object x of type T if T​::​operator()(T1, T2, T3) exists and if the operator is selected as the best match function by the overload resolution mechanism ([over.match.best]).

16.5.5 Subscripting [over.sub]

operator[] shall be a non-static member function with exactly one parameter.
It implements the subscripting syntax
postfix-expression [ expr-or-braced-init-list ]
Thus, a subscripting expression x[y] is interpreted as x.operator[](y) for a class object x of type T if T​::​operator[](T1) exists and if the operator is selected as the best match function by the overload resolution mechanism ([over.match.best]).
[Example
:
struct X {
  Z operator[](std::initializer_list<int>);
};
X x;
x[{1,2,3}] = 7;           // OK: meaning x.operator[]({1,2,3})
int a[10];
a[{1,2,3}] = 7;           // error: built-in subscript operator
end example
]

16.5.6 Class member access [over.ref]

operator-> shall be a non-static member function taking no parameters.
It implements the class member access syntax that uses ->.
postfix-expression -> template id-expression
postfix-expression -> pseudo-destructor-name
An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T​::​operator->() exists and if the operator is selected as the best match function by the overload resolution mechanism ([over.match]).

16.5.7 Increment and decrement [over.inc]

The user-defined function called operator++ implements the prefix and postfix ++ operator.
If this function is a non-static member function with no parameters, or a non-member function with one parameter, it defines the prefix increment operator ++ for objects of that type.
If the function is a non-static member function with one parameter (which shall be of type int) or a non-member function with two parameters (the second of which shall be of type int), it defines the postfix increment operator ++ for objects of that type.
When the postfix increment is called as a result of using the ++ operator, the int argument will have value zero.134
[Example
:
struct X {
  X&   operator++();            // prefix ++a
  X    operator++(int);         // postfix a++
};

struct Y { };
Y&   operator++(Y&);            // prefix ++b
Y    operator++(Y&, int);       // postfix b++

void f(X a, Y b) {
  ++a;                          // a.operator++();
  a++;                          // a.operator++(0);
  ++b;                          // operator++(b);
  b++;                          // operator++(b, 0);

  a.operator++();               // explicit call: like ++a;
  a.operator++(0);              // explicit call: like a++;
  operator++(b);                // explicit call: like ++b;
  operator++(b, 0);             // explicit call: like b++;
}
end example
]
The prefix and postfix decrement operators -- are handled analogously.
Calling operator++ explicitly, as in expressions like a.operator++(2), has no special properties: The argument to operator++ is 2.

16.5.8 User-defined literals [over.literal]

The string-literal or user-defined-string-literal in a literal-operator-id shall have no encoding-prefix and shall contain no characters other than the implicit terminating '\0'.
Some literal suffix identifiers are reserved for future standardization; see [usrlit.suffix].
A declaration whose literal-operator-id uses such a literal suffix identifier is ill-formed, no diagnostic required.
A declaration whose declarator-id is a literal-operator-id shall be a declaration of a namespace-scope function or function template (it could be a friend function ([class.friend])), an explicit instantiation or specialization of a function template, or a using-declaration.
A function declared with a literal-operator-id is a literal operator.
A function template declared with a literal-operator-id is a literal operator template.
The declaration of a literal operator shall have a parameter-declaration-clause equivalent to one of the following:
const char*
unsigned long long int
long double
char
wchar_t
char16_t
char32_t
const char*, std::size_t
const wchar_t*, std::size_t
const char16_t*, std::size_t
const char32_t*, std::size_t
If a parameter has a default argument ([dcl.fct.default]), the program is ill-formed.
A raw literal operator is a literal operator with a single parameter whose type is const char*.
The declaration of a literal operator template shall have an empty parameter-declaration-clause and its template-parameter-list shall have a single template-parameter that is a non-type template parameter pack ([temp.variadic]) with element type char.
Literal operators and literal operator templates shall not have C language linkage.
[Note
:
Literal operators and literal operator templates are usually invoked implicitly through user-defined literals ([lex.ext]).
However, except for the constraints described above, they are ordinary namespace-scope functions and function templates.
In particular, they are looked up like ordinary functions and function templates and they follow the same overload resolution rules.
Also, they can be declared inline or constexpr, they may have internal or external linkage, they can be called explicitly, their addresses can be taken, etc.
end note
]
[Example
:
void operator "" _km(long double);                  // OK
string operator "" _i18n(const char*, std::size_t); // OK
template <char...> double operator "" _\u03C0();    // OK: UCN for lowercase pi
float operator ""_e(const char*);                   // OK
float operator ""E(const char*);                    // error: reserved literal suffix ([usrlit.suffix], [lex.ext])
double operator""_Bq(long double);                  // OK: does not use the reserved identifier _­Bq ([lex.name])
double operator"" _Bq(long double);                 // uses the reserved identifier _­Bq ([lex.name])
float operator " " B(const char*);                  // error: non-empty string-literal
string operator "" 5X(const char*, std::size_t);    // error: invalid literal suffix identifier
double operator "" _miles(double);                  // error: invalid parameter-declaration-clause
template <char...> int operator "" _j(const char*); // error: invalid parameter-declaration-clause
extern "C" void operator "" _m(long double);        // error: C language linkage
end example
]

16.6 Built-in operators [over.built]

The candidate operator functions that represent the built-in operators defined in Clause [expr] are specified in this subclause.
These candidate functions participate in the operator overload resolution process as described in [over.match.oper] and are used for no other purpose.
[Note
:
Because built-in operators take only operands with non-class type, and operator overload resolution occurs only when an operand expression originally has class or enumeration type, operator overload resolution can resolve to a built-in operator only when an operand has a class type that has a user-defined conversion to a non-class type appropriate for the operator, or when an operand has an enumeration type that can be converted to a type appropriate for the operator.
Also note that some of the candidate operator functions given in this subclause are more permissive than the built-in operators themselves.
As described in [over.match.oper], after a built-in operator is selected by overload resolution the expression is subject to the requirements for the built-in operator given in Clause [expr], and therefore to any additional semantic constraints given there.
If there is a user-written candidate with the same name and parameter types as a built-in candidate operator function, the built-in operator function is hidden and is not included in the set of candidate functions.
end note
]
In this subclause, the term promoted integral type is used to refer to those integral types which are preserved by integral promotion ([conv.prom]) (including e.g. int and long but excluding e.g. char).
Similarly, the term promoted arithmetic type refers to floating types plus promoted integral types.
[Note
:
In all cases where a promoted integral type or promoted arithmetic type is required, an operand of enumeration type will be acceptable by way of the integral promotions.
end note
]
In the remainder of this section, vq represents either volatile or no cv-qualifier.
For every pair (T, vq), where T is an arithmetic type other than bool, there exist candidate operator functions of the form
vq T& operator++(vq T&);
T operator++(vq T&, int);
For every pair (T, vq), where T is an arithmetic type other than bool, there exist candidate operator functions of the form
vq T& operator--(vq T&);
T operator--(vq T&, int);
For every pair (T, vq), where T is a cv-qualified or cv-unqualified object type, there exist candidate operator functions of the form
T*vq& operator++(T*vq&);
T*vq& operator--(T*vq&);
T*    operator++(T*vq&, int);
T*    operator--(T*vq&, int);
For every cv-qualified or cv-unqualified object type T, there exist candidate operator functions of the form
T&    operator*(T*);
For every function type T that does not have cv-qualifiers or a ref-qualifier, there exist candidate operator functions of the form
T&    operator*(T*);
For every type T there exist candidate operator functions of the form
T*    operator+(T*);
For every promoted arithmetic type T, there exist candidate operator functions of the form
T operator+(T);
T operator-(T);
For every promoted integral type T, there exist candidate operator functions of the form
T operator~(T);
For every quintuple (C1, C2, T, cv1, cv2), where C2 is a class type, C1 is the same type as C2 or is a derived class of C2, and T is an object type or a function type, there exist candidate operator functions of the form
cv12 T& operator->*(cv1 C1*, cv2 T C2::*);
where cv12 is the union of cv1 and cv2.
The return type is shown for exposition only; see [expr.mptr.oper] for the determination of the operator's result type.
For every pair of promoted arithmetic types L and R, there exist candidate operator functions of the form
LR      operator*(L, R);
LR      operator/(L, R);
LR      operator+(L, R);
LR      operator-(L, R);
bool    operator<(L, R);
bool    operator>(L, R);
bool    operator<=(L, R);
bool    operator>=(L, R);
bool    operator==(L, R);
bool    operator!=(L, R);
where LR is the result of the usual arithmetic conversions between types L and R.
For every cv-qualified or cv-unqualified object type T there exist candidate operator functions of the form
T*      operator+(T*, std::ptrdiff_t);
T&      operator[](T*, std::ptrdiff_t);
T*      operator-(T*, std::ptrdiff_t);
T*      operator+(std::ptrdiff_t, T*);
T&      operator[](std::ptrdiff_t, T*);
For every T, where T is a pointer to object type, there exist candidate operator functions of the form
std::ptrdiff_t   operator-(T, T);
For every T, where T is an enumeration type or a pointer type, there exist candidate operator functions of the form
bool    operator<(T, T);
bool    operator>(T, T);
bool    operator<=(T, T);
bool    operator>=(T, T);
bool    operator==(T, T);
bool    operator!=(T, T);
For every pointer to member type T or type std​::​nullptr_­t there exist candidate operator functions of the form
bool    operator==(T, T);
bool    operator!=(T, T);
For every pair of promoted integral types L and R, there exist candidate operator functions of the form
LR      operator%(L, R);
LR      operator&(L, R);
LR      operator^(L, R);
LR      operator|(L, R);
L       operator<<(L, R);
L       operator>>(L, R);
where LR is the result of the usual arithmetic conversions between types L and R.
For every triple (L, vq, R), where L is an arithmetic type, and R is a promoted arithmetic type, there exist candidate operator functions of the form
vq L&   operator=(vq L&, R);
vq L&   operator*=(vq L&, R);
vq L&   operator/=(vq L&, R);
vq L&   operator+=(vq L&, R);
vq L&   operator-=(vq L&, R);
For every pair (T, vq), where T is any type, there exist candidate operator functions of the form
T*vq&   operator=(T*vq&, T*);
For every pair (T, vq), where T is an enumeration or pointer to member type, there exist candidate operator functions of the form
vq T&   operator=(vq T&, T);
For every pair (T, vq), where T is a cv-qualified or cv-unqualified object type, there exist candidate operator functions of the form
T*vq&   operator+=(T*vq&, std::ptrdiff_t);
T*vq&   operator-=(T*vq&, std::ptrdiff_t);
For every triple (L, vq, R), where L is an integral type, and R is a promoted integral type, there exist candidate operator functions of the form
vq L&   operator%=(vq L&, R);
vq L&   operator<<=(vq L&, R);
vq L&   operator>>=(vq L&, R);
vq L&   operator&=(vq L&, R);
vq L&   operator^=(vq L&, R);
vq L&   operator|=(vq L&, R);
There also exist candidate operator functions of the form
bool    operator!(bool);
bool    operator&&(bool, bool);
bool    operator||(bool, bool);
For every pair of promoted arithmetic types L and R, there exist candidate operator functions of the form
LR      operator?:(bool, L, R);
where LR is the result of the usual arithmetic conversions between types L and R.
[Note
:
As with all these descriptions of candidate functions, this declaration serves only to describe the built-in operator for purposes of overload resolution.
The operator “?:” cannot be overloaded.
end note
]
For every type T, where T is a pointer, pointer-to-member, or scoped enumeration type, there exist candidate operator functions of the form
T       operator?:(bool, T, T);

17 Templates [temp]

A template defines a family of classes, functions, or variables, or an alias for a family of types.
template-declaration:
	template < template-parameter-list > declaration
template-parameter-list:
	template-parameter
	template-parameter-list , template-parameter
[Note
:
The > token following the template-parameter-list of a template-declaration may be the product of replacing a >> token by two consecutive > tokens ([temp.names]).
end note
]
The declaration in a template-declaration shall
  • declare or define a function, a class, or a variable, or
  • define a member function, a member class, a member enumeration, or a static data member of a class template or of a class nested within a class template, or
  • define a member template of a class or class template, or
A template-declaration is also a definition if its declaration defines a function, a class, a variable, or a static data member.
A declaration introduced by a template declaration of a variable is a variable template.
A variable template at class scope is a static data member template.
[Example
:
template<class T>
  constexpr T pi = T(3.1415926535897932385L);
template<class T>
T circular_area(T r) {
  return pi<T> * r * r;
}
struct matrix_constants {
  template<class T>
   using pauli = hermitian_matrix<T, 2>;
  template<class T>
   constexpr pauli<T> sigma1 = { { 0, 1 }, { 1, 0 } };
  template<class T>
   constexpr pauli<T> sigma2 = { { 0, -1i }, { 1i, 0 } };
  template<class T>
   constexpr pauli<T> sigma3 = { { 1, 0 }, { 0, -1 } };
};
end example
]
A template-declaration can appear only as a namespace scope or class scope declaration.
In a function template declaration, the last component of the declarator-id shall not be a template-id.
[Note
:
That last component may be an identifier, an operator-function-id, a conversion-function-id, or a literal-operator-id.
In a class template declaration, if the class name is a simple-template-id, the declaration declares a class template partial specialization ([temp.class.spec]).
end note
]
In a template-declaration, explicit specialization, or explicit instantiation the init-declarator-list in the declaration shall contain at most one declarator.
When such a declaration is used to declare a class template, no declarator is permitted.
A template name has linkage ([basic.link]).
Specializations (explicit or implicit) of a template that has internal linkage are distinct from all specializations in other translation units.
A template, a template explicit specialization ([temp.expl.spec]), and a class template partial specialization shall not have C linkage.
Use of a linkage specification other than "C" or "C++" with any of these constructs is conditionally-supported, with implementation-defined semantics.
Template definitions shall obey the one-definition rule ([basic.def.odr]).
[Note
:
Default arguments for function templates and for member functions of class templates are considered definitions for the purpose of template instantiation ([temp.decls]) and must also obey the one-definition rule.
end note
]
A class template shall not have the same name as any other template, class, function, variable, enumeration, enumerator, namespace, or type in the same scope ([basic.scope]), except as specified in [temp.class.spec].
Except that a function template can be overloaded either by non-template functions ([dcl.fct]) with the same name or by other function templates with the same name ([temp.over]), a template name declared in namespace scope or in class scope shall be unique in that scope.
[Note
:
A local class, a local variable, or a friend function defined in a templated entity is a templated entity.
end note
]
A function template, member function of a class template, variable template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated ([temp.inst]) unless the corresponding specialization is explicitly instantiated ([temp.explicit]) in some translation unit; no diagnostic is required.

17.1 Template parameters [temp.param]

The syntax for template-parameters is:
template-parameter:
	type-parameter
	parameter-declaration
type-parameter:
	type-parameter-key ... identifier
	type-parameter-key identifier = type-id
	template < template-parameter-list > type-parameter-key ... identifier
	template < template-parameter-list > type-parameter-key identifier = id-expression
type-parameter-key:
	class
	typename
[Note
:
The > token following the template-parameter-list of a type-parameter may be the product of replacing a >> token by two consecutive > tokens ([temp.names]).
end note
]
There is no semantic difference between class and typename in a type-parameter-key.
typename followed by an unqualified-id names a template type parameter.
typename followed by a qualified-id denotes the type in a non-type135 parameter-declaration.
[Example
:
class T { /* ... */ };
int i;

template<class T, T i> void f(T t) {
  T t1 = i;         // template-parameters T and i
  ::T t2 = ::i;     // global namespace members T and i
}
Here, the template f has a type-parameter called T, rather than an unnamed non-type template-parameter of class T.
end example
]
A storage class shall not be specified in a template-parameter declaration.
Types shall not be defined in a template-parameter declaration.
A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared without template) or template-name (if declared with template) in the scope of the template declaration.
[Note
:
A template argument may be a class template or alias template.
For example,
template<class T> class myarray { /* ... */ };

template<class K, class V, template<class T> class C = myarray>
class Map {
  C<K> key;
  C<V> value;
};
end note
]
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
  • integral or enumeration type,
  • pointer to object or pointer to function,
  • lvalue reference to object or lvalue reference to function,
  • pointer to member,
  • std​::​nullptr_­t, or
  • a type that contains a placeholder type ([dcl.spec.auto]).
[Note
:
Other types are disallowed either explicitly below or implicitly by the rules governing the form of template-arguments ([temp.arg]).
end note
]
The top-level cv-qualifiers on the template-parameter are ignored when determining its type.
A non-type non-reference template-parameter is a prvalue.
It shall not be assigned to or in any other way have its value changed.
A non-type non-reference template-parameter cannot have its address taken.
When a non-type non-reference template-parameter is used as an initializer for a reference, a temporary is always used.
[Example
:
template<const X& x, int i> void f() {
  i++;                          // error: change of template-parameter value

  &x;                           // OK
  &i;                           // error: address of non-reference template-parameter

  int& ri = i;                  // error: non-const reference bound to temporary
  const int& cri = i;           // OK: const reference bound to temporary
}
end example
]
A non-type template-parameter shall not be declared to have floating-point, class, or void type.
[Example
:
template<double d> class X;     // error
template<double* pd> class Y;   // OK
template<double& rd> class Z;   // OK
end example
]
A non-type template-parameter of type “array of T” or of function type T is adjusted to be of type “pointer to T.
[Example
:
template<int* a>   struct R { /* ... */ };
template<int b[5]> struct S { /* ... */ };
int p;
R<&p> w;                        // OK
S<&p> x;                        // OK due to parameter adjustment
int v[5];
R<v> y;                         // OK due to implicit argument conversion
S<v> z;                         // OK due to both adjustment and conversion
end example
]
A default template-argument may be specified for any kind of template-parameter (type, non-type, template) that is not a template parameter pack ([temp.variadic]).
A default template-argument may be specified in a template declaration.
A default template-argument shall not be specified in the template-parameter-lists of the definition of a member of a class template that appears outside of the member's class.
A default template-argument shall not be specified in a friend class template declaration.
If a friend function template declaration specifies a default template-argument, that declaration shall be a definition and shall be the only declaration of the function template in the translation unit.
The set of default template-arguments available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are ([dcl.fct.default]).
[Example
:
template<class T1, class T2 = int> class A;
template<class T1 = int, class T2> class A;
is equivalent to
template<class T1 = int, class T2 = int> class A;
end example
]
If a template-parameter of a class template, variable template, or alias template has a default template-argument, each subsequent template-parameter shall either have a default template-argument supplied or be a template parameter pack.
If a template-parameter of a primary class template, primary variable template, or alias template is a template parameter pack, it shall be the last template-parameter.
A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list ([dcl.fct]) of the function template or has a default argument ([temp.deduct]).
A template parameter of a deduction guide template ([temp.deduct.guide]) that does not have a default argument shall be deducible from the parameter-type-list of the deduction guide template.
[Example
:
template<class T1 = int, class T2> class B;     // error

// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { }   // error
template<class... T, class U> void g() { }      // error
end example
]
A template-parameter shall not be given default arguments by two different declarations in the same scope.
[Example
:
template<class T = int> class X;
template<class T = int> class X { /* ... */ };  // error
end example
]
When parsing a default template-argument for a non-type template-parameter, the first non-nested > is taken as the end of the template-parameter-list rather than a greater-than operator.
[Example
:
template<int i = 3 > 4 >        // syntax error
class X { /* ... */ };

template<int i = (3 > 4) >      // OK
class Y { /* ... */ };
end example
]
A template-parameter of a template template-parameter is permitted to have a default template-argument.
When such default arguments are specified, they apply to the template template-parameter in the scope of the template template-parameter.
[Example
:
template <class T = float> struct B {};
template <template <class TT = float> class T> struct A {
  inline void f();
  inline void g();
};
template <template <class TT> class T> void A<T>::f() {
  T<> t;            // error - TT has no default template argument
}
template <template <class TT = char> class T> void A<T>::g() {
    T<> t;          // OK - T<char>
}
end example
]
If a template-parameter is a type-parameter with an ellipsis prior to its optional identifier or is a parameter-declaration that declares a parameter pack ([dcl.fct]), then the template-parameter is a template parameter pack ([temp.variadic]).
A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded parameter packs is a pack expansion.
Similarly, a template parameter pack that is a type-parameter with a template-parameter-list containing one or more unexpanded parameter packs is a pack expansion.
A template parameter pack that is a pack expansion shall not expand a parameter pack declared in the same template-parameter-list.
[Example
:
template <class... Types> class Tuple;                // Types is a template type parameter pack
                                                      // but not a pack expansion
template <class T, int... Dims> struct multi_array;   // Dims is a non-type template parameter pack
                                                      // but not a pack expansion
template<class... T> struct value_holder {
  template<T... Values> struct apply { };             // Values is a non-type template parameter pack
                                                      // and a pack expansion
};
template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
                                                      // pack T within the same template parameter list
end example
]
Since template template-parameters and template template-arguments are treated as types for descriptive purposes, the terms non-type parameter and non-type argument are used to refer to non-type, non-template parameters and arguments.

17.2 Names of template specializations [temp.names]

A template specialization ([temp.spec]) can be referred to by a template-id:
For a template-name to be explicitly qualified by the template arguments, the name must be known to refer to a template.
After name lookup ([basic.lookup]) finds that a name is a template-name or that an operator-function-id or a literal-operator-id refers to a set of overloaded functions any member of which is a function template, if this is followed by a <, the < is always taken as the delimiter of a template-argument-list and never as the less-than operator.
When parsing a template-argument-list, the first non-nested >136 is taken as the ending delimiter rather than a greater-than operator.
Similarly, the first non-nested >> is treated as two consecutive but distinct > tokens, the first of which is taken as the end of the template-argument-list and completes the template-id.
[Note
:
The second > token produced by this replacement rule may terminate an enclosing template-id construct or it may be part of a different construct (e.g. a cast).
end note
]
[Example
:
template<int i> class X { /* ... */ };

X< 1>2 > x1;                            // syntax error
X<(1>2)> x2;                            // OK

template<class T> class Y { /* ... */ };
Y<X<1>> x3;                             // OK, same as Y<X<1> > x3;
Y<X<6>>1>> x4;                          // syntax error
Y<X<(6>>1)>> x5;                        // OK
end example
]
The keyword template is said to appear at the top level in a qualified-id if it appears outside of a template-argument-list or decltype-specifier.
In a qualified-id of a declarator-id or in a qualified-id formed by a class-head-name or enum-head-name, the keyword template shall not appear at the top level.
In a qualified-id used as the name in a typename-specifier, elaborated-type-specifier, using-declaration, or class-or-decltype, an optional keyword template appearing at the top level is ignored.
In these contexts, a < token is always assumed to introduce a template-argument-list.
In all other contexts, when naming a template specialization of a member of an unknown specialization ([temp.dep.type]), the member template name shall be prefixed by the keyword template.
[Example
:
struct X {
  template<std::size_t> X* alloc();
  template<std::size_t> static X* adjust();
};
template<class T> void f(T* p) {
  T* p1 = p->alloc<200>();              // ill-formed: < means less than
  T* p2 = p->template alloc<200>();     // OK: < starts template argument list
  T::adjust<100>();                     // ill-formed: < means less than
  T::template adjust<100>();            // OK: < starts template argument list
}
end example
]
A name prefixed by the keyword template shall be a template-id or the name shall refer to a class template or an alias template.
[Note
:
The keyword template may not be applied to non-template members of class templates.
end note
]
[Note
:
As is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the -> or . is not dependent on a template-parameter, or the use does not appear in the scope of a template.
end note
]
[Example
:
template <class T> struct A {
  void f(int);
  template <class U> void f(U);
};

template <class T> void f(T t) {
  A<T> a;
  a.template f<>(t);                    // OK: calls template
  a.template f(t);                      // error: not a template-id
}

template <class T> struct B {
  template <class T2> struct C { };
};

// OK: T​::​template C names a class template:
template <class T, template <class X> class TT = T::template C> struct D { };
D<B<int> > db;
end example
]
A simple-template-id that names a class template specialization is a class-name.
A template-id that names an alias template specialization is a type-name.
A > that encloses the type-id of a dynamic_­cast, static_­cast, reinterpret_­cast or const_­cast, or which encloses the template-arguments of a subsequent template-id, is considered nested for the purpose of this description.

17.3 Template arguments [temp.arg]

There are three forms of template-argument, corresponding to the three forms of template-parameter: type, non-type and template.
The type and form of each template-argument specified in a template-id shall match the type and form specified for the corresponding parameter declared by the template in its template-parameter-list.
When the parameter declared by the template is a template parameter pack ([temp.variadic]), it will correspond to zero or more template-arguments.
[Example
:
template<class T> class Array {
  T* v;
  int sz;
public:
  explicit Array(int);
  T& operator[](int);
  T& elem(int i) { return v[i]; }
};

Array<int> v1(20);
typedef std::complex<double> dcomplex;  // std​::​complex is a standard library template
Array<dcomplex> v2(30);
Array<dcomplex> v3(40);

void bar() {
  v1[3] = 7;
  v2[3] = v3.elem(4) = dcomplex(7,8);
}
end example
]
In a template-argument, an ambiguity between a type-id and an expression is resolved to a type-id, regardless of the form of the corresponding template-parameter.137
[Example
:
template<class T> void f();
template<int I> void f();

void g() {
  f<int()>();       // int() is a type-id: call the first f()
}
end example
]
The name of a template-argument shall be accessible at the point where it is used as a template-argument.
[Note
:
If the name of the template-argument is accessible at the point where it is used as a template-argument, there is no further access restriction in the resulting instantiation where the corresponding template-parameter name is used.
end note
]
[Example
:
template<class T> class X {
  static T t;
};

class Y {
private:
  struct S { /* ... */ };
  X<S> x;           // OK: S is accessible
                    // X<Y​::​S> has a static member of type Y​::​S
                    // OK: even though Y​::​S is private
};

X<Y::S> y;          // error: S not accessible
end example
]
For a template-argument that is a class type or a class template, the template definition has no special access rights to the members of the template-argument.
[Example
:
template <template <class TT> class T> class A {
  typename T<int>::S s;
};

template <class U> class B {
private:
  struct S { /* ... */ };
};

A<B> b;             // ill-formed: A has no access to B​::​S
end example
]
When template argument packs or default template-arguments are used, a template-argument list can be empty.
In that case the empty <> brackets shall still be used as the template-argument-list.
[Example
:
template<class T = char> class String;
String<>* p;                    // OK: String<char>
String* q;                      // syntax error
template<class ... Elements> class Tuple;
Tuple<>* t;                     // OK: Elements is empty
Tuple* u;                       // syntax error
end example
]
An explicit destructor call ([class.dtor]) for an object that has a type that is a class template specialization may explicitly specify the template-arguments.
[Example
:
template<class T> struct A {
  ~A();
};
void f(A<int>* p, A<int>* q) {
  p->A<int>::~A();              // OK: destructor call
  q->A<int>::~A<int>();         // OK: destructor call
}
end example
]
If the use of a template-argument gives rise to an ill-formed construct in the instantiation of a template specialization, the program is ill-formed.
When the template in a template-id is an overloaded function template, both non-template functions in the overload set and function templates in the overload set for which the template-arguments do not match the template-parameters are ignored.
If none of the function templates have matching template-parameters, the program is ill-formed.
When a simple-template-id does not name a function, a default template-argument is implicitly instantiated ([temp.inst]) when the value of that default argument is needed.
[Example
:
template<typename T, typename U = int> struct S { };
S<bool>* p;         // the type of p is S<bool, int>*
The default argument for U is instantiated to form the type S<bool, int>*.
end example
]
A template-argument followed by an ellipsis is a pack expansion ([temp.variadic]).
There is no such ambiguity in a default template-argument because the form of the template-parameter determines the allowable forms of the template-argument.

17.3.1 Template type arguments [temp.arg.type]

A template-argument for a template-parameter which is a type shall be a type-id.
[Example
:
template <class T> class X { };
template <class T> void f(T t) { }
struct { } unnamed_obj;

void f() {
  struct A { };
  enum { e1 };
  typedef struct { } B;
  B b;
  X<A> x1;          // OK
  X<A*> x2;         // OK
  X<B> x3;          // OK
  f(e1);            // OK
  f(unnamed_obj);   // OK
  f(b);             // OK
}
end example
]
[Note
:
A template type argument may be an incomplete type ([basic.types]).
end note
]

17.3.2 Template non-type arguments [temp.arg.nontype]

If the type of a template-parameter contains a placeholder type ([dcl.spec.auto], [temp.param]), the deduced parameter type is determined from the type of the template-argument by placeholder type deduction ([dcl.type.auto.deduct]).
If a deduced parameter type is not permitted for a template-parameter declaration ([temp.param]), the program is ill-formed.
A template-argument for a non-type template-parameter shall be a converted constant expression ([expr.const]) of the type of the template-parameter.
For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):
[Note
:
If the template-argument represents a set of overloaded functions (or a pointer or member pointer to such), the matching function is selected from the set ([over.over]).
end note
]
[Example
:
template<const int* pci> struct X { /* ... */ };
int ai[10];
X<ai> xi;                       // array to pointer and qualification conversions

struct Y { /* ... */ };
template<const Y& b> struct Z { /* ... */ };
Y y;
Z<y> z;                         // no conversion, but note extra cv-qualification

template<int (&pa)[5]> struct W { /* ... */ };
int b[5];
W<b> w;                         // no conversion

void f(char);
void f(int);

template<void (*pf)(int)> struct A { /* ... */ };

A<&f> a;                        // selects f(int)

template<auto n> struct B { /* ... */ };
B<5> b1;                        // OK: template parameter type is int
B<'a'> b2;                      // OK: template parameter type is char
B<2.5> b3;                      // error: template parameter type cannot be double
end example
]
[Note
:
A string literal ([lex.string]) is not an acceptable template-argument.
[Example
:
template<class T, const char* p> class X {
  /* ... */
};

X<int, "Studebaker"> x1;        // error: string literal as template-argument

const char p[] = "Vivisectionist";
X<int,p> x2;                    // OK
end example
]
end note
]
[Note
:
The address of an array element or non-static data member is not an acceptable template-argument.
[Example
:
template<int* p> class X { };

int a[10];
struct S { int m; static int s; } s;

X<&a[2]> x3;                    // error: address of array element
X<&s.m> x4;                     // error: address of non-static member
X<&s.s> x5;                     // OK: address of static member
X<&S::s> x6;                    // OK: address of static member
end example
]
end note
]
[Note
:
A temporary object is not an acceptable template-argument when the corresponding template-parameter has reference type.
[Example
:
template<const int& CRI> struct B { /* ... */ };

B<1> b2;                        // error: temporary would be required for template argument

int c = 1;
B<c> b1;                        // OK
end example
]
end note
]

17.3.3 Template template arguments [temp.arg.template]

A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression.
When the template-argument names a class template, only primary class templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template parameter.
Any partial specializations ([temp.class.spec]) associated with the primary class template or primary variable template are considered when a specialization based on the template template-parameter is instantiated.
If a specialization is not visible at the point of instantiation, and it would have been selected had it been visible, the program is ill-formed, no diagnostic required.
[Example
:
template<class T> class A {     // primary template
  int x;
};
template<class T> class A<T*> { // partial specialization
  long x;
};
template<template<class U> class V> class C {
  V<int>  y;
  V<int*> z;
};
C<A> c;             // V<int> within C<A> uses the primary template, so c.y.x has type int
                    // V<int*> within C<A> uses the partial specialization, so c.z.x has type long
end example
]
A template-argument matches a template template-parameter P when P is at least as specialized as the template-argument A.
If P contains a parameter pack, then A also matches P if each of A's template parameters matches the corresponding template parameter in the template-parameter-list of P.
Two template parameters match if they are of the same kind (type, non-type, template), for non-type template-parameters, their types are equivalent ([temp.over.link]), and for template template-parameters, each of their corresponding template-parameters matches, recursively.
When P's template-parameter-list contains a template parameter pack ([temp.variadic]), the template parameter pack will match zero or more template parameters or template parameter packs in the template-parameter-list of A with the same type and form as the template parameter pack in P (ignoring whether those template parameters are template parameter packs).
[Example
:
template<class T> class A { /* ... */ };
template<class T, class U = T> class B { /* ... */ };
template<class ... Types> class C { /* ... */ };
template<auto n> class D { /* ... */ };
template<template<class> class P> class X { /* ... */ };
template<template<class ...> class Q> class Y { /* ... */ };
template<template<int> class R> class Z { /* ... */ };

X<A> xa;            // OK
X<B> xb;            // OK
X<C> xc;            // OK
Y<A> ya;            // OK
Y<B> yb;            // OK
Y<C> yc;            // OK
Z<D> zd;            // OK
end example
]
[Example
:
template <class T> struct eval;

template <template <class, class...> class TT, class T1, class... Rest>
struct eval<TT<T1, Rest...>> { };

template <class T1> struct A;
template <class T1, class T2> struct B;
template <int N> struct C;
template <class T1, int N> struct D;
template <class T1, class T2, int N = 17> struct E;

eval<A<int>> eA;                // OK: matches partial specialization of eval
eval<B<int, float>> eB;         // OK: matches partial specialization of eval
eval<C<17>> eC;                 // error: C does not match TT in partial specialization
eval<D<int, 17>> eD;            // error: D does not match TT in partial specialization
eval<E<int, float>> eE;         // error: E does not match TT in partial specialization
end example
]
A template template-parameter P is at least as specialized as a template template-argument A if, given the following rewrite to two function templates, the function template corresponding to P is at least as specialized as the function template corresponding to A according to the partial ordering rules for function templates ([temp.func.order]).
Given an invented class template X with the template parameter list of A (including default arguments):
  • Each of the two function templates has the same template parameters, respectively, as P or A.
  • Each function template has a single function parameter whose type is a specialization of X with template arguments corresponding to the template parameters from the respective function template where, for each template parameter PP in the template parameter list of the function template, a corresponding template argument AA is formed.
    If PP declares a parameter pack, then AA is the pack expansion PP... ([temp.variadic]); otherwise, AA is the id-expression PP.
If the rewrite produces an invalid type, then P is not at least as specialized as A.

17.4 Type equivalence [temp.type]

Two template-ids refer to the same class, function, or variable if
[Example
:
template<class E, int size> class buffer { /* ... */ };
buffer<char,2*512> x;
buffer<char,1024> y;
declares x and y to be of the same type, and
template<class T, void(*err_fct)()> class list { /* ... */ };
list<int,&error_handler1> x1;
list<int,&error_handler2> x2;
list<int,&error_handler2> x3;
list<char,&error_handler2> x4;
declares x2 and x3 to be of the same type.
Their type differs from the types of x1 and x4.
template<class T> struct X { };
template<class> struct Y { };
template<class T> using Z = Y<T>;
X<Y<int> > y;
X<Z<int> > z;
declares y and z to be of the same type.
end example
]
If an expression e is type-dependent ([temp.dep.expr]), decltype(e) denotes a unique dependent type.
Two such decltype-specifiers refer to the same type only if their expressions are equivalent ([temp.over.link]).
[Note
:
However, such a type may be aliased, e.g., by a typedef-name.
end note
]

17.5 Template declarations [temp.decls]

A template-id, that is, the template-name followed by a template-argument-list shall not be specified in the declaration of a primary template declaration.
[Example
:
template<class T1, class T2, int I> class A<T1, T2, I> { };     // error
template<class T1, int I> void sort<T1, I>(T1 data[I]);         // error
end example
]
[Note
:
However, this syntax is allowed in class template partial specializations ([temp.class.spec]).
end note
]
For purposes of name lookup and instantiation, default arguments and noexcept-specifiers of function templates and default arguments and noexcept-specifiers of member functions of class templates are considered definitions; each default argument or noexcept-specifier is a separate definition which is unrelated to the function template definition or to any other default arguments or noexcept-specifiers.
For the purpose of instantiation, the substatements of a constexpr if statement ([stmt.if]) are considered definitions.
Because an alias-declaration cannot declare a template-id, it is not possible to partially or explicitly specialize an alias template.

17.5.1 Class templates [temp.class]

A class template defines the layout and operations for an unbounded set of related types.
[Example
:
A single class template List might provide an unbounded set of class definitions: one class List<T> for every type T, each describing a linked list of elements of type T.
Similarly, a class template Array describing a contiguous, dynamic array might be defined like this:
template<class T> class Array {
  T* v;
  int sz;
public:
  explicit Array(int);
  T& operator[](int);
  T& elem(int i) { return v[i]; }
};
The prefix template<class T> specifies that a template is being declared and that a type-name T may be used in the declaration.
In other words, Array is a parameterized type with T as its parameter.
end example
]
When a member function, a member class, a member enumeration, a static data member or a member template of a class template is defined outside of the class template definition, the member definition is defined as a template definition in which the template-parameters are those of the class template.
The names of the template parameters used in the definition of the member may be different from the template parameter names used in the class template definition.
The template argument list following the class template name in the member definition shall name the parameters in the same order as the one used in the template parameter list of the member.
Each template parameter pack shall be expanded with an ellipsis in the template argument list.
[Example
:
template<class T1, class T2> struct A {
  void f1();
  void f2();
};

template<class T2, class T1> void A<T2,T1>::f1() { }    // OK
template<class T2, class T1> void A<T1,T2>::f2() { }    // error
template<class ... Types> struct B {
  void f3();
  void f4();
};

template<class ... Types> void B<Types ...>::f3() { }    // OK
template<class ... Types> void B<Types>::f4() { }        // error
end example
]
In a redeclaration, partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration ([dcl.type.elab]).

17.5.1.1 Member functions of class templates [temp.mem.func]

A member function of a class template may be defined outside of the class template definition in which it is declared.
[Example
:
template<class T> class Array {
  T* v;
  int sz;
public:
  explicit Array(int);
  T& operator[](int);
  T& elem(int i) { return v[i]; }
};
declares three function templates.
The subscript function might be defined like this:
template<class T> T& Array<T>::operator[](int i) {
  if (i<0 || sz<=i) error("Array: range error");
  return v[i];
}
end example
]
The template-arguments for a member function of a class template are determined by the template-arguments of the type of the object for which the member function is called.
[Example
:
The template-argument for Array<T>​::​operator[]() will be determined by the Array to which the subscripting operation is applied.
Array<int> v1(20);
Array<dcomplex> v2(30);

v1[3] = 7;                      // Array<int>​::​operator[]()
v2[3] = dcomplex(7,8);          // Array<dcomplex>​::​operator[]()
end example
]

17.5.1.2 Member classes of class templates [temp.mem.class]

A member class of a class template may be defined outside the class template definition in which it is declared.
[Note
:
The member class must be defined before its first use that requires an instantiation ([temp.inst]).
For example,
template<class T> struct A {
  class B;
};
A<int>::B* b1;                  // OK: requires A to be defined but not A​::​B
template<class T> class A<T>::B { };
A<int>::B  b2;                  // OK: requires A​::​B to be defined
end note
]

17.5.1.3 Static data members of class templates [temp.static]

A definition for a static data member or static data member template may be provided in a namespace scope enclosing the definition of the static member's class template.
[Example
:
template<class T> class X {
  static T s;
};
template<class T> T X<T>::s = 0;

struct limits {
  template<class T>
    static const T min;         // declaration
};

template<class T>
  const T limits::min = { };    // definition
end example
]
An explicit specialization of a static data member declared as an array of unknown bound can have a different bound from its definition, if any.
[Example
:
template <class T> struct A {
  static int i[];
};
template <class T> int A<T>::i[4];              // 4 elements
template <> int A<int>::i[] = { 1 };            // OK: 1 element
end example
]

17.5.1.4 Enumeration members of class templates [temp.mem.enum]

An enumeration member of a class template may be defined outside the class template definition.
[Example
:
template<class T> struct A {
  enum E : T;
};
A<int> a;
template<class T> enum A<T>::E : T { e1, e2 };
A<int>::E e = A<int>::e1;
end example
]

17.5.2 Member templates [temp.mem]

A template can be declared within a class or class template; such a template is called a member template.
A member template can be defined within or outside its class definition or class template definition.
A member template of a class template that is defined outside of its class template definition shall be specified with the template-parameters of the class template followed by the template-parameters of the member template.
[Example
:
template<class T> struct string {
  template<class T2> int compare(const T2&);
  template<class T2> string(const string<T2>& s) { /* ... */ }
};

template<class T> template<class T2> int string<T>::compare(const T2& s) {
}
end example
]
A local class of non-closure type shall not have member templates.
Access control rules (Clause [class.access]) apply to member template names.
A destructor shall not be a member template.
A non-template member function ([dcl.fct]) with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class.
When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied.
[Example
:
template <class T> struct A {
  void f(int);
  template <class T2> void f(T2);
};

template <> void A<int>::f(int) { }                 // non-template member function
template <> template <> void A<int>::f<>(int) { }   // member function template specialization

int main() {
  A<char> ac;
  ac.f(1);          // non-template
  ac.f('c');        // template
  ac.f<>(1);        // template
}
end example
]
A member function template shall not be virtual.
[Example
:
template <class T> struct AA {
  template <class C> virtual void g(C);     // error
  virtual void f();                         // OK
};
end example
]
A specialization of a member function template does not override a virtual function from a base class.
[Example
:
class B {
  virtual void f(int);
};

class D : public B {
  template <class T> void f(T); // does not override B​::​f(int)
  void f(int i) { f<>(i); }     // overriding function that calls the template instantiation
};
end example
]
A specialization of a conversion function template is referenced in the same way as a non-template conversion function that converts to the same type.
[Example
:
struct A {
  template <class T> operator T*();
};
template <class T> A::operator T*(){ return 0; }
template <> A::operator char*(){ return 0; }    // specialization
template A::operator void*();                   // explicit instantiation

int main() {
  A a;
  int* ip;
  ip = a.operator int*();       // explicit call to template operator A​::​operator int*()
}
end example
]
[Note
:
Because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates.
end note
]
A specialization of a conversion function template is not found by name lookup.
Instead, any conversion function templates visible in the context of the use are considered.
For each such operator, if argument deduction succeeds ([temp.deduct.conv]), the resulting specialization is used as if found by name lookup.
A using-declaration in a derived class cannot refer to a specialization of a conversion function template in a base class.
Overload resolution ([over.ics.rank]) and partial ordering ([temp.func.order]) are used to select the best conversion function among multiple specializations of conversion function templates and/or non-template conversion functions.

17.5.3 Variadic templates [temp.variadic]

A template parameter pack is a template parameter that accepts zero or more template arguments.
[Example
:
template<class ... Types> struct Tuple { };

Tuple<> t0;                     // Types contains no arguments
Tuple<int> t1;                  // Types contains one argument: int
Tuple<int, float> t2;           // Types contains two arguments: int and float
Tuple<0> error;                 // error: 0 is not a type
end example
]
A function parameter pack is a function parameter that accepts zero or more function arguments.
[Example
:
template<class ... Types> void f(Types ... args);

f();                            // OK: args contains no arguments
f(1);                           // OK: args contains one argument: int
f(2, 1.0);                      // OK: args contains two arguments: int and double
end example
]
A parameter pack is either a template parameter pack or a function parameter pack.
A pack expansion consists of a pattern and an ellipsis, the instantiation of which produces zero or more instantiations of the pattern in a list (described below).
The form of the pattern depends on the context in which the expansion occurs.
Pack expansions can occur in the following contexts:
[Example
:
template<class ... Types> void f(Types ... rest);
template<class ... Types> void g(Types ... rest) {
  f(&rest ...);     // “&rest ...” is a pack expansion; “&rest” is its pattern
}
end example
]
For the purpose of determining whether a parameter pack satisfies a rule regarding entities other than parameter packs, the parameter pack is considered to be the entity that would result from an instantiation of the pattern in which it appears.
A parameter pack whose name appears within the pattern of a pack expansion is expanded by that pack expansion.
An appearance of the name of a parameter pack is only expanded by the innermost enclosing pack expansion.
The pattern of a pack expansion shall name one or more parameter packs that are not expanded by a nested pack expansion; such parameter packs are called unexpanded parameter packs in the pattern.
All of the parameter packs expanded by a pack expansion shall have the same number of arguments specified.
An appearance of a name of a parameter pack that is not expanded is ill-formed.
[Example
:
template<typename...> struct Tuple {};
template<typename T1, typename T2> struct Pair {};

template<class ... Args1> struct zip {
  template<class ... Args2> struct with {
    typedef Tuple<Pair<Args1, Args2> ... > type;
  };
};

typedef zip<short, int>::with<unsigned short, unsigned>::type T1;
    // T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>>
typedef zip<short>::with<unsigned short, unsigned>::type T2;
    // error: different number of arguments specified for Args1 and Args2

template<class ... Args>
  void g(Args ... args) {                   // OK: Args is expanded by the function parameter pack args
    f(const_cast<const Args*>(&args)...);   // OK: “Args” and “args” are expanded
    f(5 ...);                               // error: pattern does not contain any parameter packs
    f(args);                                // error: parameter pack “args” is not expanded
    f(h(args ...) + args ...);              // OK: first “args” expanded within h,
                                            // second “args” expanded within f
  }
end example
]
The instantiation of a pack expansion that is neither a sizeof... expression nor a fold-expression produces a list , where N is the number of elements in the pack expansion parameters.
Each is generated by instantiating the pattern and replacing each pack expansion parameter with its ith element.
Such an element, in the context of the instantiation, is interpreted as follows:
  • if the pack is a template parameter pack, the element is a template parameter ([temp.param]) of the corresponding kind (type or non-type) designating the type or value from the template argument; otherwise,
  • if the pack is a function parameter pack, the element is an id-expression designating the function parameter that resulted from the instantiation of the pattern where the pack is declared.
All of the become elements in the enclosing list.
[Note
:
The variety of list varies with the context: expression-list, base-specifier-list, template-argument-list, etc.
end note
]
When N is zero, the instantiation of the expansion produces an empty list.
Such an instantiation does not alter the syntactic interpretation of the enclosing construct, even in cases where omitting the list entirely would otherwise be ill-formed or would result in an ambiguity in the grammar.
[Example
:
template<class... T> struct X : T... { };
template<class... T> void f(T... values) {
  X<T...> x(values...);
}

template void f<>();    // OK: X<> has no base classes
                        // x is a variable of type X<> that is value-initialized
end example
]
The instantiation of a sizeof... expression ([expr.sizeof]) produces an integral constant containing the number of elements in the parameter pack it expands.
The instantiation of a fold-expression produces:
  • (( op ) op ) op for a unary left fold,
  • op ( op ( op )) for a unary right fold,
  • (((E op ) op ) op ) op for a binary left fold, and
  • op ( op ( op ( op E))) for a binary right fold.
In each case, op is the fold-operator, N is the number of elements in the pack expansion parameters, and each is generated by instantiating the pattern and replacing each pack expansion parameter with its ith element.
For a binary fold-expression, E is generated by instantiating the cast-expression that did not contain an unexpanded parameter pack.
[Example
:
template<typename ...Args>
  bool all(Args ...args) { return (... && args); }

bool b = all(true, true, true, false);
Within the instantiation of all, the returned expression expands to ((true && true) && true) && false, which evaluates to false.
end example
]
If N is zero for a unary fold-expression, the value of the expression is shown in Table 14; if the operator is not listed in Table 14, the instantiation is ill-formed.
Table 14 — Value of folding empty sequences
Operator
Value when parameter pack is empty
&&
true
||
false
,
void()

17.5.4 Friends [temp.friend]

A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or a non-template function or class.
For a friend function declaration that is not a template declaration:
  • if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise,
  • if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, the friend declaration refers to that function, otherwise,
  • if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template ([temp.deduct.decl]), otherwise,
  • the name shall be an unqualified-id that declares (or redeclares) a non-template function.
[Example
:
template<class T> class task;
template<class T> task<T>* preempt(task<T>*);

template<class T> class task {
  friend void next_time();
  friend void process(task<T>*);
  friend task<T>* preempt<T>(task<T>*);
  template<class C> friend int func(C);

  friend class task<int>;
  template<class P> friend class frd;
};
Here, each specialization of the task class template has the function next_­time as a friend; because process does not have explicit template-arguments, each specialization of the task class template has an appropriately typed function process as a friend, and this friend is not a function template specialization; because the friend preempt has an explicit template-argument T, each specialization of the task class template has the appropriate specialization of the function template preempt as a friend; and each specialization of the task class template has all specializations of the function template func as friends.
Similarly, each specialization of the task class template has the class template specialization task<int> as a friend, and has all specializations of the class template frd as friends.
end example
]
A friend template may be declared within a class or class template.
A friend function template may be defined within a class or class template, but a friend class template may not be defined in a class or class template.
In these cases, all specializations of the friend class or friend function template are friends of the class or class template granting friendship.
[Example
:
class A {
  template<class T> friend class B;                 // OK
  template<class T> friend void f(T){ /* ... */ }   // OK
};
end example
]
A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated ([temp.inst]), partially specialized ([temp.class.spec]) or explicitly specialized ([temp.expl.spec]), are friends of the class containing the template friend declaration.
[Example
:
class X {
  template<class T> friend struct A;
  class Y { };
};

template<class T> struct A { X::Y ab; };            // OK
template<class T> struct A<T*> { X::Y ab; };        // OK
end example
]
A member of a class template may be declared to be a friend of a non-template class.
In this case, the corresponding member of every specialization of the primary class template and class template partial specializations thereof is a friend of the class granting friendship.
For explicit specializations and specializations of partial specializations, the corresponding member is the member (if any) that has the same name, kind (type, function, class template, or function template), template parameters, and signature as the member of the class template instantiation that would otherwise have been generated.
[Example
:
template<class T> struct A {
  struct B { };
  void f();
  struct D {
    void g();
  };
};
template<> struct A<int> {
  struct B { };
  int f();
  struct D {
    void g();
  };
};

class C {
  template<class T> friend struct A<T>::B;      // grants friendship to A<int>​::​B even though
                                                // it is not a specialization of A<T>​::​B
  template<class T> friend void A<T>::f();      // does not grant friendship to A<int>​::​f()
                                                // because its return type does not match
  template<class T> friend void A<T>::D::g();   // does not grant friendship to A<int>​::​D​::​g()
                                                // because A<int>​::​D is not a specialization of A<T>​::​D
};
end example
]
[Note
:
A friend declaration may first declare a member of an enclosing namespace scope ([temp.inject]).
end note
]
A friend template shall not be declared in a local class.
Friend declarations shall not declare partial specializations.
[Example
:
template<class T> class A { };
class X {
  template<class T> friend class A<T*>;         // error
};
end example
]
When a friend declaration refers to a specialization of a function template, the function parameter declarations shall not include default arguments, nor shall the inline specifier be used in such a declaration.

17.5.5 Class template partial specializations [temp.class.spec]

A primary class template declaration is one in which the class template name is an identifier.
A template declaration in which the class template name is a simple-template-id is a partial specialization of the class template named in the simple-template-id.
A partial specialization of a class template provides an alternative definition of the template that is used instead of the primary definition when the arguments in a specialization match those given in the partial specialization ([temp.class.spec.match]).
The primary template shall be declared before any specializations of that template.
A partial specialization shall be declared before the first use of a class template specialization that would make use of the partial specialization as the result of an implicit or explicit instantiation in every translation unit in which such a use occurs; no diagnostic is required.
Each class template partial specialization is a distinct template and definitions shall be provided for the members of a template partial specialization ([temp.class.spec.mfunc]).
[Example
:
template<class T1, class T2, int I> class A             { };
template<class T, int I>            class A<T, T*, I>   { };
template<class T1, class T2, int I> class A<T1*, T2, I> { };
template<class T>                   class A<int, T*, 5> { };
template<class T1, class T2, int I> class A<T1, T2*, I> { };
The first declaration declares the primary (unspecialized) class template.
The second and subsequent declarations declare partial specializations of the primary template.
end example
]
The template parameters are specified in the angle bracket enclosed list that immediately follows the keyword template.
For partial specializations, the template argument list is explicitly written immediately following the class template name.
For primary templates, this list is implicitly described by the template parameter list.
Specifically, the order of the template arguments is the sequence in which they appear in the template parameter list.
[Example
:
The template argument list for the primary template in the example above is <T1, T2, I>.
end example
]
[Note
:
The template argument list shall not be specified in the primary template declaration.
For example,
template<class T1, class T2, int I>
class A<T1, T2, I> { };                         // error
end note
]
A class template partial specialization may be declared in any scope in which the corresponding primary template may be defined ([namespace.memdef], [class.mem], [temp.mem]).
[Example
:
template<class T> struct A {
  struct C {
    template<class T2> struct B { };
    template<class T2> struct B<T2**> { };      // partial specialization #1
  };
};

// partial specialization of A<T>​::​C​::​B<T2>
template<class T> template<class T2>
  struct A<T>::C::B<T2*> { };                   // #2

A<short>::C::B<int*> absip;                     // uses partial specialization #2
end example
]
Partial specialization declarations themselves are not found by name lookup.
Rather, when the primary template name is used, any previously-declared partial specializations of the primary template are also considered.
One consequence is that a using-declaration which refers to a class template does not restrict the set of partial specializations which may be found through the using-declaration.
[Example
:
namespace N {
  template<class T1, class T2> class A { };     // primary template
}

using N::A;                                     // refers to the primary template

namespace N {
  template<class T> class A<T, T*> { };         // partial specialization
}

A<int,int*> a;      // uses the partial specialization, which is found through the using-declaration
                    // which refers to the primary template
end example
]
A non-type argument is non-specialized if it is the name of a non-type parameter.
All other non-type arguments are specialized.
Within the argument list of a class template partial specialization, the following restrictions apply:
  • The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization.
    [Example
    :
    template <class T, T t> struct C {};
    template <class T> struct C<T, 1>;              // error
    
    template< int X, int (*array_ptr)[X] > class A {};
    int array[5];
    template< int X > class A<X,&array> { };        // error
    
    end example
    ]
  • The specialization shall be more specialized than the primary template ([temp.class.order]).
  • The template parameter list of a specialization shall not contain default template argument values.138
  • An argument shall not contain an unexpanded parameter pack.
    If an argument is a pack expansion ([temp.variadic]), it shall be the last argument in the template argument list.
There is no way in which they could be used.

17.5.5.1 Matching of class template partial specializations [temp.class.spec.match]

When a class template is used in a context that requires an instantiation of the class, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations.
This is done by matching the template arguments of the class template specialization with the template argument lists of the partial specializations.
  • If exactly one matching specialization is found, the instantiation is generated from that specialization.
  • If more than one matching specialization is found, the partial order rules ([temp.class.order]) are used to determine whether one of the specializations is more specialized than the others.
    If none of the specializations is more specialized than all of the other matching specializations, then the use of the class template is ambiguous and the program is ill-formed.
  • If no matches are found, the instantiation is generated from the primary template.
A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list ([temp.deduct]).
[Example
:
template<class T1, class T2, int I> class A             { };    // #1
template<class T, int I>            class A<T, T*, I>   { };    // #2
template<class T1, class T2, int I> class A<T1*, T2, I> { };    // #3
template<class T>                   class A<int, T*, 5> { };    // #4
template<class T1, class T2, int I> class A<T1, T2*, I> { };    // #5

A<int, int, 1>   a1;            // uses #1
A<int, int*, 1>  a2;            // uses #2, T is int, I is 1
A<int, char*, 5> a3;            // uses #4, T is char
A<int, char*, 1> a4;            // uses #5, T1 is int, T2 is char, I is 1
A<int*, int*, 2> a5;            // ambiguous: matches #3 and #5
end example
]
If the template arguments of a partial specialization cannot be deduced because of the structure of its template-parameter-list and the template-id, the program is ill-formed.
[Example
:
template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {};     // error

template <int I> struct A<I, I> {};         // OK

template <int I, int J, int K> struct B {};
template <int I> struct B<I, I*2, 2> {};    // OK
end example
]
In a type name that refers to a class template specialization, (e.g., A<int, int, 1>) the argument list shall match the template parameter list of the primary template.
The template arguments of a specialization are deduced from the arguments of the primary template.

17.5.5.2 Partial ordering of class template specializations [temp.class.order]

For two class template partial specializations, the first is more specialized than the second if, given the following rewrite to two function templates, the first function template is more specialized than the second according to the ordering rules for function templates ([temp.func.order]):
  • Each of the two function templates has the same template parameters as the corresponding partial specialization.
  • Each function template has a single function parameter whose type is a class template specialization where the template arguments are the corresponding template parameters from the function template for each template argument in the template-argument-list of the simple-template-id of the partial specialization.
[Example
:
template<int I, int J, class T> class X { };
template<int I, int J>          class X<I, J, int> { };         // #1
template<int I>                 class X<I, I, int> { };         // #2

template<int I0, int J0> void f(X<I0, J0, int>);                // A
template<int I0>         void f(X<I0, I0, int>);                // B

template <auto v>    class Y { };
template <auto* p>   class Y<p> { };                            // #3
template <auto** pp> class Y<pp> { };                           // #4

template <auto* p0>   void g(Y<p0>);                            // C
template <auto** pp0> void g(Y<pp0>);                           // D
According to the ordering rules for function templates, the function template B is more specialized than the function template A and the function template D is more specialized than the function template C.
Therefore, the partial specialization #2 is more specialized than the partial specialization #1 and the partial specialization #4 is more specialized than the partial specialization #3.
end example
]

17.5.5.3 Members of class template specializations [temp.class.spec.mfunc]

The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization.
The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization.
A class template specialization is a distinct template.
The members of the class template partial specialization are unrelated to the members of the primary template.
Class template partial specialization members that are used in a way that requires a definition shall be defined; the definitions of members of the primary template are never used as definitions for members of a class template partial specialization.
An explicit specialization of a member of a class template partial specialization is declared in the same way as an explicit specialization of the primary template.
[Example
:
// primary class template
template<class T, int I> struct A {
  void f();
};

// member of primary class template
template<class T, int I> void A<T,I>::f() { }

// class template partial specialization
template<class T> struct A<T,2> {
  void f();
  void g();
  void h();
};

// member of class template partial specialization
template<class T> void A<T,2>::g() { }

// explicit specialization
template<> void A<char,2>::h() { }

int main() {
  A<char,0> a0;
  A<char,2> a2;
  a0.f();           // OK, uses definition of primary template's member
  a2.g();           // OK, uses definition of partial specialization's member
  a2.h();           // OK, uses definition of explicit specialization's member
  a2.f();           // ill-formed, no definition of f for A<T,2>; the primary template is not used here
}
end example
]
If a member template of a class template is partially specialized, the member template partial specializations are member templates of the enclosing class template; if the enclosing class template is instantiated ([temp.inst], [temp.explicit]), a declaration for every member template partial specialization is also instantiated as part of creating the members of the class template specialization.
If the primary member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of the member template are ignored for this specialization of the enclosing class template.
If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the primary member template and its other partial specializations are still considered for this specialization of the enclosing class template.
[Example
:
template<class T> struct A {
  template<class T2> struct B {};                     // #1
  template<class T2> struct B<T2*> {};                // #2
};

template<> template<class T2> struct A<short>::B {};  // #3

A<char>::B<int*>  abcip;  // uses #2
A<short>::B<int*> absip;  // uses #3
A<char>::B<int>  abci;    // uses #1
end example
]

17.5.6 Function templates [temp.fct]

A function template defines an unbounded set of related functions.
[Example
:
A family of sort functions might be declared like this:
template<class T> class Array { };
template<class T> void sort(Array<T>&);
end example
]
A function template can be overloaded with other function templates and with non-template functions ([dcl.fct]).
A non-template function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.139
That is, declarations of non-template functions do not merely guide overload resolution of function template specializations with the same name.
If such a non-template function is odr-used ([basic.def.odr]) in a program, it must be defined; it will not be implicitly instantiated using the function template definition.

17.5.6.2 Partial ordering of function templates [temp.func.order]

If a function template is overloaded, the use of a function template specialization might be ambiguous because template argument deduction ([temp.deduct]) may associate the function template specialization with more than one function template declaration.
Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template specialization refers:
Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type.
The deduction process determines whether one of the templates is more specialized than the other.
If so, the more specialized template is the one chosen by the partial ordering process.
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs ([temp.variadic]) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.
[Note
:
The type replacing the placeholder in the type of the value synthesized for a non-type template parameter is also a unique synthesized type.
end note
]
If only one of the function templates M is a non-static member of some class A, M is considered to have a new first parameter inserted in its function parameter list.
Given cv as the cv-qualifiers of M (if any), the new parameter is of type “rvalue reference to cv A” if the optional ref-qualifier of M is && or if M has no ref-qualifier and the first parameter of the other template has rvalue reference type.
Otherwise, the new parameter is of type “lvalue reference to cv A.
[Note
:
This allows a non-static member to be ordered with respect to a non-member function and for the results to be equivalent to the ordering of two equivalent non-members.
end note
]
[Example
:
struct A { };
template<class T> struct B {
  template<class R> int operator*(R&);              // #1
};

template<class T, class R> int operator*(T&, R&);   // #2

// The declaration of B​::​operator* is transformed into the equivalent of
// template<class R> int operator*(B<A>&, R&);      // #1a

int main() {
  A a;
  B<A> b;
  b * a;                                            // calls #1a
}
end example
]
Using the transformed function template's function type, perform type deduction against the other template as described in [temp.deduct.partial].
[Example
:
template<class T> struct A { A(); };

template<class T> void f(T);
template<class T> void f(T*);
template<class T> void f(const T*);

template<class T> void g(T);
template<class T> void g(T&);

template<class T> void h(const T&);
template<class T> void h(A<T>&);

void m() {
  const int* p;
  f(p);             // f(const T*) is more specialized than f(T) or f(T*)
  float x;
  g(x);             // ambiguous: g(T) or g(T&)
  A<int> z;
  h(z);             // overload resolution selects h(A<T>&)
  const A<int> z2;
  h(z2);            // h(const T&) is called because h(A<T>&) is not callable
}
end example
]
[Note
:
Since partial ordering in a call context considers only parameters for which there are explicit call arguments, some parameters are ignored (namely, function parameter packs, parameters with default arguments, and ellipsis parameters).
[Example
:
template<class T> void f(T);                            // #1
template<class T> void f(T*, int=1);                    // #2
template<class T> void g(T);                            // #3
template<class T> void g(T*, ...);                      // #4
int main() {
  int* ip;
  f(ip);                                                // calls #2
  g(ip);                                                // calls #4
}
end example
]
[Example
:
template<class T, class U> struct A { };

template<class T, class U> void f(U, A<U, T>* p = 0);   // #1
template<         class U> void f(U, A<U, U>* p = 0);   // #2
template<class T         > void g(T, T = T());          // #3
template<class T, class... U> void g(T, U ...);         // #4

void h() {
  f<int>(42, (A<int, int>*)0);                          // calls #2
  f<int>(42);                                           // error: ambiguous
  g(42);                                                // error: ambiguous
}
end example
]
[Example
:
template<class T, class... U> void f(T, U...);          // #1
template<class T            > void f(T);                // #2
template<class T, class... U> void g(T*, U...);         // #3
template<class T            > void g(T);                // #4

void h(int i) {
  f(&i);                                                // error: ambiguous
  g(&i);                                                // OK: calls #3
}
end example
]
end note
]

17.5.7 Alias templates [temp.alias]

An alias template is a name for a family of types.
The name of the alias template is a template-name.
When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.
[Note
:
An alias template name is never deduced.
end note
]
[Example
:
template<class T> struct Alloc { /* ... */ };
template<class T> using Vec = vector<T, Alloc<T>>;
Vec<int> v;         // same as vector<int, Alloc<int>> v;

template<class T>
  void process(Vec<T>& v)
  { /* ... */ }

template<class T>
  void process(vector<T, Alloc<T>>& w)
  { /* ... */ }     // error: redefinition

template<template<class> class TT>
  void f(TT<int>);

f(v);               // error: Vec not deduced

template<template<class,class> class TT>
  void g(TT<int, Alloc<int>>);
g(v);               // OK: TT = vector
end example
]
However, if the template-id is dependent, subsequent template argument substitution still applies to the template-id.
[Example
:
template<typename...> using void_t = void;
template<typename T> void_t<typename T::foo> f();
f<int>();           // error, int does not have a nested type foo
end example
]
The type-id in an alias template declaration shall not refer to the alias template being declared.
The type produced by an alias template specialization shall not directly or indirectly make use of that specialization.
[Example
:
template <class T> struct A;
template <class T> using B = typename A<T>::U;
template <class T> struct A {
  typedef B<T> U;
};
B<short> b;         // error: instantiation of B<short> uses own type via A<short>​::​U
end example
]

17.6 Name resolution [temp.res]

Three kinds of names can be used within a template definition:
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
[Example
:
// no B declared here

class X;

template<class T> class Y {
  class Z;                      // forward declaration of member class

  void f() {
    X* a1;                      // declare pointer to X
    T* a2;                      // declare pointer to T
    Y* a3;                      // declare pointer to Y<T>
    Z* a4;                      // declare pointer to Z
    typedef typename T::A TA;
    TA* a5;                     // declare pointer to T's A
    typename T::A* a6;          // declare pointer to T's A
    T::A* a7;                   // T​::​A is not a type name:
                                // multiplication of T​::​A by a7; ill-formed, no visible declaration of a7
    B* a8;                      // B is not a type name:
                                // multiplication of B by a8; ill-formed, no visible declarations of B and a8
  }
};
end example
]
When a qualified-id is intended to refer to a type that is not a member of the current instantiation ([temp.dep.type]) and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword typename, forming a typename-specifier.
If the qualified-id in a typename-specifier does not denote a type or a class template, the program is ill-formed.
If a specialization of a template is instantiated for a set of template-arguments such that the qualified-id prefixed by typename does not denote a type or a class template, the specialization is ill-formed.
The usual qualified name lookup ([basic.lookup.qual]) is used to find the qualified-id even in the presence of typename.
[Example
:
struct A {
  struct X { };
  int X;
};
struct B {
  struct X { };
};
template<class T> void f(T t) {
  typename T::X x;
}
void foo() {
  A a;
  B b;
  f(b);             // OK: T​::​X refers to B​::​X
  f(a);             // error: T​::​X refers to the data member A​::​X not the struct A​::​X
}
end example
]
A qualified name used as the name in a class-or-decltype or an elaborated-type-specifier is implicitly assumed to name a type, without the use of the typename keyword.
In a nested-name-specifier that immediately contains a nested-name-specifier that depends on a template parameter, the identifier or simple-template-id is implicitly assumed to name a type, without the use of the typename keyword.
[Note
:
The typename keyword is not permitted by the syntax of these constructs.
end note
]
If, for a given set of template arguments, a specialization of a template is instantiated that refers to a qualified-id that denotes a type or a class template, and the qualified-id refers to a member of an unknown specialization, the qualified-id shall either be prefixed by typename or shall be used in a context in which it implicitly names a type as described above.
[Example
:
template <class T> void f(int i) {
  T::x * i;         // T​::​x must not be a type
}

struct Foo {
  typedef int x;
};

struct Bar {
  static int const x = 5;
};

int main() {
  f<Bar>(1);        // OK
  f<Foo>(1);        // error: Foo​::​x is a type
}
end example
]
Within the definition of a class template or within the definition of a member of a class template following the declarator-id, the keyword typename is not required when referring to the name of a previously declared member of the class template that declares a type or a class template.
[Note
:
Such names can be found using unqualified name lookup ([basic.lookup.unqual]), class member lookup ([class.qual]) into the current instantiation ([temp.dep.type]), or class member access expression lookup ([basic.lookup.classref]) when the type of the object expression is the current instantiation ([temp.dep.expr]).
end note
]
[Example
:
template<class T> struct A {
  typedef int B;
  B b;              // OK, no typename required
};
end example
]
Knowing which names are type names allows the syntax of every template to be checked.
The program is ill-formed, no diagnostic required, if:
  • no valid specialization can be generated for a template or a substatement of a constexpr if statement ([stmt.if]) within a template and the template is not instantiated, or
  • every valid specialization of a variadic template requires an empty template parameter pack, or
  • a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter, or
  • the interpretation of such a construct in the hypothetical instantiation is different from the interpretation of the corresponding construct in any actual instantiation of the template.
    [Note
    :
    This can happen in situations including the following:
    • a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is performed, or
    • lookup for a name in the template definition found a using-declaration, but the lookup in the corresponding scope in the instantiation does not find any declarations because the using-declaration was a pack expansion and the corresponding pack is empty, or
    • an instantiation uses a default argument or default template argument that had not been defined at the point at which the template was defined, or
    • constant expression evaluation ([expr.const]) within the template instantiation uses
      • the value of a const object of integral or unscoped enumeration type or
      • the value of a constexpr object or
      • the value of a reference or
      • the definition of a constexpr function,
      and that entity was not defined when the template was defined, or
    • a class template specialization or variable template specialization that is specified by a non-dependent simple-template-id is used by the template, and either it is instantiated from a partial specialization that was not defined when the template was defined or it names an explicit specialization that was not declared when the template was defined.
    end note
    ]
Otherwise, no diagnostic shall be issued for a template for which a valid specialization can be generated.
[Note
:
If a template is instantiated, errors will be diagnosed according to the other rules in this International Standard.
Exactly when these errors are diagnosed is a quality of implementation issue.
end note
]
[Example
:
int j;
template<class T> class X {
  void f(T t, int i, char* p) {
    t = i;          // diagnosed if X​::​f is instantiated, and the assignment to t is an error
    p = i;          // may be diagnosed even if X​::​f is not instantiated
    p = j;          // may be diagnosed even if X​::​f is not instantiated
  }
  void g(T t) {
    +;              // may be diagnosed even if X​::​g is not instantiated
  }
};

template<class... T> struct A {
  void operator++(int, T... t);                     // error: too many parameters
};
template<class... T> union X : T... { };            // error: union with base class
template<class... T> struct A : T...,  T... { };    // error: duplicate base class
end example
]
When looking for the declaration of a name used in a template definition, the usual lookup rules ([basic.lookup.unqual], [basic.lookup.argdep]) are used for non-dependent names.
The lookup of names dependent on the template parameters is postponed until the actual template argument is known ([temp.dep]).
[Example
:
#include <iostream>
using namespace std;

template<class T> class Set {
  T* p;
  int cnt;
public:
  Set();
  Set<T>(const Set<T>&);
  void printall() {
    for (int i = 0; i<cnt; i++)
      cout << p[i] << '\n';
  }
};
in the example, i is the local variable i declared in printall, cnt is the member cnt declared in Set, and cout is the standard output stream declared in iostream.
However, not every declaration can be found this way; the resolution of some names must be postponed until the actual template-arguments are known.
For example, even though the name operator<< is known within the definition of printall() and a declaration of it can be found in <iostream>, the actual declaration of operator<< needed to print p[i] cannot be known until it is known what type T is ([temp.dep]).
end example
]
If a name does not depend on a template-parameter (as defined in [temp.dep]), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition; the name is bound to the declaration (or declarations) found at that point and this binding is not affected by declarations that are visible at the point of instantiation.
[Example
:
void f(char);

template<class T> void g(T t) {
  f(1);             // f(char)
  f(T(1));          // dependent
  f(t);             // dependent
  dd++;             // not dependent; error: declaration for dd not found
}

enum E { e };
void f(E);

double dd;
void h() {
  g(e);             // will cause one call of f(char) followed by two calls of f(E)
  g('a');           // will cause three calls of f(char)
}
end example
]
[Note
:
For purposes of name lookup, default arguments and noexcept-specifiers of function templates and default arguments and noexcept-specifiers of member functions of class templates are considered definitions ([temp.decls]).
end note
]

17.6.1 Locally declared names [temp.local]

Like normal (non-template) classes, class templates have an injected-class-name (Clause [class]).
The injected-class-name can be used as a template-name or a type-name.
When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself.
Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.
Within the scope of a class template specialization or partial specialization, when the injected-class-name is used as a type-name, it is equivalent to the template-name followed by the template-arguments of the class template specialization or partial specialization enclosed in <>.
[Example
:
template<template<class> class T> class A { };
template<class T> class Y;
template<> class Y<int> {
  Y* p;                               // meaning Y<int>
  Y<char>* q;                         // meaning Y<char>
  A<Y>* a;                            // meaning A<​::​Y>
  class B {
    template<class> friend class Y;   // meaning ​::​Y
  };
};
end example
]
The injected-class-name of a class template or class template specialization can be used either as a template-name or a type-name wherever it is in scope.
[Example
:
template <class T> struct Base {
  Base* p;
};

template <class T> struct Derived: public Base<T> {
  typename Derived::Base* p;    // meaning Derived​::​Base<T>
};

template<class T, template<class> class U = T::template Base> struct Third { };
Third<Base<int> > t;            // OK: default argument uses injected-class-name as a template
end example
]
A lookup that finds an injected-class-name ([class.member.lookup]) can result in an ambiguity in certain cases (for example, if it is found in more than one base class).
If all of the injected-class-names that are found refer to specializations of the same class template, and if the name is used as a template-name, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous.
[Example
:
template <class T> struct Base { };
template <class T> struct Derived: Base<int>, Base<char> {
  typename Derived::Base b;             // error: ambiguous
  typename Derived::Base<double> d;     // OK
};
end example
]
When the normal name of the template (i.e., the name from the enclosing scope, not the injected-class-name) is used, it always refers to the class template itself and not a specialization of the template.
[Example
:
template<class T> class X {
  X* p;             // meaning X<T>
  X<T>* p2;
  X<int>* p3;
  ::X* p4;          // error: missing template argument list
                    // ​::​X does not refer to the injected-class-name
};
end example
]
A template-parameter shall not be redeclared within its scope (including nested scopes).
A template-parameter shall not have the same name as the template name.
[Example
:
template<class T, int i> class Y {
  int T;            // error: template-parameter redeclared
  void f() {
    char T;         // error: template-parameter redeclared
  }
};

template<class X> class X;      // error: template-parameter redeclared
end example
]
In the definition of a member of a class template that appears outside of the class template definition, the name of a member of the class template hides the name of a template-parameter of any enclosing class templates (but not a template-parameter of the member if the member is a class or function template).
[Example
:
template<class T> struct A {
  struct B { /* ... */ };
  typedef void C;
  void f();
  template<class U> void g(U);
};

template<class B> void A<B>::f() {
  B b;              // A's B, not the template parameter
}

template<class B> template<class C> void A<B>::g(C) {
  B b;              // A's B, not the template parameter
  C c;              // the template parameter C, not A's C
}
end example
]
In the definition of a member of a class template that appears outside of the namespace containing the class template definition, the name of a template-parameter hides the name of a member of this namespace.
[Example
:
namespace N {
  class C { };
  template<class T> class B {
    void f(T);
  };
}
template<class C> void N::B<C>::f(C) {
  C b;              // C is the template parameter, not N​::​C
}
end example
]
In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each non-dependent base class ([temp.dep.type]), if the name of the base class or the name of a member of the base class is the same as the name of a template-parameter, the base class name or member name hides the template-parameter name ([basic.scope.hiding]).
[Example
:
struct A {
  struct B { /* ... */ };
  int a;
  int Y;
};

template<class B, class a> struct X : A {
  B b;              // A's B
  a b;              // error: A's a isn't a type name
};
end example
]

17.6.2 Dependent names [temp.dep]

Inside a template, some constructs have semantics which may differ from one instantiation to another.
Such a construct depends on the template parameters.
In particular, types and expressions may depend on the type and/or value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names.
An expressions may be type-dependent (that is, its type may depend on a template parameter) or value-dependent (that is, its value when evaluated as a constant expression ([expr.const]) may depend on a template parameter) as described in this subclause.
In an expression of the form:
If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name.
Such names are unbound and are looked up at the point of the template instantiation ([temp.point]) in both the context of the template definition and the context of the point of instantiation.
[Example
:
template<class T> struct X : B<T> {
  typename T::A* pa;
  void f(B<T>* pb) {
    static int i = B<T>::i;
    pb->j++;
  }
};
the base class name B<T>, the type name T​::​A, the names B<T>​::​i and pb->j explicitly depend on the template-parameter.
end example
]
In the definition of a class or class template, the scope of a dependent base class ([temp.dep.type]) is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
[Example
:
typedef double A;
template<class T> class B {
  typedef int A;
};
template<class T> struct X : B<T> {
  A a;              // a has type double
};
The type name A in the definition of X<T> binds to the typedef name defined in the global namespace scope, not to the typedef name defined in the base class B<T>.
end example
]
[Example
:
struct A {
  struct B { /* ... */ };
  int a;
  int Y;
};

int a;

template<class T> struct Y : T {
  struct B { /* ... */ };
  B b;                          // The B defined in Y
  void f(int i) { a = i; }      // ​::​a
  Y* p;                         // Y<T>
};

Y<A> ya;
The members A​::​B, A​::​a, and A​::​Y of the template argument A do not affect the binding of names in Y<A>.
end example
]

17.6.2.1 Dependent types [temp.dep.type]

A name refers to the current instantiation if it is
  • in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the injected-class-name (Clause [class]) of the class template or nested class,
  • in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of the primary template (as described below) enclosed in <> (or an equivalent template alias specialization),
  • in the definition of a nested class of a class template, the name of the nested class referenced as a member of the current instantiation, or
  • in the definition of a partial specialization or a member of a partial specialization, the name of the class template followed by the template argument list of the partial specialization enclosed in <> (or an equivalent template alias specialization).
    If the nth template parameter is a parameter pack, the nth template argument is a pack expansion ([temp.variadic]) whose pattern is the name of the parameter pack.
The template argument list of a primary template is a template argument list in which the nth template argument has the value of the nth template parameter of the class template.
If the nth template parameter is a template parameter pack ([temp.variadic]), the nth template argument is a pack expansion ([temp.variadic]) whose pattern is the name of the template parameter pack.
A template argument that is equivalent to a template parameter (i.e., has the same constant value or the same type as the template parameter) can be used in place of that template parameter in a reference to the current instantiation. In the case of a non-type template argument, the argument must have been given the value of the template parameter and not an expression in which the template parameter appears as a subexpression.
[Example
:
template <class T> class A {
  A* p1;                        // A is the current instantiation
  A<T>* p2;                     // A<T> is the current instantiation
  A<T*> p3;                     // A<T*> is not the current instantiation
  ::A<T>* p4;                   // ​::​A<T> is the current instantiation
  class B {
    B* p1;                      // B is the current instantiation
    A<T>::B* p2;                // A<T>​::​B is the current instantiation
    typename A<T*>::B* p3;      // A<T*>​::​B is not the current instantiation
  };
};

template <class T> class A<T*> {
  A<T*>* p1;                    // A<T*> is the current instantiation
  A<T>* p2;                     // A<T> is not the current instantiation
};

template <class T1, class T2, int I> struct B {
  B<T1, T2, I>* b1;             // refers to the current instantiation
  B<T2, T1, I>* b2;             // not the current instantiation
  typedef T1 my_T1;
  static const int my_I = I;
  static const int my_I2 = I+0;
  static const int my_I3 = my_I;
  B<my_T1, T2, my_I>* b3;       // refers to the current instantiation
  B<my_T1, T2, my_I2>* b4;      // not the current instantiation
  B<my_T1, T2, my_I3>* b5;      // refers to the current instantiation
};
end example
]
A dependent base class is a base class that is a dependent type and is not the current instantiation.
[Note
:
A base class can be the current instantiation in the case of a nested class naming an enclosing class as a base.
[Example
:
template<class T> struct A {
  typedef int M;
  struct B {
    typedef void M;
    struct C;
  };
};

template<class T> struct A<T>::B::C : A<T> {
  M m;                          // OK, A<T>​::​M
};
end example
]
end note
]
  • An unqualified name that, when looked up, refers to at least one member of a class that is the current instantiation or a non-dependent base class thereof.
    [Note
    :
    This can only occur when looking up a name in a scope enclosed by the definition of a class template.
    end note
    ]
  • A qualified-id in which the nested-name-specifier refers to the current instantiation and that, when looked up, refers to at least one member of a class that is the current instantiation or a non-dependent base class thereof.
    [Note
    :
    If no such member is found, and the current instantiation has any dependent base classes, then the qualified-id is a member of an unknown specialization; see below.
    end note
    ]
  • An id-expression denoting the member in a class member access expression ([expr.ref]) for which the type of the object expression is the current instantiation, and the id-expression, when looked up ([basic.lookup.classref]), refers to at least one member of a class that is the current instantiation or a non-dependent base class thereof.
    [Note
    :
    If no such member is found, and the current instantiation has any dependent base classes, then the id-expression is a member of an unknown specialization; see below.
    end note
    ]
[Example
:
template <class T> class A {
  static const int i = 5;
  int n1[i];                    // i refers to a member of the current instantiation
  int n2[A::i];                 // A​::​i refers to a member of the current instantiation
  int n3[A<T>::i];              // A<T>​::​i refers to a member of the current instantiation
  int f();
};

template <class T> int A<T>::f() {
  return i;                     // i refers to a member of the current instantiation
}
end example
]
A name is a dependent member of the current instantiation if it is a member of the current instantiation that, when looked up, refers to at least one member of a class that is the current instantiation.
  • A qualified-id in which the nested-name-specifier names a dependent type that is not the current instantiation.
  • A qualified-id in which the nested-name-specifier refers to the current instantiation, the current instantiation has at least one dependent base class, and name lookup of the qualified-id does not find any member of a class that is the current instantiation or a non-dependent base class thereof.
  • An id-expression denoting the member in a class member access expression ([expr.ref]) in which either
    • the type of the object expression is the current instantiation, the current instantiation has at least one dependent base class, and name lookup of the id-expression does not find a member of a class that is the current instantiation or a non-dependent base class thereof; or
    • the type of the object expression is dependent and is not the current instantiation.
If a qualified-id in which the nested-name-specifier refers to the current instantiation is not a member of the current instantiation or a member of an unknown specialization, the program is ill-formed even if the template containing the qualified-id is not instantiated; no diagnostic required.
Similarly, if the id-expression in a class member access expression for which the type of the object expression is the current instantiation does not refer to a member of the current instantiation or a member of an unknown specialization, the program is ill-formed even if the template containing the member access expression is not instantiated; no diagnostic required.
[Example
:
template<class T> class A {
  typedef int type;
  void f() {
    A<T>::type i;               // OK: refers to a member of the current instantiation
    typename A<T>::other j;     // error: neither a member of the current instantiation nor
                                // a member of an unknown specialization
  }
};
end example
]
If, for a given set of template arguments, a specialization of a template is instantiated that refers to a member of the current instantiation with a qualified-id or class member access expression, the name in the qualified-id or class member access expression is looked up in the template instantiation context.
If the result of this lookup differs from the result of name lookup in the template definition context, name lookup is ambiguous.
[Example
:
struct A {
  int m;
};

struct B {
  int m;
};

template<typename T>
struct C : A, T {
  int f() { return this->m; }   // finds A​::​m in the template definition context
  int g() { return m; }         // finds A​::​m in the template definition context
};

template int C<B>::f();         // error: finds both A​::​m and B​::​m
template int C<B>::g();         // OK: transformation to class member access syntax
                                // does not occur in the template definition context; see [class.mfct.non-static]
end example
]
A type is dependent if it is
  • a template parameter,
  • a member of an unknown specialization,
  • a nested class or enumeration that is a dependent member of the current instantiation,
  • a cv-qualified type where the cv-unqualified type is dependent,
  • a compound type constructed from any dependent type,
  • an array type whose element type is dependent or whose bound (if any) is value-dependent,
  • a function type whose exception specification is value-dependent,
  • a simple-template-id in which either the template name is a template parameter or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent or is a pack expansion
    [Note
    :
    This includes an injected-class-name (Clause [class]) of a class template used without a template-argument-list.
    end note
    ]
    , or
  • denoted by decltype(expression), where expression is type-dependent ([temp.dep.expr]).
[Note
:
Because typedefs do not introduce new types, but instead simply refer to other types, a name that refers to a typedef that is a member of the current instantiation is dependent only if the type referred to is dependent.
end note
]

17.6.2.2 Type-dependent expressions [temp.dep.expr]

Except as described below, an expression is type-dependent if any subexpression is type-dependent.
this is type-dependent if the class type of the enclosing member function is dependent ([temp.dep.type]).
An id-expression is type-dependent if it contains
or if it names a dependent member of the current instantiation that is a static data member of type “array of unknown bound of T” for some T ([temp.static]).
Expressions of the following forms are type-dependent only if the type specified by the type-id, simple-type-specifier or new-type-id is dependent, even if any subexpression is type-dependent:
Expressions of the following forms are never type-dependent (because the type of the expression cannot be dependent):
literal
postfix-expression . pseudo-destructor-name
postfix-expression -> pseudo-destructor-name
sizeof unary-expression
sizeof ( type-id )
sizeof ... ( identifier )
alignof ( type-id )
typeid ( expression )
typeid ( type-id )
:: delete cast-expression
:: delete [ ] cast-expression
throw assignment-expression
noexcept ( expression )
[Note
:
For the standard library macro offsetof, see [support.types].
end note
]
A class member access expression ([expr.ref]) is type-dependent if the expression refers to a member of the current instantiation and the type of the referenced member is dependent, or the class member access expression refers to a member of an unknown specialization.
[Note
:
In an expression of the form x.y or xp->y the type of the expression is usually the type of the member y of the class of x (or the class pointed to by xp).
However, if x or xp refers to a dependent type that is not the current instantiation, the type of y is always dependent.
If x or xp refers to a non-dependent type or refers to the current instantiation, the type of y is the type of the class member access expression.
end note
]
A braced-init-list is type-dependent if any element is type-dependent or is a pack expansion.
A fold-expression is type-dependent.

17.6.2.3 Value-dependent expressions [temp.dep.constexpr]

Except as described below, an expression used in a context where a constant expression is required is value-dependent if any subexpression is value-dependent.
An id-expression is value-dependent if:
  • it is type-dependent,
  • it is the name of a non-type template parameter,
  • it names a static data member that is a dependent member of the current instantiation and is not initialized in a member-declarator,
  • it names a static member function that is a dependent member of the current instantiation, or
  • it is a constant with literal type and is initialized with an expression that is value-dependent.
Expressions of the following form are value-dependent if the unary-expression or expression is type-dependent or the type-id is dependent:
sizeof unary-expression
sizeof ( type-id )
typeid ( expression )
typeid ( type-id )
alignof ( type-id )
noexcept ( expression )
[Note
:
For the standard library macro offsetof, see [support.types].
end note
]
Expressions of the following form are value-dependent if either the type-id or simple-type-specifier is dependent or the expression or cast-expression is value-dependent:
simple-type-specifier ( expression-list )
static_cast < type-id > ( expression )
const_cast < type-id > ( expression )
reinterpret_cast < type-id > ( expression )
( type-id ) cast-expression
Expressions of the following form are value-dependent:
sizeof ... ( identifier )
fold-expression
An expression of the form &qualified-id where the qualified-id names a dependent member of the current instantiation is value-dependent.
An expression of the form &cast-expression is also value-dependent if evaluating cast-expression as a core constant expression ([expr.const]) succeeds and the result of the evaluation refers to a templated entity that is an object with static or thread storage duration or a member function.

17.6.2.4 Dependent template arguments [temp.dep.temp]

A type template-argument is dependent if the type it specifies is dependent.
A non-type template-argument is dependent if its type is dependent or the constant expression it specifies is value-dependent.
Furthermore, a non-type template-argument is dependent if the corresponding non-type template-parameter is of reference or pointer type and the template-argument designates or points to a member of the current instantiation or a member of a dependent type.
A template template-argument is dependent if it names a template-parameter or is a qualified-id that refers to a member of an unknown specialization.

17.6.3 Non-dependent names [temp.nondep]

Non-dependent names used in a template definition are found using the usual name lookup and bound at the point they are used.
[Example
:
void g(double);
void h();

template<class T> class Z {
public:
  void f() {
    g(1);           // calls g(double)
    h++;            // ill-formed: cannot increment function; this could be diagnosed
                    // either here or at the point of instantiation
  }
};

void g(int);        // not in scope at the point of the template definition, not considered for the call g(1)
end example
]

17.6.4 Dependent name resolution [temp.dep.res]

In resolving dependent names, names from the following sources are considered:
  • Declarations that are visible at the point of definition of the template.
  • Declarations from namespaces associated with the types of the function arguments both from the instantiation context ([temp.point]) and from the definition context.

17.6.4.1 Point of instantiation [temp.point]

For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization.
Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.
If a function template or member function of a class template is called in a way which uses the definition of a default argument of that function template or member function, the point of instantiation of the default argument is the point of instantiation of the function template or member function specialization.
For a noexcept-specifier of a function template specialization or specialization of a member function of a class template, if the noexcept-specifier is implicitly instantiated because it is needed by another template specialization and the context that requires it depends on a template parameter, the point of instantiation of the noexcept-specifier is the point of instantiation of the specialization that requires it.
Otherwise, the point of instantiation for such a noexcept-specifier immediately follows the namespace scope declaration or definition that requires the noexcept-specifier.
For a class template specialization, a class member template specialization, or a specialization for a class member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization, if the context from which the specialization is referenced depends on a template parameter, and if the specialization is not instantiated previous to the instantiation of the enclosing template, the point of instantiation is immediately before the point of instantiation of the enclosing template.
Otherwise, the point of instantiation for such a specialization immediately precedes the namespace scope declaration or definition that refers to the specialization.
If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of instantiation of its enclosing class template specialization.
An explicit instantiation definition is an instantiation point for the specialization or specializations specified by the explicit instantiation.
The instantiation context of an expression that depends on the template arguments is the set of declarations with external linkage declared prior to the point of instantiation of the template specialization in the same translation unit.
A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation.
A specialization for a class template has at most one point of instantiation within a translation unit.
A specialization for any template may have points of instantiation in multiple translation units.
If two different points of instantiation give a template specialization different meanings according to the one-definition rule ([basic.def.odr]), the program is ill-formed, no diagnostic required.

17.6.4.2 Candidate functions [temp.dep.candidate]

For a function call where the postfix-expression is a dependent name, the candidate functions are found using the usual lookup rules ([basic.lookup.unqual], [basic.lookup.argdep]) except that:
  • For the part of the lookup using unqualified name lookup ([basic.lookup.unqual]), only function declarations from the template definition context are found.
  • For the part of the lookup using associated namespaces ([basic.lookup.argdep]), only function declarations found in either the template definition context or the template instantiation context are found.
If the call would be ill-formed or would find a better match had the lookup within the associated namespaces considered all the function declarations with external linkage introduced in those namespaces in all translation units, not just considering those declarations found in the template definition and template instantiation contexts, then the program has undefined behavior.

17.6.5 Friend names declared within a class template [temp.inject]

Friend classes or functions can be declared within a class template.
When a template is instantiated, the names of its friends are treated as if the specialization had been explicitly declared at its point of instantiation.
As with non-template classes, the names of namespace-scope friend functions of a class template specialization are not visible during an ordinary lookup unless explicitly declared at namespace scope ([class.friend]).
Such names may be found under the rules for associated classes ([basic.lookup.argdep]).140
[Example
:
template<typename T> struct number {
  number(int);
  friend number gcd(number x, number y) { return 0; };
};

void g() {
  number<double> a(3), b(4);
  a = gcd(a,b);     // finds gcd because number<double> is an associated class,
                    // making gcd visible in its namespace (global scope)
  b = gcd(3,4);     // ill-formed; gcd is not visible
}
end example
]
Friend declarations do not introduce new names into any scope, either when the template is declared or when it is instantiated.

17.7 Template instantiation and specialization [temp.spec]

The act of instantiating a function, a class, a member of a class template or a member template is referred to as template instantiation.
A function instantiated from a function template is called an instantiated function.
A class instantiated from a class template is called an instantiated class.
A member function, a member class, a member enumeration, or a static data member of a class template instantiated from the member definition of the class template is called, respectively, an instantiated member function, member class, member enumeration, or static data member.
A member function instantiated from a member function template is called an instantiated member function.
A member class instantiated from a member class template is called an instantiated member class.
An explicit specialization may be declared for a function template, a class template, a member of a class template or a member template.
An explicit specialization declaration is introduced by template<>.
In an explicit specialization declaration for a class template, a member of a class template or a class member template, the name of the class that is explicitly specialized shall be a simple-template-id.
In the explicit specialization declaration for a function template or a member function template, the name of the function or member function explicitly specialized may be a template-id.
[Example
:
template<class T = int> struct A {
  static int x;
};
template<class U> void g(U) { }

template<> struct A<double> { };        // specialize for T == double
template<> struct A<> { };              // specialize for T == int
template<> void g(char) { }             // specialize for U == char
                                        // U is deduced from the parameter type
template<> void g<int>(int) { }         // specialize for U == int
template<> int A<char>::x = 0;          // specialize for T == char

template<class T = int> struct B {
  static int x;
};
template<> int B<>::x = 1;              // specialize for T == int
end example
]
An instantiated template specialization can be either implicitly instantiated ([temp.inst]) for a given argument list or be explicitly instantiated ([temp.explicit]).
A specialization is a class, function, or class member that is either instantiated or explicitly specialized ([temp.expl.spec]).
For a given template and a given set of template-arguments,
  • an explicit instantiation definition shall appear at most once in a program,
  • an explicit specialization shall be defined at most once in a program (according to [basic.def.odr]), and
  • both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit instantiation follows a declaration of the explicit specialization.
An implementation is not required to diagnose a violation of this rule.
Each class template specialization instantiated from a template has its own copy of any static members.
[Example
:
template<class T> class X {
  static T s;
};
template<class T> T X<T>::s = 0;
X<int> aa;
X<char*> bb;
X<int> has a static member s of type int and X<char*> has a static member s of type char*.
end example
]
If a function declaration acquired its function type through a dependent type ([temp.dep.type]) without using the syntactic form of a function declarator, the program is ill-formed.
[Example
:
template<class T> struct A {
  static T t;
};
typedef int function();
A<function> a;      // ill-formed: would declare A<function>​::​t as a static member function
end example
]

17.7.1 Implicit instantiation [temp.inst]

Unless a class template specialization has been explicitly instantiated ([temp.explicit]) or explicitly specialized ([temp.expl.spec]), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program.
[Note
:
In particular, if the semantics of an expression depend on the member or base class lists of a class template specialization, the class template specialization is implicitly generated.
For instance, deleting a pointer to class type depends on whether or not the class declares a destructor, and a conversion between pointers to class type depends on the inheritance relationship between the two classes involved.
end note
]
[Example
:
template<class T> class B { /* ... */ };
template<class T> class D : public B<T> { /* ... */ };

void f(void*);
void f(B<int>*);

void g(D<int>* p, D<char>* pp, D<double>* ppp) {
  f(p);             // instantiation of D<int> required: call f(B<int>*)
  B<char>* q = pp;  // instantiation of D<char> required: convert D<char>* to B<char>*
  delete ppp;       // instantiation of D<double> required
}
end example
]
If a class template has been declared, but not defined, at the point of instantiation ([temp.point]), the instantiation yields an incomplete class type ([basic.types]).
[Example
:
template<class T> class X;
X<char> ch;         // error: incomplete type X<char>
end example
]
[Note
:
Within a template declaration, a local class ([class.local]) or enumeration and the members of a local class are never considered to be entities that can be separately instantiated (this includes their default arguments, noexcept-specifiers, and non-static data member initializers, if any).
As a result, the dependent names are looked up, the semantic constraints are checked, and any templates used are instantiated as part of the instantiation of the entity within which the local class or enumeration is declared.
end note
]
The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, default arguments, or noexcept-specifiers of the class member functions, member classes, scoped member enumerations, static data members, member templates, and friends; and it causes the implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions.
However, for the purpose of determining whether an instantiated redeclaration is valid according to [basic.def.odr] and [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition.
[Example
:
template<class T, class U>
struct Outer {
  template<class X, class Y> struct Inner;
  template<class Y> struct Inner<T, Y>;         // #1a
  template<class Y> struct Inner<T, Y> { };     // #1b; OK: valid redeclaration of #1a
  template<class Y> struct Inner<U, Y> { };     // #2
};

Outer<int, int> outer;                          // error at #2
Outer<int, int>​::​Inner<int, Y> is redeclared at #1b.
(It is not defined but noted as being associated with a definition in Outer<T, U>.)
#2 is also a redeclaration of #1a.
It is noted as associated with a definition, so it is an invalid redeclaration of the same partial specialization.
template<typename T> struct Friendly {
  template<typename U> friend int f(U) { return sizeof(T); }
};
Friendly<char> fc;
Friendly<float> ff;                             // ill-formed: produces second definition of f(U)
end example
]
Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist.
A function whose declaration was instantiated from a friend function definition is implicitly instantiated when it is referenced in a context that requires a function definition to exist.
Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a class template is implicitly instantiated when the function is called in a context that requires the value of the default argument.
[Example
:
template<class T> struct Z {
  void f();
  void g();
};

void h() {
  Z<int> a;         // instantiation of class Z<int> required
  Z<char>* p;       // instantiation of class Z<char> not required
  Z<double>* q;     // instantiation of class Z<double> not required

  a.f();            // instantiation of Z<int>​::​f() required
  p->g();           // instantiation of class Z<char> required, and
                    // instantiation of Z<char>​::​g() required
}
Nothing in this example requires class Z<double>, Z<int>​::​g(), or Z<char>​::​f() to be implicitly instantiated.
end example
]
Unless a variable template specialization has been explicitly instantiated or explicitly specialized, the variable template specialization is implicitly instantiated when the specialization is used.
A default template argument for a variable template is implicitly instantiated when the variable template is referenced in a context that requires the value of the default argument.
If the function selected by overload resolution ([over.match]) can be determined without instantiating a class template definition, it is unspecified whether that instantiation actually takes place.
[Example
:
template <class T> struct S {
  operator int();
};

void f(int);
void f(S<int>&);
void f(S<float>);

void g(S<int>& sr) {
  f(sr);            // instantiation of S<int> allowed but not required
                    // instantiation of S<float> allowed but not required
};
end example
]
If a function template or a member function template specialization is used in a way that involves overload resolution, a declaration of the specialization is implicitly instantiated ([temp.over]).
An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, a static data member of a class template, or a substatement of a constexpr if statement ([stmt.if]), unless such instantiation is required.
It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated.
The use of a template specialization in a default argument shall not cause the template to be implicitly instantiated except that a class template may be instantiated where its complete type is needed to determine the correctness of the default argument.
The use of a default argument in a function call causes specializations in the default argument to be implicitly instantiated.
Implicitly instantiated class, function, and variable template specializations are placed in the namespace where the template is defined.
Implicitly instantiated specializations for members of a class template are placed in the namespace where the enclosing class template is defined.
Implicitly instantiated member templates are placed in the namespace where the enclosing class or class template is defined.
[Example
:
namespace N {
  template<class T> class List {
  public:
    T* get();
  };
}

template<class K, class V> class Map {
public:
  N::List<V> lt;
  V get(K);
};

void g(Map<const char*,int>& m) {
  int i = m.get("Nicholas");
}
a call of lt.get() from Map<const char*,int>​::​get() would place List<int>​::​get() in the namespace N rather than in the global namespace.
end example
]
If a function template f is called in a way that requires a default argument to be used, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the default argument is done as if the default argument had been an initializer used in a function template specialization with the same scope, the same template parameters and the same access as that of the function template f used at that point, except that the scope in which a closure type is declared ([expr.prim.lambda.closure]) – and therefore its associated namespaces – remain as determined from the context of the definition for the default argument.
This analysis is called default argument instantiation.
The instantiated default argument is then used as the argument of f.
Each default argument is instantiated independently.
[Example
:
template<class T> void f(T x, T y = ydef(T()), T z = zdef(T()));

class  A { };

A zdef(A);

void g(A a, A b, A c) {
  f(a, b, c);       // no default argument instantiation
  f(a, b);          // default argument z = zdef(T()) instantiated
  f(a);             // ill-formed; ydef is not declared
}
end example
]
The noexcept-specifier of a function template specialization is not instantiated along with the function declaration; it is instantiated when needed ([except.spec]).
If such an noexcept-specifier is needed but has not yet been instantiated, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the noexcept-specifier is done as if it were being done as part of instantiating the declaration of the specialization at that point.
[Note
:
[temp.point] defines the point of instantiation of a template specialization.
end note
]
There is an implementation-defined quantity that specifies the limit on the total depth of recursive instantiations ([implimits]), which could involve more than one template.
The result of an infinite recursion in instantiation is undefined.
[Example
:
template<class T> class X {
  X<T>* p;          // OK
  X<T*> a;          // implicit generation of X<T> requires
                    // the implicit instantiation of X<T*> which requires
                    // the implicit instantiation of X<T**> which …
};
end example
]

17.7.2 Explicit instantiation [temp.explicit]

A class, function, variable, or member template specialization can be explicitly instantiated from its template.
A member function, member class or static data member of a class template can be explicitly instantiated from the member definition associated with its class template.
An explicit instantiation of a function template or member function of a class template shall not use the inline or constexpr specifiers.
The syntax for explicit instantiation is:
explicit-instantiation:
	extern template declaration
There are two forms of explicit instantiation: an explicit instantiation definition and an explicit instantiation declaration.
An explicit instantiation declaration begins with the extern keyword.
If the explicit instantiation is for a class or member class, the elaborated-type-specifier in the declaration shall include a simple-template-id.
If the explicit instantiation is for a function or member function, the unqualified-id in the declaration shall be either a template-id or, where all template arguments can be deduced, a template-name or operator-function-id.
[Note
:
The declaration may declare a qualified-id, in which case the unqualified-id of the qualified-id must be a template-id.
end note
]
If the explicit instantiation is for a member function, a member class or a static data member of a class template specialization, the name of the class template specialization in the qualified-id for the member name shall be a simple-template-id.
If the explicit instantiation is for a variable, the unqualified-id in the declaration shall be a template-id.
An explicit instantiation shall appear in an enclosing namespace of its template.
If the name declared in the explicit instantiation is an unqualified name, the explicit instantiation shall appear in the namespace where its template is declared or, if that namespace is inline ([namespace.def]), any namespace from its enclosing namespace set.
[Note
:
Regarding qualified names in declarators, see [dcl.meaning].
end note
]
[Example
:
template<class T> class Array { void mf(); };
template class Array<char>;
template void Array<int>::mf();

template<class T> void sort(Array<T>& v) { /* ... */ }
template void sort(Array<char>&);       // argument is deduced here

namespace N {
  template<class T> void f(T&) { }
}
template void N::f<int>(int&);
end example
]
A declaration of a function template, a variable template, a member function or static data member of a class template, or a member function template of a class or class template shall precede an explicit instantiation of that entity.
A definition of a class template, a member class of a class template, or a member class template of a class or class template shall precede an explicit instantiation of that entity unless the explicit instantiation is preceded by an explicit specialization of the entity with the same template arguments.
If the declaration of the explicit instantiation names an implicitly-declared special member function (Clause [special]), the program is ill-formed.
For a given set of template arguments, if an explicit instantiation of a template appears after a declaration of an explicit specialization for that template, the explicit instantiation has no effect.
Otherwise, for an explicit instantiation definition the definition of a function template, a variable template, a member function template, or a member function or static data member of a class template shall be present in every translation unit in which it is explicitly instantiated.
An explicit instantiation of a class, function template, or variable template specialization is placed in the namespace in which the template is defined.
An explicit instantiation for a member of a class template is placed in the namespace where the enclosing class template is defined.
An explicit instantiation for a member template is placed in the namespace where the enclosing class or class template is defined.
[Example
:
namespace N {
  template<class T> class Y { void mf() { } };
}

template class Y<int>;          // error: class template Y not visible in the global namespace

using N::Y;
template class Y<int>;          // error: explicit instantiation outside of the namespace of the template

template class N::Y<char*>;             // OK: explicit instantiation in namespace N
template void N::Y<double>::mf();       // OK: explicit instantiation in namespace N
end example
]
A trailing template-argument can be left unspecified in an explicit instantiation of a function template specialization or of a member function template specialization provided it can be deduced from the type of a function parameter ([temp.deduct]).
[Example
:
template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v) { /* ... */ }

// instantiate sort(Array<int>&) – template-argument deduced
template void sort<>(Array<int>&);
end example
]
An explicit instantiation that names a class template specialization is also an explicit instantiation of the same kind (declaration or definition) of each of its members (not including members inherited from base classes and members that are templates) that has not been previously explicitly specialized in the translation unit containing the explicit instantiation, except as described below.
[Note
:
In addition, it will typically be an explicit instantiation of certain implementation-dependent data about the class.
end note
]
An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.
Except for inline functions and variables, declarations with types deduced from their initializer or return value ([dcl.spec.auto]), const variables of literal types, variables of reference types, and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the entity to which they refer.
[Note
:
The intent is that an inline function that is the subject of an explicit instantiation declaration will still be implicitly instantiated when odr-used ([basic.def.odr]) so that the body can be considered for inlining, but that no out-of-line copy of the inline function would be generated in the translation unit.
end note
]
If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration.
An entity that is the subject of an explicit instantiation declaration and that is also used in a way that would otherwise cause an implicit instantiation ([temp.inst]) in the translation unit shall be the subject of an explicit instantiation definition somewhere in the program; otherwise the program is ill-formed, no diagnostic required.
[Note
:
This rule does apply to inline functions even though an explicit instantiation declaration of such an entity has no other normative effect.
This is needed to ensure that if the address of an inline function is taken in a translation unit in which the implementation chose to suppress the out-of-line body, another translation unit will supply the body.
end note
]
An explicit instantiation declaration shall not name a specialization of a template with internal linkage.
The usual access checking rules do not apply to names used to specify explicit instantiations.
[Note
:
In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible.
end note
]
An explicit instantiation does not constitute a use of a default argument, so default argument instantiation is not done.
[Example
:
char* p = 0;
template<class T> T g(T x = &p) { return x; }
template int g<int>(int);       // OK even though &p isn't an int.
end example
]

17.7.3 Explicit specialization [temp.expl.spec]

An explicit specialization of any of the following:
  • function template
  • class template
  • variable template
  • member function of a class template
  • static data member of a class template
  • member class of a class template
  • member enumeration of a class template
  • member class template of a class or class template
  • member function template of a class or class template
can be declared by a declaration introduced by template<>; that is:
explicit-specialization:
	template < > declaration
[Example
:
template<class T> class stream;

template<> class stream<char> { /* ... */ };

template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v) { /* ... */ }

template<> void sort<char*>(Array<char*>&);
Given these declarations, stream<char> will be used as the definition of streams of chars; other streams will be handled by class template specializations instantiated from the class template.
Similarly, sort<char*> will be used as the sort function for arguments of type Array<char*>; other Array types will be sorted by functions generated from the template.
end example
]
An explicit specialization may be declared in any scope in which the corresponding primary template may be defined ([namespace.memdef], [class.mem], [temp.mem]).
A declaration of a function template, class template, or variable template being explicitly specialized shall precede the declaration of the explicit specialization.
[Note
:
A declaration, but not a definition of the template is required.
end note
]
The definition of a class or class template shall precede the declaration of an explicit specialization for a member template of the class or class template.
[Example
:
template<> class X<int> { /* ... */ };          // error: X not a template

template<class T> class X;

template<> class X<char*> { /* ... */ };        // OK: X is a template
end example
]
A member function, a member function template, a member class, a member enumeration, a member class template, a static data member, or a static data member template of a class template may be explicitly specialized for a class specialization that is implicitly instantiated; in this case, the definition of the class template shall precede the explicit specialization for the member of the class template.
If such an explicit specialization for the member of a class template names an implicitly-declared special member function (Clause [special]), the program is ill-formed.
A member of an explicitly specialized class is not implicitly instantiated from the member declaration of the class template; instead, the member of the class template specialization shall itself be explicitly defined if its definition is required.
In this case, the definition of the class template explicit specialization shall be in scope at the point at which the member is defined.
The definition of an explicitly specialized class is unrelated to the definition of a generated specialization.
That is, its members need not have the same names, types, etc.
as the members of a generated specialization.
Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax.
The same is true when defining a member of an explicitly specialized member class.
However, template<> is used in defining a member of an explicitly specialized member class template that is specialized as a class template.
[Example
:
template<class T> struct A {
  struct B { };
  template<class U> struct C { };
};

template<> struct A<int> {
  void f(int);
};

void h() {
  A<int> a;
  a.f(16);          // A<int>​::​f must be defined somewhere
}

// template<> not used for a member of an explicitly specialized class template
void A<int>::f(int) { /* ... */ }

template<> struct A<char>::B {
  void f();
};
// template<> also not used when defining a member of an explicitly specialized member class
void A<char>::B::f() { /* ... */ }

template<> template<class U> struct A<char>::C {
  void f();
};
// template<> is used when defining a member of an explicitly specialized member class template
// specialized as a class template
template<>
template<class U> void A<char>::C<U>::f() { /* ... */ }

template<> struct A<short>::B {
  void f();
};
template<> void A<short>::B::f() { /* ... */ }              // error: template<> not permitted

template<> template<class U> struct A<short>::C {
  void f();
};
template<class U> void A<short>::C<U>::f() { /* ... */ }    // error: template<> required
end example
]
If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required.
An implicit instantiation is never generated for an explicit specialization that is declared but not defined.
[Example
:
class String { };
template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v) { /* ... */ }

void f(Array<String>& v) {
  sort(v);          // use primary template sort(Array<T>&), T is String
}

template<> void sort<String>(Array<String>& v);     // error: specialization after use of primary template
template<> void sort<>(Array<char*>& v);            // OK: sort<char*> not yet used
template<class T> struct A {
  enum E : T;
  enum class S : T;
};
template<> enum A<int>::E : int { eint };           // OK
template<> enum class A<int>::S : int { sint };     // OK
template<class T> enum A<T>::E : T { eT };
template<class T> enum class A<T>::S : T { sT };
template<> enum A<char>::E : char { echar };        // ill-formed, A<char>​::​E was instantiated
                                                    // when A<char> was instantiated
template<> enum class A<char>::S : char { schar };  // OK
end example
]
The placement of explicit specialization declarations for function templates, class templates, variable templates, member functions of class templates, static data members of class templates, member classes of class templates, member enumerations of class templates, member class templates of class templates, member function templates of class templates, static data member templates of class templates, member functions of member templates of class templates, member functions of member templates of non-template classes, static data member templates of non-template classes, member function templates of member classes of class templates, etc.
, and the placement of partial specialization declarations of class templates, variable templates, member class templates of non-template classes, static data member templates of non-template classes, member class templates of class templates, etc.
, can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below.
When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.
A template explicit specialization is in the scope of the namespace in which the template was defined.
[Example
:
namespace N {
  template<class T> class X { /* ... */ };
  template<class T> class Y { /* ... */ };

  template<> class X<int> { /* ... */ };        // OK: specialization in same namespace
  template<> class Y<double>;                   // forward-declare intent to specialize for double
}

template<> class N::Y<double> { /* ... */ };    // OK: specialization in enclosing namespace
template<> class N::Y<short> { /* ... */ };     // OK: specialization in enclosing namespace
end example
]
A simple-template-id that names a class template explicit specialization that has been declared but not defined can be used exactly like the names of other incompletely-defined classes ([basic.types]).
[Example
:
template<class T> class X;                      // X is a class template
template<> class X<int>;

X<int>* p;                                      // OK: pointer to declared class X<int>
X<int> x;                                       // error: object of incomplete class X<int>
end example
]
A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type.
[Example
:
template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v);

// explicit specialization for sort(Array<int>&)
// with deduced template-argument of type int
template<> void sort(Array<int>&);
end example
]
A function with the same name as a template and a type that exactly matches that of a template specialization is not an explicit specialization ([temp.fct]).
An explicit specialization of a function or variable template is inline only if it is declared with the inline specifier or defined as deleted, and independently of whether its function or variable template is inline.
[Example
:
template<class T> void f(T) { /* ... */ }
template<class T> inline T g(T) { /* ... */ }

template<> inline void f<>(int) { /* ... */ }   // OK: inline
template<> int g<>(int) { /* ... */ }           // OK: not inline
end example
]
An explicit specialization of a static data member of a template or an explicit specialization of a static data member template is a definition if the declaration includes an initializer; otherwise, it is a declaration.
[Note
:
The definition of a static data member of a template that requires default-initialization must use a braced-init-list:
template<> X Q<int>::x;                         // declaration
template<> X Q<int>::x ();                      // error: declares a function
template<> X Q<int>::x { };                     // definition
end note
]
A member or a member template of a class template may be explicitly specialized for a given implicit instantiation of the class template, even if the member or member template is defined in the class template definition.
An explicit specialization of a member or member template is specified using the syntax for explicit specialization.
[Example
:
template<class T> struct A {
  void f(T);
  template<class X1> void g1(T, X1);
  template<class X2> void g2(T, X2);
  void h(T) { }
};

// specialization
template<> void A<int>::f(int);

// out of class member template definition
template<class T> template<class X1> void A<T>::g1(T, X1) { }

// member template specialization
template<> template<class X1> void A<int>::g1(int, X1);

// member template specialization
template<> template<>
  void A<int>::g1(int, char);           // X1 deduced as char
template<> template<>
  void A<int>::g2<char>(int, char);     // X2 specified as char

// member specialization even if defined in class definition
template<> void A<int>::h(int) { }
end example
]
A member or a member template may be nested within many enclosing class templates.
In an explicit specialization for such a member, the member declaration shall be preceded by a template<> for each enclosing class template that is explicitly specialized.
[Example
:
template<class T1> class A {
  template<class T2> class B {
    void mf();
  };
};
template<> template<> class A<int>::B<double>;
template<> template<> void A<char>::B<char>::mf();
end example
]
In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well.
In such explicit specialization declaration, the keyword template followed by a template-parameter-list shall be provided instead of the template<> preceding the explicit specialization declaration of the member.
The types of the template-parameters in the template-parameter-list shall be the same as those specified in the primary template definition.
[Example
:
template <class T1> class A {
  template<class T2> class B {
    template<class T3> void mf1(T3);
    void mf2();
  };
};
template <> template <class X>
  class A<int>::B {
      template <class T> void mf1(T);
  };
template <> template <> template<class T>
  void A<int>::B<double>::mf1(T t) { }
template <class Y> template <>
  void A<Y>::B<double>::mf2() { }       // ill-formed; B<double> is specialized but
                                        // its enclosing class template A is not
end example
]
A specialization of a member function template, member class template, or static data member template of a non-specialized class template is itself a template.
An explicit specialization declaration shall not be a friend declaration.
Default function arguments shall not be specified in a declaration or a definition for one of the following explicit specializations:
  • the explicit specialization of a function template;
  • the explicit specialization of a member function template;
  • the explicit specialization of a member function of a class template where the class template specialization to which the member function specialization belongs is implicitly instantiated.
    [Note
    :
    Default function arguments may be specified in the declaration or definition of a member function of a class template specialization that is explicitly specialized.
    end note
    ]

17.8 Function template specializations [temp.fct.spec]

A function instantiated from a function template is called a function template specialization; so is an explicit specialization of a function template.
Template arguments can be explicitly specified when naming the function template specialization, deduced from the context (e.g., deduced from the function arguments in a call to the function template specialization, see [temp.deduct]), or obtained from default template arguments.
Each function template specialization instantiated from a template has its own copy of any static variable.
[Example
:
template<class T> void f(T* p) {
  static T s;
};

void g(int a, char* b) {
  f(&a);            // calls f<int>(int*)
  f(&b);            // calls f<char*>(char**)
}
Here f<int>(int*) has a static variable s of type int and f<char*>(char**) has a static variable s of type char*.
end example
]

17.8.1 Explicit template argument specification [temp.arg.explicit]

Template arguments can be specified when referring to a function template specialization by qualifying the function template name with the list of template-arguments in the same way as template-arguments are specified in uses of a class template specialization.
[Example
:
template<class T> void sort(Array<T>& v);
void f(Array<dcomplex>& cv, Array<int>& ci) {
  sort<dcomplex>(cv);                   // sort(Array<dcomplex>&)
  sort<int>(ci);                        // sort(Array<int>&)
}
and
template<class U, class V> U convert(V v);

void g(double d) {
  int i = convert<int,double>(d);       // int convert(double)
  char c = convert<char,double>(d);     // char convert(double)
}
end example
]
A template argument list may be specified when referring to a specialization of a function template
  • when a function is called,
  • when the address of a function is taken, when a function initializes a reference to function, or when a pointer to member function is formed,
  • in an explicit specialization,
  • in an explicit instantiation, or
  • in a friend declaration.
Trailing template arguments that can be deduced ([temp.deduct]) or obtained from default template-arguments may be omitted from the list of explicit template-arguments.
A trailing template parameter pack ([temp.variadic]) not otherwise deduced will be deduced to an empty sequence of template arguments.
If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted.
In contexts where deduction is done and fails, or in contexts where deduction is not done, if a template argument list is specified and it, along with any default template arguments, identifies a single function template specialization, then the template-id is an lvalue for the function template specialization.
[Example
:
template<class X, class Y> X f(Y);
template<class X, class Y, class ... Z> X g(Y);
void h() {
  int i = f<int>(5.6);          // Y is deduced to be double
  int j = f(5.6);               // ill-formed: X cannot be deduced
  f<void>(f<int, bool>);        // Y for outer f deduced to be int (*)(bool)
  f<void>(f<int>);              // ill-formed: f<int> does not denote a single function template specialization
  int k = g<int>(5.6);          // Y is deduced to be double, Z is deduced to an empty sequence
  f<void>(g<int, bool>);        // Y for outer f is deduced to be int (*)(bool),
                                // Z is deduced to an empty sequence
}
end example
]
[Note
:
An empty template argument list can be used to indicate that a given use refers to a specialization of a function template even when a non-template function ([dcl.fct]) is visible that would otherwise be used.
For example:
template <class T> int f(T);    // #1
int f(int);                     // #2
int k = f(1);                   // uses #2
int l = f<>(1);                 // uses #1
end note
]
Template arguments that are present shall be specified in the declaration order of their corresponding template-parameters.
The template argument list shall not specify more template-arguments than there are corresponding template-parameters unless one of the template-parameters is a template parameter pack.
[Example
:
template<class X, class Y, class Z> X f(Y,Z);
template<class ... Args> void f2();
void g() {
  f<int,const char*,double>("aa",3.0);
  f<int,const char*>("aa",3.0); // Z is deduced to be double
  f<int>("aa",3.0);             // Y is deduced to be const char*, and Z is deduced to be double
  f("aa",3.0);                  // error: X cannot be deduced
  f2<char, short, int, long>(); // OK
}
end example
]
Implicit conversions (Clause [conv]) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction.
[Note
:
Template parameters do not participate in template argument deduction if they are explicitly specified.
For example,
template<class T> void f(T);

class Complex {
  Complex(double);
};

void g() {
  f<Complex>(1);    // OK, means f<Complex>(Complex(1))
}
end note
]
[Note
:
Because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates.
end note
]
[Note
:
For simple function names, argument dependent lookup ([basic.lookup.argdep]) applies even when the function name is not visible within the scope of the call.
This is because the call still has the syntactic form of a function call ([basic.lookup.unqual]).
But when a function template with explicit template arguments is used, the call does not have the correct syntactic form unless there is a function template with that name visible at the point of the call.
If no such name is visible, the call is not syntactically well-formed and argument-dependent lookup does not apply.
If some such name is visible, argument dependent lookup applies and additional function templates may be found in other namespaces.
[Example
:
namespace A {
  struct B { };
  template<int X> void f(B);
}
namespace C {
  template<class T> void f(T t);
}
void g(A::B b) {
  f<3>(b);          // ill-formed: not a function call
  A::f<3>(b);       // well-formed
  C::f<3>(b);       // ill-formed; argument dependent lookup applies only to unqualified names
  using C::f;
  f<3>(b);          // well-formed because C​::​f is visible; then A​::​f is found by argument dependent lookup
}
end example
]
end note
]
Template argument deduction can extend the sequence of template arguments corresponding to a template parameter pack, even when the sequence contains explicitly specified template arguments.
[Example
:
template<class ... Types> void f(Types ... values);

void g() {
  f<int*, float*>(0, 0, 0);     // Types is deduced to the sequence int*, float*, int
}
end example
]

17.8.2 Template argument deduction [temp.deduct]

When a function template specialization is referenced, all of the template arguments shall have values.
The values can be explicitly specified or, in some cases, be deduced from the use or obtained from default template-arguments.
[Example
:
void f(Array<dcomplex>& cv, Array<int>& ci) {
  sort(cv);                     // calls sort(Array<dcomplex>&)
  sort(ci);                     // calls sort(Array<int>&)
}
and
void g(double d) {
  int i = convert<int>(d);      // calls convert<int,double>(double)
  int c = convert<char>(d);     // calls convert<char,double>(double)
}
end example
]
When an explicit template argument list is specified, the template arguments must be compatible with the template parameter list and must result in a valid function type as described below; otherwise type deduction fails.
Specifically, the following steps are performed when evaluating an explicitly specified template argument list with respect to a given function template:
  • The specified template arguments must match the template parameters in kind (i.e., type, non-type, template). There must not be more arguments than there are parameters unless at least one parameter is a template parameter pack, and there shall be an argument for each non-pack parameter. Otherwise, type deduction fails.
  • Non-type arguments must match the types of the corresponding non-type template parameters, or must be convertible to the types of the corresponding non-type parameters as specified in [temp.arg.nontype], otherwise type deduction fails.
  • The specified template argument values are substituted for the corresponding template parameters as specified below.
After this substitution is performed, the function parameter type adjustments described in [dcl.fct] are performed.
[Example
:
A parameter type of “void (const int, int[5])” becomes “void(*)(int,int*).
end example
]
[Note
:
A top-level qualifier in a function parameter declaration does not affect the function type but still affects the type of the function parameter variable within the function.
end note
]
[Example
:
template <class T> void f(T t);
template <class X> void g(const X x);
template <class Z> void h(Z, Z*);

int main() {
  // #1: function type is f(int), t is non const
  f<int>(1);

  // #2: function type is f(int), t is const
  f<const int>(1);

  // #3: function type is g(int), x is const
  g<int>(1);

  // #4: function type is g(int), x is const
  g<const int>(1);

  // #5: function type is h(int, const int*)
  h<const int>(1,0);
}
end example
]
[Note
:
f<int>(1) and f<const int>(1) call distinct functions even though both of the functions called have the same function type.
end note
]
The resulting substituted and adjusted function type is used as the type of the function template for template argument deduction.
If a template argument has not been deduced and its corresponding template parameter has a default argument, the template argument is determined by substituting the template arguments determined for preceding template parameters into the default argument.
If the substitution results in an invalid type, as described above, type deduction fails.
[Example
:
template <class T, class U = double>
void f(T t = 0, U u = 0);

void g() {
  f(1, 'c');        // f<int,char>(1,'c')
  f(1);             // f<int,double>(1,0)
  f();              // error: T cannot be deduced
  f<int>();         // f<int,double>(0,0)
  f<int,char>();    // f<int,char>(0,0)
}
end example
]
When all template arguments have been deduced or obtained from default template arguments, all uses of template parameters in the template parameter list of the template and the function type are replaced with the corresponding deduced or default argument values.
If the substitution results in an invalid type, as described above, type deduction fails.
At certain points in the template argument deduction process it is necessary to take a function type that makes use of template parameters and replace those template parameters with the corresponding template arguments.
This is done at the beginning of template argument deduction when any explicitly specified template arguments are substituted into the function type, and again at the end of template argument deduction when any template arguments that were deduced or obtained from default arguments are substituted.
The substitution occurs in all types and expressions that are used in the function type and in template parameter declarations.
The expressions include not only constant expressions such as those that appear in array bounds or as nontype template arguments but also general expressions (i.e., non-constant expressions) inside sizeof, decltype, and other contexts that allow non-constant expressions.
The substitution proceeds in lexical order and stops when a condition that causes deduction to fail is encountered.
[Note
:
The equivalent substitution in exception specifications is done only when the noexcept-specifier is instantiated, at which point a program is ill-formed if the substitution results in an invalid type or expression.
end note
]
[Example
:
template <class T> struct A { using X = typename T::X; };
template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { }
template <class T> auto g(typename A<T>::X) -> typename T::X;
template <class T> void g(...) { }

void h() {
  f<int>(0);        // OK, substituting return type causes deduction to fail
  g<int>(0);        // error, substituting parameter type instantiates A<int>
}
end example
]
If a substitution results in an invalid type or expression, type deduction fails.
An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written using the substituted arguments.
[Note
:
If no diagnostic is required, the program is still ill-formed.
Access checking is done as part of the substitution process.
end note
]
Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure.
[Note
:
The substitution into types and expressions can result in effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc.
Such effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
[Example
:
struct X { };
struct Y {
  Y(X){}
};

template <class T> auto f(T t1, T t2) -> decltype(t1 + t2);     // #1
X f(Y, Y);          // #2

X x1, x2;
X x3 = f(x1, x2);   // deduction fails on #1 (cannot add X+X), calls #2
end example
]
[Note
:
Type deduction may fail for the following reasons:
  • Attempting to instantiate a pack expansion containing multiple parameter packs of differing lengths.
  • Attempting to create an array with an element type that is void, a function type, a reference type, or an abstract class type, or attempting to create an array with a size that is zero or negative.
    [Example
    :
    template <class T> int f(T[5]);
    int I = f<int>(0);
    int j = f<void>(0);             // invalid array
    
    end example
    ]
  • Attempting to use a type that is not a class or enumeration type in a qualified name.
    [Example
    :
    template <class T> int f(typename T::B*);
    int i = f<int>(0);
    end example
    ]
  • Attempting to use a type in a nested-name-specifier of a qualified-id when that type does not contain the specified member, or
    • the specified member is not a type where a type is required, or
    • the specified member is not a template where a template is required, or
    • the specified member is not a non-type where a non-type is required.
    [Example
    :
    template <int I> struct X { };
    template <template <class T> class> struct Z { };
    template <class T> void f(typename T::Y*){}
    template <class T> void g(X<T::N>*){}
    template <class T> void h(Z<T::template TT>*){}
    struct A {};
    struct B { int Y; };
    struct C {
      typedef int N;
    };
    struct D {
      typedef int TT;
    };
    
    int main() {
      // Deduction fails in each of these cases:
      f<A>(0);          // A does not contain a member Y
      f<B>(0);          // The Y member of B is not a type
      g<C>(0);          // The N member of C is not a non-type
      h<D>(0);          // The TT member of D is not a template
    }
    end example
    ]
  • Attempting to create a pointer to reference type.
  • Attempting to create a reference to void.
  • Attempting to create “pointer to member of T” when T is not a class type.
    [Example
    :
    template <class T> int f(int T::*);
    int i = f<int>(0);
    end example
    ]
  • Attempting to give an invalid type to a non-type template parameter.
    [Example
    :
    template <class T, T> struct S {};
    template <class T> int f(S<T, T()>*);
    struct X {};
    int i0 = f<X>(0);
    end example
    ]
  • Attempting to perform an invalid conversion in either a template argument expression, or an expression used in the function declaration.
    [Example
    :
    template <class T, T*> int f(int);
    int i2 = f<int,1>(0);           // can't conv 1 to int*
    
    end example
    ]
  • Attempting to create a function type in which a parameter has a type of void, or in which the return type is a function type or array type.
  • Attempting to create a function type in which a parameter type or the return type is an abstract class type ([class.abstract]).
end note
]
[Example
:
In the following example, assuming a signed char cannot represent the value 1000, a narrowing conversion ([dcl.init.list]) would be required to convert the template-argument of type int to signed char, therefore substitution fails for the second template ([temp.arg.nontype]).
template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1000>(0);            // OK
int i2 = f<1>(0);               // ambiguous; not narrowing
end example
]

17.8.2.1 Deducing template arguments from a function call [temp.deduct.call]

Template argument deduction is done by comparing each function template parameter type (call it P) that contains template-parameters that participate in template argument deduction with the type of the corresponding argument of the call (call it A) as described below.
If removing references and cv-qualifiers from P gives std​::​initializer_­list<P'> or P'[N] for some P' and N and the argument is a non-empty initializer list ([dcl.init.list]), then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument, and in the P'[N] case, if N is a non-type template parameter, N is deduced from the length of the initializer list.
Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context ([temp.deduct.type]).
[Example
:
template<class T> void f(std::initializer_list<T>);
f({1,2,3});                     // T deduced to int
f({1,"asdf"});                  // error: T deduced to both int and const char*

template<class T> void g(T);
g({1,2,3});                     // error: no argument deduced for T

template<class T, int N> void h(T const(&)[N]);
h({1,2,3});                     // T deduced to int, N deduced to 3

template<class T> void j(T const(&)[3]);
j({42});                        // T deduced to int, array bound not considered

struct Aggr { int i; int j; };
template<int N> void k(Aggr const(&)[N]);
k({1,2,3});                     // error: deduction fails, no conversion from int to Aggr
k({{1},{2},{3}});               // OK, N deduced to 3

template<int M, int N> void m(int const(&)[M][N]);
m({{1,2},{3,4}});               // M and N both deduced to 2

template<class T, int N> void n(T const(&)[N], T);
n({{1},{2},{3}},Aggr());        // OK, T is Aggr, N is 3
end example
]
For a function parameter pack that occurs at the end of the parameter-declaration-list, deduction is performed for each remaining argument of the call, taking the type P of the declarator-id of the function parameter pack as the corresponding function template parameter type.
Each deduction deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack.
When a function parameter pack appears in a non-deduced context ([temp.deduct.type]), the type of that parameter pack is never deduced.
[Example
:
template<class ... Types> void f(Types& ...);
template<class T1, class ... Types> void g(T1, Types ...);
template<class T1, class ... Types> void g1(Types ..., T1);

void h(int x, float& y) {
  const int z = x;
  f(x, y, z);                   // Types is deduced to int, float, const int
  g(x, y, z);                   // T1 is deduced to int; Types is deduced to float, int
  g1(x, y, z);                  // error: Types is not deduced
  g1<int, int, int>(x, y, z);   // OK, no deduction occurs
}
end example
]
If P is not a reference type:
  • If A is an array type, the pointer type produced by the array-to-pointer standard conversion ([conv.array]) is used in place of A for type deduction; otherwise,
  • If A is a function type, the pointer type produced by the function-to-pointer standard conversion ([conv.func]) is used in place of A for type deduction; otherwise,
  • If A is a cv-qualified type, the top-level cv-qualifiers of A's type are ignored for type deduction.
If P is a cv-qualified type, the top-level cv-qualifiers of P's type are ignored for type deduction.
If P is a reference type, the type referred to by P is used for type deduction.
[Example
:
template<class T> int f(const T&);
int n1 = f(5);                  // calls f<int>(const int&)
const int i = 0;
int n2 = f(i);                  // calls f<int>(const int&)
template <class T> int g(volatile T&);
int n3 = g(i);                  // calls g<const int>(const volatile int&)
end example
]
A forwarding reference is an rvalue reference to a cv-unqualified template parameter that does not represent a template parameter of a class template (during class template argument deduction ([over.match.class.deduct])).
If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction.
[Example
:
template <class T> int f(T&& heisenreference);
template <class T> int g(const T&&);
int i;
int n1 = f(i);                  // calls f<int&>(int&)
int n2 = f(0);                  // calls f<int>(int&&)
int n3 = g(i);                  // error: would call g<int>(const int&&), which
                                // would bind an rvalue reference to an lvalue

template <class T> struct A {
  template <class U>
    A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference.
                                // U&& is a forwarding reference.
  A(T&&, int*);                 // #2
};

template <class T> A(T&&, int*) -> A<T>;    // #3: T&& is a forwarding reference.

int *ip;
A a{i, 0, ip};                  // error: cannot deduce from #1
A a0{0, 0, ip};                 // uses #1 to deduce A<int> and #1 to initialize
A a2{i, ip};                    // uses #3 to deduce A<int&> and #2 to initialize
end example
]
In general, the deduction process attempts to find template argument values that will make the deduced A identical to A (after the type A is transformed as described above).
However, there are three cases that allow a difference:
  • If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be more cv-qualified than the transformed A.
  • The transformed A can be another pointer or pointer to member type that can be converted to the deduced A via a function pointer conversion ([conv.fctptr]) and/or qualification conversion ([conv.qual]).
  • If P is a class and P has the form simple-template-id, then the transformed A can be a derived class of the deduced A.
    Likewise, if P is a pointer to a class of the form simple-template-id, the transformed A can be a pointer to a derived class pointed to by the deduced A.
These alternatives are considered only if type deduction would otherwise fail.
If they yield more than one possible deduced A, the type deduction fails.
[Note
:
If a template-parameter is not used in any of the function parameters of a function template, or is used only in a non-deduced context, its corresponding template-argument cannot be deduced from a function call and the template-argument must be explicitly specified.
end note
]
When P is a function type, function pointer type, or pointer to member function type:
  • If the argument is an overload set containing one or more function templates, the parameter is treated as a non-deduced context.
  • If the argument is an overload set (not containing function templates), trial argument deduction is attempted using each of the members of the set.
    If deduction succeeds for only one of the overload set members, that member is used as the argument value for the deduction.
    If deduction succeeds for more than one member of the overload set the parameter is treated as a non-deduced context.
[Example
:
// Only one function of an overload set matches the call so the function parameter is a deduced context.
template <class T> int f(T (*p)(T));
int g(int);
int g(char);
int i = f(g);       // calls f(int (*)(int))
end example
]
[Example
:
// Ambiguous deduction causes the second function parameter to be a non-deduced context.
template <class T> int f(T, T (*p)(T));
int g(int);
char g(char);
int i = f(1, g);    // calls f(int, int (*)(int))
end example
]
[Example
:
// The overload set contains a template, causing the second function parameter to be a non-deduced context.
template <class T> int f(T, T (*p)(T));
char g(char);
template <class T> T g(T);
int i = f(1, g);    // calls f(int, int (*)(int))
end example
]
If deduction succeeds for all parameters that contain template-parameters that participate in template argument deduction, and all template arguments are explicitly specified, deduced, or obtained from default template arguments, remaining parameters are then compared with the corresponding arguments.
For each remaining parameter P with a type that was non-dependent before substitution of any explicitly-specified template arguments, if the corresponding argument A cannot be implicitly converted to P, deduction fails.
[Note
:
Parameters with dependent types in which no template-parameters participate in template argument deduction, and parameters that became non-dependent due to substitution of explicitly-specified template arguments, will be checked during overload resolution.
end note
]
[Example
:
  template <class T> struct Z {
    typedef typename T::x xx;
  };
  template <class T> typename Z<T>::xx f(void *, T);    // #1
  template <class T> void f(int, T);                    // #2
  struct A {} a;
  int main() {
    f(1, a);        // OK, deduction fails for #1 because there is no conversion from int to void*
  }
end example
]

17.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr]

Template arguments can be deduced from the type specified when taking the address of an overloaded function ([over.over]).
The function template's function type and the specified type are used as the types of P and A, and the deduction is done as described in [temp.deduct.type].
A placeholder type ([dcl.spec.auto]) in the return type of a function template is a non-deduced context.
If template argument deduction succeeds for such a function, the return type is determined from instantiation of the function body.

17.8.2.3 Deducing conversion function template arguments [temp.deduct.conv]

Template argument deduction is done by comparing the return type of the conversion function template (call it P) with the type that is required as the result of the conversion (call it A; see [dcl.init], [over.match.conv], and [over.match.ref] for the determination of that type) as described in [temp.deduct.type].
If P is a reference type, the type referred to by P is used in place of P for type deduction and for any further references to or transformations of P in the remainder of this section.
If A is not a reference type:
  • If P is an array type, the pointer type produced by the array-to-pointer standard conversion ([conv.array]) is used in place of P for type deduction; otherwise,
  • If P is a function type, the pointer type produced by the function-to-pointer standard conversion ([conv.func]) is used in place of P for type deduction; otherwise,
  • If P is a cv-qualified type, the top-level cv-qualifiers of P's type are ignored for type deduction.
If A is a cv-qualified type, the top-level cv-qualifiers of A's type are ignored for type deduction.
If A is a reference type, the type referred to by A is used for type deduction.
In general, the deduction process attempts to find template argument values that will make the deduced A identical to A.
However, there are four cases that allow a difference:
  • If the original A is a reference type, A can be more cv-qualified than the deduced A (i.e., the type referred to by the reference)
  • If the original A is a function pointer type, A can be “pointer to function” even if the deduced A is “pointer to noexcept function”.
  • If the original A is a pointer to member function type, A can be “pointer to member of type function” even if the deduced A is “pointer to member of type noexcept function”.
  • The deduced A can be another pointer or pointer to member type that can be converted to A via a qualification conversion.
These alternatives are considered only if type deduction would otherwise fail.
If they yield more than one possible deduced A, the type deduction fails.
When the deduction process requires a qualification conversion for a pointer or pointer to member type as described above, the following process is used to determine the deduced template argument values:
If A is a type “pointer to ” “pointer to” T1 and P is a type “pointer to ” “pointer to” T2, then the cv-unqualified T1 and T2 are used as the types of A and P respectively for type deduction.
[Example
:
struct A {
  template <class T> operator T***();
};
A a;
const int * const * const * p1 = a;     // T is deduced as int, not const int
end example
]

17.8.2.4 Deducing template arguments during partial ordering [temp.deduct.partial]

Template argument deduction is done by comparing certain types associated with the two function templates being compared.
Two sets of types are used to determine the partial ordering.
For each of the templates involved there is the original function type and the transformed function type.
[Note
:
The creation of the transformed type is described in [temp.func.order].
end note
]
The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template.
This process is done twice for each type involved in the partial ordering comparison: once using the transformed template-1 as the argument template and template-2 as the parameter template and again using the transformed template-2 as the argument template and template-1 as the parameter template.
The types used to determine the ordering depend on the context in which the partial ordering is done:
  • In the context of a function call, the types used are those function parameter types for which the function call has arguments.141
  • In the context of a call to a conversion function, the return types of the conversion function templates are used.
  • In other contexts ([temp.func.order]) the function template's function type is used.
Each type nominated above from the parameter template and the corresponding type from the argument template are used as the types of P and A.
If a particular P contains no template-parameters that participate in template argument deduction, that P is not used to determine the ordering.
Before the partial ordering is done, certain transformations are performed on the types used for partial ordering:
  • If P is a reference type, P is replaced by the type referred to.
  • If A is a reference type, A is replaced by the type referred to.
If both P and A were reference types (before being replaced with the type referred to above), determine which of the two types (if any) is more cv-qualified than the other; otherwise the types are considered to be equally cv-qualified for partial ordering purposes.
The result of this determination will be used below.
Remove any top-level cv-qualifiers:
  • If P is a cv-qualified type, P is replaced by the cv-unqualified version of P.
  • If A is a cv-qualified type, A is replaced by the cv-unqualified version of A.
Using the resulting types P and A, the deduction is then done as described in [temp.deduct.type].
If P is a function parameter pack, the type A of each remaining parameter type of the argument template is compared with the type P of the declarator-id of the function parameter pack.
Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack.
Similarly, if A was transformed from a function parameter pack, it is compared with each remaining parameter type of the parameter template.
If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template.
[Example
:
template<class... Args>           void f(Args... args);         // #1
template<class T1, class... Args> void f(T1 a1, Args... args);  // #2
template<class T1, class T2>      void f(T1 a1, T2 a2);         // #3

f();                // calls #1
f(1, 2, 3);         // calls #2
f(1, 2);            // calls #3; non-variadic template #3 is more specialized
                    // than the variadic templates #1 and #2
end example
]
If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transformations above) and both P and A were reference types (before being replaced with the type referred to above):
  • if the type from the argument template was an lvalue reference and the type from the parameter template was not, the parameter type is not considered to be at least as specialized as the argument type; otherwise,
  • if the type from the argument template is more cv-qualified than the type from the parameter template (as described above), the parameter type is not considered to be at least as specialized as the argument type.
Function template F is at least as specialized as function template G if, for each pair of types used to determine the ordering, the type from F is at least as specialized as the type from G.
F is more specialized than G if F is at least as specialized as G and G is not at least as specialized as F.
If, after considering the above, function template F is at least as specialized as function template G and vice-versa, and if G has a trailing parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing parameter pack, then F is more specialized than G.
In most cases, all template parameters must have values in order for deduction to succeed, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering.
[Note
:
A template parameter used in a non-deduced context is considered used.
end note
]
[Example
:
template <class T> T f(int);            // #1
template <class T, class U> T f(U);     // #2
void g() {
  f<int>(1);                            // calls #1
}
end example
]
[Note
:
Partial ordering of function templates containing template parameter packs is independent of the number of deduced arguments for those template parameter packs.
end note
]
[Example
:
template<class ...> struct Tuple { };
template<class ... Types> void g(Tuple<Types ...>);                 // #1
template<class T1, class ... Types> void g(Tuple<T1, Types ...>);   // #2
template<class T1, class ... Types> void g(Tuple<T1, Types& ...>);  // #3

g(Tuple<>());                   // calls #1
g(Tuple<int, float>());         // calls #2
g(Tuple<int, float&>());        // calls #3
g(Tuple<int>());                // calls #3
end example
]
Default arguments are not considered to be arguments in this context; they only become arguments after a function has been selected.

17.8.2.5 Deducing template arguments from a type [temp.deduct.type]

Template arguments can be deduced in several different contexts, but in each case a type that is specified in terms of template parameters (call it P) is compared with an actual type (call it A), and an attempt is made to find template argument values (a type for a type parameter, a value for a non-type parameter, or a template for a template parameter) that will make P, after substitution of the deduced values (call it the deduced A), compatible with A.
In some cases, the deduction is done using a single set of types P and A, in other cases, there will be a set of corresponding types P and A.
Type deduction is done independently for each P/A pair, and the deduced template argument values are then combined.
If type deduction cannot be done for any P/A pair, or if for any pair the deduction leads to more than one possible set of deduced values, or if different pairs yield different deduced values, or if any template argument remains neither deduced nor explicitly specified, template argument deduction fails.
The type of a type parameter is only deduced from an array bound if it is not otherwise deduced.
A given type P can be composed from a number of other types, templates, and non-type values:
  • A function type includes the types of each of the function parameters and the return type.
  • A pointer to member type includes the type of the class object pointed to and the type of the member pointed to.
  • A type that is a specialization of a class template (e.g., A<int>) includes the types, templates, and non-type values referenced by the template argument list of the specialization.
  • An array type includes the array element type and the value of the array bound.
In most cases, the types, templates, and non-type values that are used to compose P participate in template argument deduction.
That is, they may be used to determine the value of a template argument, and the value so determined must be consistent with the values determined elsewhere.
In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified.
If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
[Note
:
Under [temp.deduct.call] and [temp.deduct.partial], if P contains no template-parameters that appear in deduced contexts, no deduction is done, so P and A need not have the same form.
end note
]
The non-deduced contexts are:
  • The nested-name-specifier of a type that was specified using a qualified-id.
  • A non-type template argument or an array bound in which a subexpression references a template parameter.
  • A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done.
  • A function parameter for which argument deduction cannot be done because the associated function argument is a function, or a set of overloaded functions ([over.over]), and one or more of the following apply:
    • more than one function matches the function parameter type (resulting in an ambiguous deduction), or
    • no function matches the function parameter type, or
    • the set of functions supplied as an argument contains one or more function templates.
  • A function parameter for which the associated argument is an initializer list ([dcl.init.list]) but the parameter does not have a type for which deduction from an initializer list is specified ([temp.deduct.call]).
    [Example
    :
    template<class T> void g(T);
    g({1,2,3});                 // error: no argument deduced for T
    
    end example
    ]
  • A function parameter pack that does not occur at the end of the parameter-declaration-list.
When a type name is specified in a way that includes a non-deduced context, all of the types that comprise that type name are also non-deduced.
However, a compound type can include both deduced and non-deduced types.
[Example
:
If a type is specified as A<T>​::​B<T2>, both T and T2 are non-deduced.
Likewise, if a type is specified as A<I+J>​::​X<T>, I, J, and T are non-deduced.
If a type is specified as void f(typename A<T>​::​B, A<T>), the T in A<T>​::​B is non-deduced but the T in A<T> is deduced.
end example
]
[Example
:
Here is an example in which different parameter/argument pairs produce inconsistent template argument deductions:
template<class T> void f(T x, T y) { /* ... */ }
struct A { /* ... */ };
struct B : A { /* ... */ };
void g(A a, B b) {
  f(a,b);           // error: T could be A or B
  f(b,a);           // error: T could be A or B
  f(a,a);           // OK: T is A
  f(b,b);           // OK: T is B
}
Here is an example where two template arguments are deduced from a single function parameter/argument pair.
This can lead to conflicts that cause type deduction to fail:
template <class T, class U> void f(  T (*)( T, U, U )  );

int g1( int, float, float);
char g2( int, float, float);
int g3( int, char, float);

void r() {
  f(g1);            // OK: T is int and U is float
  f(g2);            // error: T could be char or int
  f(g3);            // error: U could be char or float
}
Here is an example where a qualification conversion applies between the argument type on the function call and the deduced template argument type:
template<class T> void f(const T*) { }
int* p;
void s() {
  f(p);             // f(const int*)
}
Here is an example where the template argument is used to instantiate a derived class type of the corresponding function parameter type:
template <class T> struct B { };
template <class T> struct D : public B<T> {};
struct D2 : public B<int> {};
template <class T> void f(B<T>&){}
void t() {
  D<int> d;
  D2     d2;
  f(d);             // calls f(B<int>&)
  f(d2);            // calls f(B<int>&)
}
end example
]
A template type argument T, a template template argument TT or a template non-type argument i can be deduced if P and A have one of the following forms:
T
cv-list T
T*
T&
T&&
T[integer-constant]
template-name<T>  (where template-name refers to a class template)
type(T)
T()
T(T)
T type::*
type T::*
T T::*
T (type::*)()
type (T::*)()
type (type::*)(T)
type (T::*)(T)
T (type::*)(T)
T (T::*)()
T (T::*)(T)
type[i]
template-name<i>  (where template-name refers to a class template)
TT<T>
TT<i>
TT<>
where (T) represents a parameter-type-list ([dcl.fct]) where at least one parameter type contains a T, and () represents a parameter-type-list where no parameter type contains a T.
Similarly, <T> represents template argument lists where at least one argument contains a T, <i> represents template argument lists where at least one argument contains an i and <> represents template argument lists where no argument contains a T or an i.
If P has a form that contains <T> or <i>, then each argument of the respective template argument list of P is compared with the corresponding argument of the corresponding template argument list of A.
If the template argument list of P contains a pack expansion that is not the last template argument, the entire template argument list is a non-deduced context.
If is a pack expansion, then the pattern of is compared with each remaining argument in the template argument list of A.
Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by .
During partial ordering ([temp.deduct.partial]), if was originally a pack expansion:
  • if P does not contain a template argument corresponding to then is ignored;
  • otherwise, if is not a pack expansion, template argument deduction fails.
[Example
:
template<class T1, class... Z> class S;                               // #1
template<class T1, class... Z> class S<T1, const Z&...> { };          // #2
template<class T1, class T2>   class S<T1, const T2&> { };            // #3
S<int, const int&> s;         // both #2 and #3 match; #3 is more specialized

template<class T, class... U>            struct A { };                // #1
template<class T1, class T2, class... U> struct A<T1, T2*, U...> { }; // #2
template<class T1, class T2>             struct A<T1, T2> { };        // #3
template struct A<int, int*>; // selects #2
end example
]
Similarly, if P has a form that contains (T), then each parameter type of the respective parameter-type-list ([dcl.fct]) of P is compared with the corresponding parameter type of the corresponding parameter-type-list of A.
If P and A are function types that originated from deduction when taking the address of a function template ([temp.deduct.funcaddr]) or when deducing template arguments from a function declaration ([temp.deduct.decl]) and and are parameters of the top-level parameter-type-list of P and A, respectively, is adjusted if it is a forwarding reference ([temp.deduct.call]) and is an lvalue reference, in which case the type of is changed to be the template parameter type (i.e., T&& is changed to simply T).
[Note
:
As a result, when is T&& and is X&, the adjusted will be T, causing T to be deduced as X&.
end note
]
[Example
:
template <class T> void f(T&&);
template <> void f(int&) { }    // #1
template <> void f(int&&) { }   // #2
void g(int i) {
  f(i);                         // calls f<int&>(int&), i.e., #1
  f(0);                         // calls f<int>(int&&), i.e., #2
}
end example
]
If the parameter-declaration corresponding to is a function parameter pack, then the type of its declarator-id is compared with each remaining parameter type in the parameter-type-list of A.
Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack.
During partial ordering ([temp.deduct.partial]), if was originally a function parameter pack:
  • if P does not contain a function parameter type corresponding to then is ignored;
  • otherwise, if is not a function parameter pack, template argument deduction fails.
[Example
:
template<class T, class... U> void f(T*, U...) { }  // #1
template<class T>             void f(T) { }         // #2
template void f(int*);                              // selects #1
end example
]
These forms can be used in the same way as T is for further composition of types.
[Example
:
X<int> (*)(char[6])
is of the form
template-name<T> (*)(type[i])
which is a variant of
type (*)(T)
where type is X<int> and T is char[6].
end example
]
Template arguments cannot be deduced from function arguments involving constructs other than the ones specified above.
When the value of the argument corresponding to a non-type template parameter P that is declared with a dependent type is deduced from an expression, the template parameters in the type of P are deduced from the type of the value.
[Example
:
template<long n> struct A { };

template<typename T> struct C;
template<typename T, T n> struct C<A<n>> {
  using Q = T;
};

using R = long;
using R = C<A<2>>::Q;           // OK; T was deduced to long from the
                                // template argument value in the type A<2>
end example
]
The type of N in the type T[N] is std​::​size_­t.
[Example
:
template<typename T> struct S;
template<typename T, T n> struct S<int[n]> {
  using Q = T;
};

using V = decltype(sizeof 0);
using V = S<int[42]>::Q;        // OK; T was deduced to std​::​size_­t from the type int[42]
end example
]
[Example
:
template<class T, T i> void f(int (&a)[i]);
int v[10];
void g() {
  f(v);                         // OK: T is std​::​size_­t
}
end example
]
[Note
:
Except for reference and pointer types, a major array bound is not part of a function parameter type and cannot be deduced from an argument:
template<int i> void f1(int a[10][i]);
template<int i> void f2(int a[i][20]);
template<int i> void f3(int (&a)[i][20]);

void g() {
  int v[10][20];
  f1(v);                        // OK: i deduced to be 20
  f1<20>(v);                    // OK
  f2(v);                        // error: cannot deduce template-argument i
  f2<10>(v);                    // OK
  f3(v);                        // OK: i deduced to be 10
}
end note
]
[Note
:
If, in the declaration of a function template with a non-type template parameter, the non-type template parameter is used in a subexpression in the function parameter list, the expression is a non-deduced context as specified above.
[Example
:
template <int i> class A { /* ... */ };
template <int i> void g(A<i+1>);
template <int i> void f(A<i>, A<i+1>);
void k() {
  A<1> a1;
  A<2> a2;
  g(a1);                        // error: deduction fails for expression i+1
  g<0>(a1);                     // OK
  f(a1, a2);                    // OK
}
end example
]
end note
]
[Note
:
Template parameters do not participate in template argument deduction if they are used only in non-deduced contexts.
For example,
template<int i, typename T>
T deduce(typename A<T>::X x,    // T is not deduced here
         T t,                   // but T is deduced here
         typename B<i>::Y y);   // i is not deduced here
A<int> a;
B<77>  b;

int    x = deduce<77>(a.xm, 62, b.ym);
// T is deduced to be int, a.xm must be convertible to A<int>​::​X
// i is explicitly specified to be 77, b.ym must be convertible to B<77>​::​Y
end note
]
If P has a form that contains <i>, and if the type of i differs from the type of the corresponding template parameter of the template named by the enclosing simple-template-id, deduction fails.
If P has a form that contains [i], and if the type of i is not an integral type, deduction fails.142
[Example
:
template<int i> class A { /* ... */ };
template<short s> void f(A<s>);
void k1() {
  A<1> a;
  f(a);             // error: deduction fails for conversion from int to short
  f<1>(a);          // OK
}

template<const short cs> class B { };
template<short s> void g(B<s>);
void k2() {
  B<1> b;
  g(b);             // OK: cv-qualifiers are ignored on template parameter types
}
end example
]
A template-argument can be deduced from a function, pointer to function, or pointer to member function type.
[Example
:
template<class T> void f(void(*)(T,int));
template<class T> void foo(T,int);
void g(int,int);
void g(char,int);

void h(int,int,int);
void h(char,int);
int m() {
  f(&g);            // error: ambiguous
  f(&h);            // OK: void h(char,int) is a unique match
  f(&foo);          // error: type deduction fails because foo is a template
}
end example
]
A template type-parameter cannot be deduced from the type of a function default argument.
[Example
:
template <class T> void f(T = 5, T = 7);
void g() {
  f(1);             // OK: call f<int>(1,7)
  f();              // error: cannot deduce T
  f<int>();         // OK: call f<int>(5,7)
}
end example
]
The template-argument corresponding to a template template-parameter is deduced from the type of the template-argument of a class template specialization used in the argument list of a function call.
[Example
:
template <template <class T> class X> struct A { };
template <template <class T> class X> void f(A<X>) { }
template<class T> struct B { };
A<B> ab;
f(ab);              // calls f(A<B>)
end example
]
[Note
:
Template argument deduction involving parameter packs ([temp.variadic]) can deduce zero or more arguments for each parameter pack.
end note
]
[Example
:
template<class> struct X { };
template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { };
template<class ... Types> struct Y { };
template<class T, class ... Types> struct Y<T, Types& ...> { };

template<class ... Types> int f(void (*)(Types ...));
void g(int, float);

X<int> x1;                      // uses primary template
X<int(int, float, double)> x2;  // uses partial specialization; ArgTypes contains float, double
X<int(float, int)> x3;          // uses primary template
Y<> y1;                         // use primary template; Types is empty
Y<int&, float&, double&> y2;    // uses partial specialization; T is int&, Types contains float, double
Y<int, float, double> y3;       // uses primary template; Types contains int, float, double
int fv = f(g);                  // OK; Types contains int, float
end example
]
Although the template-argument corresponding to a template-parameter of type bool may be deduced from an array bound, the resulting value will always be true because the array bound will be nonzero.

17.8.2.6 Deducing template arguments from a function declaration [temp.deduct.decl]

In a declaration whose declarator-id refers to a specialization of a function template, template argument deduction is performed to identify the specialization to which the declaration refers.
Specifically, this is done for explicit instantiations ([temp.explicit]), explicit specializations ([temp.expl.spec]), and certain friend declarations ([temp.friend]).
This is also done to determine whether a deallocation function template specialization matches a placement operator new ([basic.stc.dynamic.deallocation], [expr.new]).
In all these cases, P is the type of the function template being considered as a potential match and A is either the function type from the declaration or the type of the deallocation function that would match the placement operator new as described in [expr.new].
The deduction is done as described in [temp.deduct.type].
If, for the set of function templates so considered, there is either no match or more than one match after partial ordering has been considered ([temp.func.order]), deduction fails and, in the declaration cases, the program is ill-formed.

17.8.3 Overload resolution [temp.over]

A function template can be overloaded either by (non-template) functions of its name or by (other) function templates of the same name.
When a call to that name is written (explicitly, or implicitly using the operator notation), template argument deduction ([temp.deduct]) and checking of any explicit template arguments ([temp.arg]) are performed for each function template to find the template argument values (if any) that can be used with that function template to instantiate a function template specialization that can be invoked with the call arguments.
For each function template, if the argument deduction and checking succeeds, the template-arguments (deduced and/or explicit) are used to synthesize the declaration of a single function template specialization which is added to the candidate functions set to be used in overload resolution.
If, for a given function template, argument deduction fails or the synthesized function template specialization would be ill-formed, no such function is added to the set of candidate functions for that template.
The complete set of candidate functions includes all the synthesized declarations and all of the non-template overloaded functions of the same name.
The synthesized declarations are treated like any other functions in the remainder of overload resolution, except as explicitly noted in [over.match.best].143
[Example
:
template<class T> T max(T a, T b) { return a>b?a:b; }

void f(int a, int b, char c, char d) {
  int m1 = max(a,b);            // max(int a, int b)
  char m2 = max(c,d);           // max(char a, char b)
  int m3 = max(a,c);            // error: cannot generate max(int,char)
}
Adding the non-template function
int max(int,int);
to the example above would resolve the third call, by providing a function that could be called for max(a,c) after using the standard conversion of char to int for c.
end example
]
[Example
:
Here is an example involving conversions on a function argument involved in template-argument deduction:
template<class T> struct B { /* ... */ };
template<class T> struct D : public B<T> { /* ... */ };
template<class T> void f(B<T>&);

void g(B<int>& bi, D<int>& di) {
  f(bi);            // f(bi)
  f(di);            // f((B<int>&)di)
}
end example
]
[Example
:
Here is an example involving conversions on a function argument not involved in template-parameter deduction:
template<class T> void f(T*,int);       // #1
template<class T> void f(T,char);       // #2

void h(int* pi, int i, char c) {
  f(pi,i);          // #1: f<int>(pi,i)
  f(pi,c);          // #2: f<int*>(pi,c)

  f(i,c);           // #2: f<int>(i,c);
  f(i,i);           // #2: f<int>(i,char(i))
}
end example
]
Only the signature of a function template specialization is needed to enter the specialization in a set of candidate functions.
Therefore only the function template declaration is needed to resolve a call for which a template specialization is a candidate.
[Example
:
template<class T> void f(T);    // declaration

void g() {
  f("Annemarie");               // call of f<const char*>
}
The call of f is well-formed even if the template f is only declared and not defined at the point of the call.
The program will be ill-formed unless a specialization for f<const char*>, either implicitly or explicitly generated, is present in some translation unit.
end example
]
The parameters of function template specializations contain no template parameter types.
The set of conversions allowed on deduced arguments is limited, because the argument deduction process produces function templates with parameters that either match the call arguments exactly or differ only in ways that can be bridged by the allowed limited conversions.
Non-deduced arguments allow the full range of conversions.
Note also that [over.match.best] specifies that a non-template function will be given preference over a template specialization if the two functions are otherwise equally good candidates for an overload match.

17.9 Deduction guides [temp.deduct.guide]

Deduction guides are used when a template-name appears as a type specifier for a deduced class type ([dcl.type.class.deduct]).
Deduction guides are not found by name lookup.
Instead, when performing class template argument deduction ([over.match.class.deduct]), any deduction guides declared for the class template are considered.
[Example
:
template<class T, class D = int>
struct S {
  T data;
};
template<class U>
S(U) -> S<typename U::type>;

struct A {
  using type = short;
  operator type();
};
S x{A()};           // x is of type S<short, int>
end example
]
The same restrictions apply to the parameter-declaration-clause of a deduction guide as in a function declaration ([dcl.fct]).
The simple-template-id shall name a class template specialization.
The template-name shall be the same identifier as the template-name of the simple-template-id.
A deduction-guide shall be declared in the same scope as the corresponding class template and, for a member class template, with the same access.
Two deduction guide declarations in the same translation unit for the same class template shall not have equivalent parameter-declaration-clauses.

18 Exception handling [except]

Exception handling provides a way of transferring control and information from a point in the execution of a thread to an exception handler associated with a point previously passed by the execution.
A handler will be invoked only by throwing an exception in code executed in the handler's try block or in functions called from the handler's try block.
[Note
:
Within this Clause “try block” is taken to mean both try-block and function-try-block.
end note
]
A goto or switch statement shall not be used to transfer control into a try block or into a handler.
[Example
:
void f() {
  goto l1;          // ill-formed
  goto l2;          // ill-formed
  try {
    goto l1;        // OK
    goto l2;        // ill-formed
    l1: ;
  } catch (...) {
    l2: ;
    goto l1;        // ill-formed
    goto l2;        // OK
  }
}
end example
]
A goto, break, return, or continue statement can be used to transfer control out of a try block or handler.
When this happens, each variable declared in the try block will be destroyed in the context that directly contains its declaration.
[Example
:
lab:  try {
  T1 t1;
  try {
    T2 t2;
    if (condition)
      goto lab;
    } catch(...) { /* handler 2 */ }
  } catch(...) { /* handler 1 */ }
Here, executing goto lab; will destroy first t2, then t1, assuming the condition does not declare a variable.
Any exception thrown while destroying t2 will result in executing handler 2; any exception thrown while destroying t1 will result in executing handler 1.
end example
]
A function-try-block associates a handler-seq with the ctor-initializer, if present, and the compound-statement.
An exception thrown during the execution of the compound-statement or, for constructors and destructors, during the initialization or destruction, respectively, of the class's subobjects, transfers control to a handler in a function-try-block in the same way as an exception thrown during the execution of a try-block transfers control to other handlers.
[Example
:
int f(int);
class C {
  int i;
  double d;
public:
  C(int, double);
};

C::C(int ii, double id)
try : i(f(ii)), d(id) {
    // constructor statements
} catch (...) {
    // handles exceptions thrown from the ctor-initializer and from the constructor statements
}
end example
]
In this section, “before” and “after” refer to the “sequenced before” relation ([intro.execution]).

18.1 Throwing an exception [except.throw]

Throwing an exception transfers control to a handler.
[Note
:
An exception can be thrown from one of the following contexts: throw-expressions ([expr.throw]), allocation functions ([basic.stc.dynamic.allocation]), dynamic_­cast ([expr.dynamic.cast]), typeid ([expr.typeid]), new-expressions ([expr.new]), and standard library functions ([structure.specifications]).
end note
]
An object is passed and the type of that object determines which handlers can catch it.
[Example
:
throw "Help!";
can be caught by a handler of const char* type:
try {
    // ...
} catch(const char* p) {
    // handle character string exceptions here
}
and
class Overflow {
public:
    Overflow(char,double,double);
};

void f(double x) {
    throw Overflow('+',x,3.45e107);
}
can be caught by a handler for exceptions of type Overflow:
try {
    f(1.2);
} catch(Overflow& oo) {
    // handle exceptions of type Overflow here
}
end example
]
When an exception is thrown, control is transferred to the nearest handler with a matching type ([except.handle]); “nearest” means the handler for which the compound-statement or ctor-initializer following the try keyword was most recently entered by the thread of control and not yet exited.
Throwing an exception copy-initializes ([dcl.init], [class.copy]) a temporary object, called the exception object.
An lvalue denoting the temporary is used to initialize the variable declared in the matching handler ([except.handle]).
If the type of the exception object would be an incomplete type or a pointer to an incomplete type other than cv void the program is ill-formed.
The memory for the exception object is allocated in an unspecified way, except as noted in [basic.stc.dynamic.allocation].
If a handler exits by rethrowing, control is passed to another handler for the same exception object.
The points of potential destruction for the exception object are:
  • when an active handler for the exception exits by any means other than rethrowing, immediately after the destruction of the object (if any) declared in the exception-declaration in the handler;
  • when an object of type std​::​exception_­ptr ([propagation]) that refers to the exception object is destroyed, before the destructor of std​::​exception_­ptr returns.
Among all points of potential destruction for the exception object, there is an unspecified last one where the exception object is destroyed.
All other points happen before that last one ([intro.races]).
[Note
:
No other thread synchronization is implied in exception handling.
end note
]
The implementation may then deallocate the memory for the exception object; any such deallocation is done in an unspecified way.
[Note
:
A thrown exception does not propagate to other threads unless caught, stored, and rethrown using appropriate library functions; see [propagation] and [futures].
end note
]
When the thrown object is a class object, the constructor selected for the copy-initialization as well as the constructor selected for a copy-initialization considering the thrown object as an lvalue shall be non-deleted and accessible, even if the copy/move operation is elided ([class.copy]).
The destructor is potentially invoked ([class.dtor]).
An exception is considered caught when a handler for that exception becomes active ([except.handle]).
[Note
:
An exception can have active handlers and still be considered uncaught if it is rethrown.
end note
]
If the exception handling mechanism handling an uncaught exception ([except.uncaught]) directly invokes a function that exits via an exception, std​::​terminate is called ([except.terminate]).
[Example
:
struct C {
  C() { }
  C(const C&) {
    if (std::uncaught_exceptions()) {
      throw 0;      // throw during copy to handler's exception-declaration object ([except.handle])
    }
  }
};

int main() {
  try {
    throw C();      // calls std​::​terminate() if construction of the handler's
                    // exception-declaration object is not elided ([class.copy])
  } catch(C) { }
}
end example
]
[Note
:
Consequently, destructors should generally catch exceptions and not let them propagate.
end note
]

18.2 Constructors and destructors [except.ctor]

As control passes from the point where an exception is thrown to a handler, destructors are invoked by a process, specified in this section, called stack unwinding.
The destructor is invoked for each automatic object of class type constructed, but not yet destroyed, since the try block was entered.
If an exception is thrown during the destruction of temporaries or local variables for a return statement ([stmt.return]), the destructor for the returned object (if any) is also invoked.
The objects are destroyed in the reverse order of the completion of their construction.
[Example
:
struct A { };

struct Y { ~Y() noexcept(false) { throw 0; } };

A f() {
  try {
    A a;
    Y y;
    A b;
    return {};      // #1
  } catch (...) {
  }
  return {};        // #2
}
At #1, the returned object of type A is constructed.
Then, the local variable b is destroyed ([stmt.jump]).
Next, the local variable y is destroyed, causing stack unwinding, resulting in the destruction of the returned object, followed by the destruction of the local variable a.
Finally, the returned object is constructed again at #2.
end example
]
If the initialization or destruction of an object other than by delegating constructor is terminated by an exception, the destructor is invoked for each of the object's direct subobjects and, for a complete object, virtual base class subobjects, whose initialization has completed ([dcl.init]) and whose destructor has not yet begun execution, except that in the case of destruction, the variant members of a union-like class are not destroyed.
The subobjects are destroyed in the reverse order of the completion of their construction.
Such destruction is sequenced before entering a handler of the function-try-block of the constructor or destructor, if any.
If the compound-statement of the function-body of a delegating constructor for an object exits via an exception, the object's destructor is invoked.
Such destruction is sequenced before entering a handler of the function-try-block of a delegating constructor for that object, if any.
[Note
:
If the object was allocated by a new-expression ([expr.new]), the matching deallocation function ([basic.stc.dynamic.deallocation]), if any, is called to free the storage occupied by the object.
end note
]

18.3 Handling an exception [except.handle]

The exception-declaration in a handler describes the type(s) of exceptions that can cause that handler to be entered.
The exception-declaration shall not denote an incomplete type, an abstract class type, or an rvalue reference type.
The exception-declaration shall not denote a pointer or reference to an incomplete type, other than void*, const void*, volatile void*, or const volatile void*.
A handler of type “array of T” or function type T is adjusted to be of type “pointer to T.
A handler is a match for an exception object of type E if
  • The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv-qualifiers), or
  • the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
  • the handler is of type cv T or const T& where T is a pointer or pointer to member type and E is a pointer or pointer to member type that can be converted to T by one or more of
  • the handler is of type cv T or const T& where T is a pointer or pointer to member type and E is std​::​nullptr_­t.
[Note
:
A throw-expression whose operand is an integer literal with value zero does not match a handler of pointer or pointer to member type.
A handler of reference to array or function type is never a match for any exception object ([expr.throw]).
end note
]
[Example
:
class Matherr { /* ... */ virtual void vf(); };
class Overflow: public Matherr { /* ... */ };
class Underflow: public Matherr { /* ... */ };
class Zerodivide: public Matherr { /* ... */ };

void f() {
  try {
    g();
  } catch (Overflow oo) {
    // ...
  } catch (Matherr mm) {
    // ...
  }
}
Here, the Overflow handler will catch exceptions of type Overflow and the Matherr handler will catch exceptions of type Matherr and of all types publicly derived from Matherr including exceptions of type Underflow and Zerodivide.
end example
]
The handlers for a try block are tried in order of appearance.
[Note
:
This makes it possible to write handlers that can never be executed, for example by placing a handler for a final derived class after a handler for a corresponding unambiguous public base class.
end note
]
A ... in a handler's exception-declaration functions similarly to ... in a function parameter declaration; it specifies a match for any exception.
If present, a ... handler shall be the last handler for its try block.
If no match is found among the handlers for a try block, the search for a matching handler continues in a dynamically surrounding try block of the same thread.
A handler is considered active when initialization is complete for the parameter (if any) of the catch clause.
[Note
:
The stack will have been unwound at that point.
end note
]
Also, an implicit handler is considered active when std​::​terminate() is entered due to a throw.
A handler is no longer considered active when the catch clause exits.
The exception with the most recently activated handler that is still active is called the currently handled exception.
If no matching handler is found, the function std​::​terminate() is called; whether or not the stack is unwound before this call to std​::​terminate() is implementation-defined ([except.terminate]).
Referring to any non-static member or base class of an object in the handler for a function-try-block of a constructor or destructor for that object results in undefined behavior.
The scope and lifetime of the parameters of a function or constructor extend into the handlers of a function-try-block.
Exceptions thrown in destructors of objects with static storage duration or in constructors of namespace-scope objects with static storage duration are not caught by a function-try-block on the main function ([basic.start.main]).
Exceptions thrown in destructors of objects with thread storage duration or in constructors of namespace-scope objects with thread storage duration are not caught by a function-try-block on the initial function of the thread.
If a return statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.
The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor.
Otherwise, flowing off the end of the compound-statement of a handler of a function-try-block is equivalent to flowing off the end of the compound-statement of that function (see [stmt.return]).
The variable declared by the exception-declaration, of type cv T or cv T&, is initialized from the exception object, of type E, as follows:
  • if T is a base class of E, the variable is copy-initialized ([dcl.init]) from the corresponding base class subobject of the exception object;
  • otherwise, the variable is copy-initialized ([dcl.init]) from the exception object.
The lifetime of the variable ends when the handler exits, after the destruction of any automatic objects initialized within the handler.
When the handler declares an object, any changes to that object will not affect the exception object.
When the handler declares a reference to an object, any changes to the referenced object are changes to the exception object and will have effect should that object be rethrown.

18.4 Exception specifications [except.spec]

The predicate indicating whether a function cannot exit via an exception is called the exception specification of the function.
If the predicate is false, the function has a potentially-throwing exception specification, otherwise it has a non-throwing exception specification.
The exception specification is either defined implicitly, or defined explicitly by using a noexcept-specifier as a suffix of a function declarator ([dcl.fct]).
noexcept-specifier:
	noexcept ( constant-expression )
	noexcept
	throw ( )
In a noexcept-specifier, the constant-expression, if supplied, shall be a contextually converted constant expression of type bool ([expr.const]); that constant expression is the exception specification of the function type in which the noexcept-specifier appears.
A ( token that follows noexcept is part of the noexcept-specifier and does not commence an initializer ([dcl.init]).
The noexcept-specifier noexcept without a constant-expression is equivalent to the noexcept-specifier noexcept(true).
The noexcept-specifier throw() is deprecated ([depr.except.spec]), and equivalent to the noexcept-specifier noexcept(true).
If a declaration of a function does not have a noexcept-specifier, the declaration has a potentially throwing exception specification unless it is a destructor or a deallocation function or is defaulted on its first declaration, in which cases the exception specfication is as specified below and no other declaration for that function shall have a noexcept-specifier.
In an explicit instantiation ([temp.explicit]) a noexcept-specifier may be specified, but is not required.
If a noexcept-specifier is specified in an explicit instantiation directive, the exception specification shall be the same as the exception specification of all other declarations of that function.
A diagnostic is required only if the exception specifications are not the same within a single translation unit.
If a virtual function has a non-throwing exception specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall have a non-throwing exception specification, unless the overriding function is defined as deleted.
[Example
:
struct B {
  virtual void f() noexcept;
  virtual void g();
  virtual void h() noexcept = delete;
};

struct D: B {
  void f();                     // ill-formed
  void g() noexcept;            // OK
  void h() = delete;            // OK
};
The declaration of D​::​f is ill-formed because it has a potentially-throwing exception specification, whereas B​::​f has a non-throwing exception specification.
end example
]
Whenever an exception is thrown and the search for a handler ([except.handle]) encounters the outermost block of a function with a non-throwing exception specification, the function std​::​terminate() is called ([except.terminate]).
[Note
:
An implementation shall not reject an expression merely because, when executed, it throws or might throw an exception from a function with a non-throwing exception specification.
end note
]
[Example
:
extern void f();                // potentially-throwing

void g() noexcept {
  f();                          // valid, even if f throws
  throw 42;                     // valid, effectively a call to std​::​terminate
}
The call to f is well-formed even though, when called, f might throw an exception.
end example
]
An expression e is potentially-throwing if
  • e is a function call ([expr.call]) whose postfix-expression has a function type, or a pointer-to-function type, with a potentially-throwing exception specification, or
  • e implicitly invokes a function (such as an overloaded operator, an allocation function in a new-expression, a constructor for a function argument, or a destructor if e is a full-expression ([intro.execution])) that is potentially-throwing, or
  • e is a throw-expression, or
  • e is a dynamic_­cast expression that casts to a reference type and requires a runtime check ([expr.dynamic.cast]), or
  • e is a typeid expression applied to a (possibly parenthesized) built-in unary * operator applied to a pointer to a polymorphic class type ([expr.typeid]), or
  • any of the immediate subexpressions ([intro.execution]) of e is potentially-throwing.
An implicitly-declared constructor for a class X, or a constructor without a noexcept-specifier that is defaulted on its first declaration, has a potentially-throwing exception specification if and only if any of the following constructs is potentially-throwing:
  • a constructor selected by overload resolution in the implicit definition of the constructor for class X to initialize a potentially constructed subobject, or
  • a subexpression of such an initialization, such as a default argument expression, or,
  • for a default constructor, a default member initializer.
[Note
:
Even though destructors for fully-constructed subobjects are invoked when an exception is thrown during the execution of a constructor ([except.ctor]), their exception specifications do not contribute to the exception specification of the constructor, because an exception thrown from such a destructor would call std​::​terminate rather than escape the constructor ([except.throw], [except.terminate]).
end note
]
The exception specification for an implicitly-declared destructor, or a destructor without a noexcept-specifier, is potentially-throwing if and only if any of the destructors for any of its potentially constructed subojects is potentially throwing.
The exception specification for an implicitly-declared assignment operator, or an assignment-operator without a noexcept-specifier that is defaulted on its first declaration, is potentially-throwing if and only if the invocation of any assignment operator in the implicit definition is potentially-throwing.
A deallocation function ([basic.stc.dynamic.deallocation]) with no explicit noexcept-specifier has a non-throwing exception specification.
[Example
:
struct A {
  A(int = (A(5), 0)) noexcept;
  A(const A&) noexcept;
  A(A&&) noexcept;
  ~A();
};
struct B {
  B() throw();
  B(const B&) = default;        // implicit exception specification is noexcept(true)
  B(B&&, int = (throw Y(), 0)) noexcept;
  ~B() noexcept(false);
};
int n = 7;
struct D : public A, public B {
    int * p = new int[n];
    // D​::​D() potentially-throwing, as the new operator may throw bad_­alloc or bad_­array_­new_­length
    // D​::​D(const D&) non-throwing
    // D​::​D(D&&) potentially-throwing, as the default argument for B's constructor may throw
    // D​::​ D() potentially-throwing
};
Furthermore, if A​::​~A() were virtual, the program would be ill-formed since a function that overrides a virtual function from a base class shall not have a potentially-throwing exception specification if the base class function has a non-throwing exception specification.
end example
]
An exception specification is considered to be needed when:
  • in an expression, the function is the unique lookup result or the selected member of a set of overloaded functions ([basic.lookup], [over.match], [over.over]);
  • the function is odr-used ([basic.def.odr]) or, if it appears in an unevaluated operand, would be odr-used if the expression were potentially-evaluated;
  • the exception specification is compared to that of another declaration (e.g., an explicit specialization or an overriding virtual function);
  • the function is defined; or
  • the exception specification is needed for a defaulted special member function that calls the function.
    [Note
    :
    A defaulted declaration does not require the exception specification of a base member function to be evaluated until the implicit exception specification of the derived function is needed, but an explicit noexcept-specifier needs the implicit exception specification to compare against.
    end note
    ]
The exception specification of a defaulted special member function is evaluated as described above only when needed; similarly, the noexcept-specifier of a specialization of a function template or member function of a class template is instantiated only when needed.

18.5 Special functions [except.special]

The function std​::​terminate() ([except.terminate]) is used by the exception handling mechanism for coping with errors related to the exception handling mechanism itself.
The function std​::​current_­exception() ([propagation]) and the class std​::​nested_­exception ([except.nested]) can be used by a program to capture the currently handled exception.

18.5.1 The std​::​terminate() function [except.terminate]

In some situations exception handling must be abandoned for less subtle error handling techniques.
[Note
:
These situations are:
end note
]
In such cases, std​::​terminate() is called ([exception.terminate]).
In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std​::​terminate() is called.
In the situation where the search for a handler ([except.handle]) encounters the outermost block of a function with a non-throwing exception specification ([except.spec]), it is implementation-defined whether the stack is unwound, unwound partially, or not unwound at all before std​::​terminate() is called.
In all other situations, the stack shall not be unwound before std​::​terminate() is called.
An implementation is not permitted to finish stack unwinding prematurely based on a determination that the unwind process will eventually cause a call to std​::​terminate().

18.5.2 The std​::​uncaught_­exceptions() function [except.uncaught]

An exception is considered uncaught after completing the initialization of the exception object ([except.throw]) until completing the activation of a handler for the exception ([except.handle]).
This includes stack unwinding.
If an exception is rethrown ([expr.throw], [propagation]), it is considered uncaught from the point of rethrow until the rethrown exception is caught.
The function std​::​uncaught_­exceptions() ([uncaught.exceptions]) returns the number of uncaught exceptions in the current thread.

19 Preprocessing directives [cpp]

A preprocessing directive consists of a sequence of preprocessing tokens that satisfies the following constraints: The first token in the sequence is a # preprocessing token that (at the start of translation phase 4) is either the first character in the source file (optionally after white space containing no new-line characters) or that follows white space containing at least one new-line character.
The last token in the sequence is the first new-line character that follows the first token in the sequence.144
A new-line character ends the preprocessing directive even if it occurs within what would otherwise be an invocation of a function-like macro.
A text line shall not begin with a # preprocessing token.
A conditionally-supported-directive shall not begin with any of the directive names appearing in the syntax.
A conditionally-supported-directive is conditionally-supported with implementation-defined semantics.
When in a group that is skipped ([cpp.cond]), the directive syntax is relaxed to allow any sequence of preprocessing tokens to occur between the directive name and the following new-line character.
The only white-space characters that shall appear between preprocessing tokens within a preprocessing directive (from just after the introducing # preprocessing token through just before the terminating new-line character) are space and horizontal-tab (including spaces that have replaced comments or possibly other white-space characters in translation phase 3).
The implementation can process and skip sections of source files conditionally, include other source files, and replace macros.
These capabilities are called preprocessing, because conceptually they occur before translation of the resulting translation unit.
The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated.
[Example
:
In:
#define EMPTY
EMPTY   #   include <file.h>
the sequence of preprocessing tokens on the second line is not a preprocessing directive, because it does not begin with a # at the start of translation phase 4, even though it will do so after the macro EMPTY has been replaced.
end example
]
Thus, preprocessing directives are commonly called “lines”.
These “lines” have no other syntactic significance, as all white space is equivalent except in certain situations during preprocessing (see the # character string literal creation operator in [cpp.stringize], for example).

19.1 Conditional inclusion [cpp.cond]

The expression that controls conditional inclusion shall be an integral constant expression except that identifiers (including those lexically identical to keywords) are interpreted as described below145 and it may contain zero or more defined-macro-expressions and/or has-include-expressions as unary operator expressions.
A defined-macro-expression evaluates to 1 if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.
The third and fourth forms of has-include-expression are considered only if neither of the first or second forms matches, in which case the preprocessing tokens are processed just as in normal text.
The header or source file identified by the parenthesized preprocessing token sequence in each contained has-include-expression is searched for as if that preprocessing token sequence were the pp-tokens in a #include directive, except that no further macro expansion is performed.
If such a directive would not satisfy the syntactic requirements of a #include directive, the program is ill-formed.
The has-include-expression evaluates to 1 if the search for the source file succeeds, and to 0 if the search fails.
The #ifdef and #ifndef directives, and the defined conditional inclusion operator, shall treat __has_­include as if it were the name of a defined macro.
The identifier __has_­include shall not appear in any context not mentioned in this section.
Each preprocessing token that remains (in the list of preprocessing tokens that will become the controlling expression) after all macro replacements have occurred shall be in the lexical form of a token ([lex.token]).
Preprocessing directives of the forms
# if		constant-expression new-line group
# elif		constant-expression new-line group
check whether the controlling constant expression evaluates to nonzero.
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text.
If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined.
After all replacements due to macro expansion and evaluations of defined-macro-expressions and has-include-expressions have been performed, all remaining identifiers and keywords, except for true and false, are replaced with the pp-number 0, and then each preprocessing token is converted into a token.
[Note
:
An alternative token ([lex.digraph]) is not an identifier, even when its spelling consists entirely of letters and underscores.
Therefore it is not subject to this replacement.
end note
]
The resulting tokens comprise the controlling constant expression which is evaluated according to the rules of [expr.const] using arithmetic that has at least the ranges specified in [support.limits].
For the purposes of this token conversion and evaluation all signed and unsigned integer types act as if they have the same representation as, respectively, intmax_­t or uintmax_­t ([cstdint]).
[Note
:
Thus on an implementation where std​::​numeric_­limits<int>​::​max() is 0x7FFF and std​::​numeric_­limits<unsigned int>​::​max() is 0xFFFF, the integer literal 0x8000 is signed and positive within a #if expression even though it is unsigned in translation phase 7 ([lex.phases]).
end note
]
This includes interpreting character literals, which may involve converting escape sequences into execution character set members.
Whether the numeric value for these character literals matches the value obtained when an identical character literal occurs in an expression (other than within a #if or #elif directive) is implementation-defined.
[Note
:
Thus, the constant expression in the following #if directive and if statement is not guaranteed to evaluate to the same value in these two contexts:
#if 'z' - 'a' == 25
if ('z' - 'a' == 25)
end note
]
Also, whether a single-character character literal may have a negative value is implementation-defined.
Each subexpression with type bool is subjected to integral promotion before processing continues.
Preprocessing directives of the forms
# ifdef		identifier new-line group
# ifndef		identifier new-line group
check whether the identifier is or is not currently defined as a macro name.
Their conditions are equivalent to #if defined identifier and #if !defined identifier respectively.
Each directive's condition is checked in order.
If it evaluates to false (zero), the group that it controls is skipped: directives are processed only through the name that determines the directive in order to keep track of the level of nested conditionals; the rest of the directives' preprocessing tokens are ignored, as are the other preprocessing tokens in the group.
Only the first group whose control condition evaluates to true (nonzero) is processed; any following groups are skipped and their controlling directives are processed as if they were in a group that is skipped.
If none of the conditions evaluates to true, and there is a #else directive, the group controlled by the #else is processed; lacking a #else directive, all the groups until the #endif are skipped.146
[Example
:
This demonstrates a way to include a library optional facility only if it is available:
#if __has_include(<optional>)
#  include <optional>
#  define have_optional 1
#elif __has_include(<experimental/optional>)
#  include <experimental/optional>
#  define have_optional 1
#  define experimental_optional 1
#else
#  define have_optional 0
#endif
end example
]
Because the controlling constant expression is evaluated during translation phase 4, all identifiers either are or are not macro names — there simply are no keywords, enumeration constants, etc.
As indicated by the syntax, a preprocessing token shall not follow a #else or #endif directive before the terminating new-line character.
However, comments may appear anywhere in a source file, including within a preprocessing directive.

19.2 Source file inclusion [cpp.include]

A #include directive shall identify a header or source file that can be processed by the implementation.
A preprocessing directive of the form
# include < h-char-sequence > new-line
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header.
How the places are specified or the header identified is implementation-defined.
A preprocessing directive of the form
# include " q-char-sequence " new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters.
The named source file is searched for in an implementation-defined manner.
If this search is not supported, or if the search fails, the directive is reprocessed as if it read
# include < h-char-sequence > new-line
with the identical contained sequence (including > characters, if any) from the original directive.
A preprocessing directive of the form
# include pp-tokens new-line
(that does not match one of the two previous forms) is permitted.
The preprocessing tokens after include in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined.147 The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.
The implementation shall provide unique mappings for sequences consisting of one or more nondigits or digits followed by a period (.) and a single nondigit.
The first character shall not be a digit.
The implementation may ignore distinctions of alphabetical case.
A #include preprocessing directive may appear in a source file that has been read because of a #include directive in another file, up to an implementation-defined nesting limit.
[Note
:
Although an implementation may provide a mechanism for making arbitrary source files available to the < > search, in general programmers should use the < > form for headers provided with the implementation, and the " " form for sources outside the control of the implementation.
For instance:
#include <stdio.h>
#include <unistd.h>
#include "usefullib.h"
#include "myprog.h"
end note
]
[Example
:
This illustrates macro-replaced #include directives:
#if VERSION == 1
    #define INCFILE  "vers1.h"
#elif VERSION == 2
    #define INCFILE  "vers2.h"  // and so on
#else
    #define INCFILE  "versN.h"
#endif
#include INCFILE
end example
]
Note that adjacent string literals are not concatenated into a single string literal (see the translation phases in [lex.phases]); thus, an expansion that results in two string literals is an invalid directive.

19.3 Macro replacement [cpp.replace]

Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.
An identifier currently defined as an object-like macro (see below) may be redefined by another #define preprocessing directive provided that the second definition is an object-like macro definition and the two replacement lists are identical, otherwise the program is ill-formed.
Likewise, an identifier currently defined as a function-like macro (see below) may be redefined by another #define preprocessing directive provided that the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical, otherwise the program is ill-formed.
There shall be white-space between the identifier and the replacement list in the definition of an object-like macro.
If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro definition.
Otherwise, there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...).
There shall exist a ) preprocessing token that terminates the invocation.
The identifier __VA_­ARGS__ shall occur only in the replacement-list of a function-like macro that uses the ellipsis notation in the parameters.
A parameter identifier in a function-like macro shall be uniquely declared within its scope.
The identifier immediately following the define is called the macro name.
There is one name space for macro names.
Any white-space characters preceding or following the replacement list of preprocessing tokens are not considered part of the replacement list for either form of macro.
If a # preprocessing token, followed by an identifier, occurs lexically at the point at which a preprocessing directive could begin, the identifier is not subject to macro replacement.
A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name148 to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive.149
The replacement list is then rescanned for more macro names as specified below.
A preprocessing directive of the form
# define identifier lparen identifier-list ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
defines a function-like macro with parameters, whose use is similar syntactically to a function call.
The parameters are specified by the optional list of identifiers, whose scope extends from their declaration in the identifier list until the new-line character that terminates the #define preprocessing directive.
Each subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).
The replaced sequence of preprocessing tokens is terminated by the matching ) preprocessing token, skipping intervening matched pairs of left and right parenthesis preprocessing tokens.
Within the sequence of preprocessing tokens making up an invocation of a function-like macro, new-line is considered a normal white-space character.
The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro.
The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments.
If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives,150 the behavior is undefined.
If there is a ... immediately preceding the ) in the function-like macro definition, then the trailing arguments, including any separating comma preprocessing tokens, are merged to form a single item: the variable arguments.
The number of arguments so combined is such that, following merger, the number of arguments is one more than the number of parameters in the macro definition (excluding the ...).
Since, by macro-replacement time, all character literals and string literals are preprocessing tokens, not sequences possibly containing identifier-like subsequences (see [lex.phases], translation phases), they are never scanned for macro names or parameters.
An alternative token ([lex.digraph]) is not an identifier, even when its spelling consists entirely of letters and underscores.
Therefore it is not possible to define a macro whose name is the same as that of an alternative token.
A conditionally-supported-directive is a preprocessing directive regardless of whether the implementation supports it.

19.3.1 Argument substitution [cpp.subst]

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place.
A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded.
Before being substituted, each argument's preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
An identifier __VA_­ARGS__ that occurs in the replacement list shall be treated as if it were a parameter, and the variable arguments shall form the preprocessing tokens used to replace it.

19.3.2 The # operator [cpp.stringize]

Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.
If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument.
Each occurrence of white space between the argument's preprocessing tokens becomes a single space character in the character string literal.
White space before the first preprocessing token and after the last preprocessing token comprising the argument is deleted.
Otherwise, the original spelling of each preprocessing token in the argument is retained in the character string literal, except for special handling for producing the spelling of string literals and character literals: a \ character is inserted before each " and \ character of a character literal or string literal (including the delimiting " characters).
If the replacement that results is not a valid character string literal, the behavior is undefined.
The character string literal corresponding to an empty argument is "".
The order of evaluation of # and ## operators is unspecified.

19.3.3 The ## operator [cpp.concat]

A ## preprocessing token shall not occur at the beginning or at the end of a replacement list for either form of macro definition.
If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ## preprocessing token, the parameter is replaced by the corresponding argument's preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.151
For both object-like and function-like macro invocations, before the replacement list is reexamined for more macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token.
Placemarker preprocessing tokens are handled specially: concatenation of two placemarkers results in a single placemarker preprocessing token, and concatenation of a placemarker with a non-placemarker preprocessing token results in the non-placemarker preprocessing token.
If the result is not a valid preprocessing token, the behavior is undefined.
The resulting token is available for further macro replacement.
The order of evaluation of ## operators is unspecified.
[Example
:
In the following fragment:
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y);          // equivalent to char p[] = "x ## y";
The expansion produces, at various stages:
join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"
In other words, expanding hash_­hash produces a new token, consisting of two adjacent sharp signs, but this new token is not the ## operator.
end example
]
Placemarker preprocessing tokens do not appear in the syntax because they are temporary entities that exist only within translation phase 4.

19.3.4 Rescanning and further replacement [cpp.rescan]

After all parameters in the replacement list have been substituted and # and ## processing has taken place, all placemarker preprocessing tokens are removed.
Then the resulting preprocessing token sequence is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.
If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file's preprocessing tokens), it is not replaced.
Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced.
These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one, but all pragma unary operator expressions within it are then processed as specified in [cpp.pragma.op] below.

19.3.5 Scope of macro definitions [cpp.scope]

A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered or (if none is encountered) until the end of the translation unit.
Macro definitions have no significance after translation phase 4.
A preprocessing directive of the form
# undef identifier new-line
causes the specified identifier no longer to be defined as a macro name.
It is ignored if the specified identifier is not currently defined as a macro name.
[Example
:
The simplest use of this facility is to define a “manifest constant”, as in
#define TABSIZE 100
int table[TABSIZE];
end example
]
[Example
:
The following defines a function-like macro whose value is the maximum of its arguments.
It has the advantages of working for any compatible types of the arguments and of generating in-line code without the overhead of function calling.
It has the disadvantages of evaluating one or the other of its arguments a second time (including side effects) and generating more code than a function if invoked several times.
It also cannot have its address taken, as it has none.
#define max(a, b) ((a) > (b) ? (a) : (b))
The parentheses ensure that the arguments and the resulting expression are bound properly.
end example
]
[Example
:
To illustrate the rules for redefinition and reexamination, the sequence
#define x       3
#define f(a)    f(x * (a))
#undef  x
#define x       2
#define g       f
#define z       z[0]
#define h       g(~
#define m(a)    a(w)
#define w       0,1
#define t(a)    a
#define p()     int
#define q(x)    x
#define r(x,y)  x ## y
#define str(x)  # x

f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
    (f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };
results in
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };
end example
]
[Example
:
To illustrate the rules for creating character string literals and concatenating tokens, the sequence
#define str(s)      # s
#define xstr(s)     str(s)
#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
               x ## s, x ## t)
#define INCFILE(n)  vers ## n
#define glue(a, b)  a ## b
#define xglue(a, b) glue(a, b)
#define HIGHLOW     "hello"
#define LOW         LOW ", world"

debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", '\4')        // this goes away
    == 0) str(: @\n), s);
#include xstr(INCFILE(2).h)
glue(HIGH, LOW);
xglue(HIGH, LOW)
results in
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);
#include "vers2.h"      (after macro replacement, before file access)
"hello";
"hello" ", world"
or, after concatenation of the character string literals,
printf("x1= %d, x2= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n", s);
#include "vers2.h"      (after macro replacement, before file access)
"hello";
"hello, world"
Space around the # and ## tokens in the macro definition is optional.
end example
]
[Example
:
To illustrate the rules for placemarker preprocessing tokens, the sequence
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
  t(10,,), t(,11,), t(,,12), t(,,) };
results in
int j[] = { 123, 45, 67, 89,
  10, 11, 12, };
end example
]
[Example
:
To demonstrate the redefinition rules, the following sequence is valid.
#define OBJ_LIKE      (1-1)
#define OBJ_LIKE      /* white space */ (1-1) /* other */
#define FUNC_LIKE(a)   ( a )
#define FUNC_LIKE( a )(     /* note the white space */ \
                a /* other stuff on this line
                  */ )
But the following redefinitions are invalid:
#define OBJ_LIKE    (0)         // different token sequence
#define OBJ_LIKE    (1 - 1)     // different white space
#define FUNC_LIKE(b) ( a )      // different parameter usage
#define FUNC_LIKE(b) ( b )      // different parameter spelling
end example
]
[Example
:
Finally, to show the variable argument list macro facilities:
#define debug(...) fprintf(stderr, __VA_­ARGS__)
#define showlist(...) puts(#__VA_­ARGS__)
#define report(test, ...) ((test) ? puts(#test) : printf(__VA_­ARGS__))
debug("Flag");
debug("X = %d\n", x);
showlist(The first, second, and third items.);
report(x>y, "x is %d but y is %d", x, y);
results in
fprintf(stderr, "Flag");
fprintf(stderr, "X = %d\n", x);
puts("The first, second, and third items.");
((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y));
end example
]

19.4 Line control [cpp.line]

The string literal of a #line directive, if present, shall be a character string literal.
The line number of the current source line is one greater than the number of new-line characters read or introduced in translation phase 1 ([lex.phases]) while processing the source file to the current token.
A preprocessing directive of the form
# line digit-sequence new-line
causes the implementation to behave as if the following sequence of source lines begins with a source line that has a line number as specified by the digit sequence (interpreted as a decimal integer).
If the digit sequence specifies zero or a number greater than 2147483647, the behavior is undefined.
A preprocessing directive of the form
# line digit-sequence " s-char-sequence " new-line
sets the presumed line number similarly and changes the presumed name of the source file to be the contents of the character string literal.
A preprocessing directive of the form
# line pp-tokens new-line
(that does not match one of the two previous forms) is permitted.
The preprocessing tokens after line on the directive are processed just as in normal text (each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens).
If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined; otherwise, the result is processed as appropriate.

19.5 Error directive [cpp.error]

A preprocessing directive of the form
# error pp-tokens new-line
causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens, and renders the program ill-formed.

19.6 Pragma directive [cpp.pragma]

A preprocessing directive of the form
# pragma pp-tokens new-line
causes the implementation to behave in an implementation-defined manner.
The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner.
Any pragma that is not recognized by the implementation is ignored.

19.7 Null directive [cpp.null]

A preprocessing directive of the form
# new-line
has no effect.

19.8 Predefined macro names [cpp.predefined]

The following macro names shall be defined by the implementation:
  • __cplusplus
    The integer literal 201703L.152
  • __DATE__
    The date of translation of the source file: a character string literal of the form "Mmm dd yyyy", where the names of the months are the same as those generated by the asctime function, and the first character of dd is a space character if the value is less than 10.
    If the date of translation is not available, an implementation-defined valid date shall be supplied.
  • __FILE__
    The presumed name of the current source file (a character string literal).153
  • __LINE__
    The presumed line number (within the current source file) of the current source line (an integer literal).154
  • __STDC_­HOSTED__
    The integer literal 1 if the implementation is a hosted implementation or the integer literal 0 if it is not.
  • __STDCPP_­DEFAULT_­NEW_­ALIGNMENT__
    An integer literal of type std​::​size_­t whose value is the alignment guaranteed by a call to operator new(std​::​size_­t) or operator new[](std​::​size_­t).
    [Note
    :
    Larger alignments will be passed to operator new(std​::​size_­t, std​::​align_­val_­t), etc.
    end note
    ]
  • __TIME__
    The time of translation of the source file: a character string literal of the form "hh:mm:ss" as in the time generated by the asctime function.
    If the time of translation is not available, an implementation-defined valid time shall be supplied.
The following macro names are conditionally defined by the implementation:
  • __STDC__
    Whether __STDC__ is predefined and if so, what its value is, are implementation-defined.
  • __STDC_­MB_­MIGHT_­NEQ_­WC__
    The integer literal 1, intended to indicate that, in the encoding for wchar_­t, a member of the basic character set need not have a code value equal to its value when used as the lone character in an ordinary character literal.
  • __STDC_­VERSION__
    Whether __STDC_­VERSION__ is predefined and if so, what its value is, are implementation-defined.
  • __STDC_­ISO_­10646__
    An integer literal of the form yyyymmL (for example, 199712L).
    If this symbol is defined, then every character in the Unicode required set, when stored in an object of type wchar_­t, has the same value as the short identifier of that character.
    The Unicode required set consists of all the characters that are defined by ISO/IEC 10646, along with all amendments and technical corrigenda as of the specified year and month.
  • __STDCPP_­STRICT_­POINTER_­SAFETY__
    Defined, and has the value integer literal 1, if and only if the implementation has strict pointer safety ([basic.stc.dynamic.safety]).
  • __STDCPP_­THREADS__
    Defined, and has the value integer literal 1, if and only if a program can have more than one thread of execution ([intro.multithread]).
The values of the predefined macros (except for __FILE__ and __LINE__) remain constant throughout the translation unit.
If any of the pre-defined macro names in this subclause, or the identifier defined, is the subject of a #define or a #undef preprocessing directive, the behavior is undefined.
Any other predefined macro names shall begin with a leading underscore followed by an uppercase letter or a second underscore.
It is intended that future versions of this International Standard will replace the value of this macro with a greater value.
Non-conforming compilers should use a value with at most five decimal digits.
The presumed source file name can be changed by the #line directive.
The presumed line number can be changed by the #line directive.

19.9 Pragma operator [cpp.pragma.op]

A unary operator expression of the form:
_Pragma ( string-literal )
is processed as follows: The string literal is destringized by deleting the L prefix, if present, deleting the leading and trailing double-quotes, replacing each escape sequence \" by a double-quote, and replacing each escape sequence \\ by a single backslash.
The resulting sequence of characters is processed through translation phase 3 to produce preprocessing tokens that are executed as if they were the pp-tokens in a pragma directive.
The original four preprocessing tokens in the unary operator expression are removed.
[Example
:
#pragma listing on "..\listing.dir"
can also be expressed as:
_Pragma ( "listing on \"..\\listing.dir\"" )
The latter form is processed in the same way whether it appears literally as shown, or results from macro replacement, as in:
#define LISTING(x) PRAGMA(listing on #x)
#define PRAGMA(x) _Pragma(#x)

LISTING( ..\listing.dir )
end example
]

20 Library introduction [library]

20.1 General [library.general]

This Clause describes the contents of the C++ standard library, how a well-formed C++ program makes use of the library, and how a conforming implementation may provide the entities in the library.
The following subclauses describe the definitions ([definitions]), method of description ([description]), and organization ([organization]) of the library.
Clause [requirements], Clauses [language.support] through [thread], and Annex [depr] specify the contents of the library, as well as library requirements and constraints on both well-formed C++ programs and conforming implementations.
Detailed specifications for each of the components in the library are in Clauses [language.support][thread], as shown in Table 15.
Table 15 — Library categories
Clause
Category
Language support library
Diagnostics library
General utilities library
Strings library
Localization library
Containers library
Iterators library
Algorithms library
Numerics library
Input/output library
Regular expressions library
Atomic operations library
Thread support library
The language support library (Clause [language.support]) provides components that are required by certain parts of the C++ language, such as memory allocation ([expr.new], [expr.delete]) and exception processing (Clause [except]).
The diagnostics library (Clause [diagnostics]) provides a consistent framework for reporting errors in a C++ program, including predefined exception classes.
The general utilities library (Clause [utilities]) includes components used by other library elements, such as a predefined storage allocator for dynamic storage management ([basic.stc.dynamic]), and components used as infrastructure in C++ programs, such as tuples, function wrappers, and time facilities.
The strings library (Clause [strings]) provides support for manipulating text represented as sequences of type char, sequences of type char16_­t, sequences of type char32_­t, sequences of type wchar_­t, and sequences of any other character-like type.
The localization library (Clause [localization]) provides extended internationalization support for text processing.
The containers (Clause [containers]), iterators (Clause [iterators]), and algorithms (Clause [algorithms]) libraries provide a C++ program with access to a subset of the most widely used algorithms and data structures.
The numerics library (Clause [numerics]) provides numeric algorithms and complex number components that extend support for numeric processing.
The valarray component provides support for n-at-a-time processing, potentially implemented as parallel operations on platforms that support such processing.
The random number component provides facilities for generating pseudo-random numbers.
The input/output library (Clause [input.output]) provides the iostream components that are the primary mechanism for C++ program input and output.
They can be used with other elements of the library, particularly strings, locales, and iterators.
The regular expressions library (Clause [re]) provides regular expression matching and searching.
The atomic operations library (Clause [atomics]) allows more fine-grained concurrent access to shared data than is possible with locks.
The thread support library (Clause [thread]) provides components to create and manage threads, including mutual exclusion and interthread communication.

20.2 The C standard library [library.c]

The C++ standard library also makes available the facilities of the C standard library, suitably adjusted to ensure static type safety.
The descriptions of many library functions rely on the C standard library for the semantics of those functions.
In some cases, the signatures specified in this International Standard may be different from the signatures in the C standard library, and additional overloads may be declared in this International Standard, but the behavior and the preconditions (including any preconditions implied by the use of an ISO C restrict qualifier) are the same unless otherwise stated.

20.3 Definitions [definitions]

[Note
:
Clause [intro.defs] defines additional terms used elsewhere in this International Standard.
end note
]

20.3.1 arbitrary-positional stream [defns.arbitrary.stream]

a stream (described in Clause [input.output]) that can seek to any integral position within the length of the stream
[Note
:
Every arbitrary-positional stream is also a repositional stream.
end note
]

20.3.2 character [defns.character]

⟨Clauses [strings], [localization], [input.output], and [re]⟩ any object which, when treated sequentially, can represent text
[Note
:
The term does not mean only char, char16_­t, char32_­t, and wchar_­t objects, but any value that can be represented by a type that provides the definitions specified in these Clauses.
end note
]

20.3.3 character container type [defns.character.container]

a class or a type used to represent a character
[Note
:
It is used for one of the template parameters of the string, iostream, and regular expression class templates.
A character container type is a POD ([basic.types]) type.
end note
]

20.3.4 comparison function [defns.comparison]

an operator function ([over.oper]) for any of the equality ([expr.eq]) or relational ([expr.rel]) operators

20.3.5 component [defns.component]

a group of library entities directly related as members, parameters, or return types
[Note
:
For example, the class template basic_­string and the non-member function templates that operate on strings are referred to as the string component.
end note
]

20.3.6 constant subexpression [defns.const.subexpr]

an expression whose evaluation as subexpression of a conditional-expression CE ([expr.cond]) would not prevent CE from being a core constant expression ([expr.const])

20.3.7 deadlock [defns.deadlock]

one or more threads are unable to continue execution because each is blocked waiting for one or more of the others to satisfy some condition

20.3.8 default behavior [defns.default.behavior.impl]

⟨implementation⟩ any specific behavior provided by the implementation, within the scope of the required behavior

20.3.9 default behavior [defns.default.behavior.func]

⟨specification⟩ a description of replacement function and handler function semantics

20.3.10 direct-non-list-initialization [defns.direct-non-list-init]

a direct-initialization ([dcl.init]) that is not list-initialization ([dcl.init.list])

20.3.11 handler function [defns.handler]

a non-reserved function whose definition may be provided by a C++ program
[Note
:
A C++ program may designate a handler function at various points in its execution by supplying a pointer to the function when calling any of the library functions that install handler functions (Clause [language.support]).
end note
]

20.3.12 iostream class templates [defns.iostream.templates]

templates, defined in Clause [input.output], that take two template arguments
[Note
:
The arguments are named charT and traits.
The argument charT is a character container class, and the argument traits is a class which defines additional characteristics and functions of the character type represented by charT necessary to implement the iostream class templates.
end note
]

20.3.13 modifier function [defns.modifier]

a class member function ([class.mfct]) other than a constructor, assignment operator, or destructor that alters the state of an object of the class

20.3.14 move assignment [defns.move.assign]

assignment of an rvalue of some object type to a modifiable lvalue of the same type

20.3.15 move construction [defns.move.constr]

direct-initialization of an object of some type with an rvalue of the same type

20.3.16 NTCTS [defns.ntcts]

a sequence of values that have character type that precede the terminating null character type value charT()

20.3.17 observer function [defns.observer]

a class member function ([class.mfct]) that accesses the state of an object of the class but does not alter that state
[Note
:
Observer functions are specified as const member functions ([class.this]).
end note
]

20.3.18 referenceable type [defns.referenceable]

an object type, a function type that does not have cv-qualifiers or a ref-qualifier, or a reference type
[Note
:
The term describes a type to which a reference can be created, including reference types.
end note
]

20.3.19 replacement function [defns.replacement]

a non-reserved function whose definition is provided by a C++ program
[Note
:
Only one definition for such a function is in effect for the duration of the program's execution, as the result of creating the program ([lex.phases]) and resolving the definitions of all translation units ([basic.link]).
end note
]

20.3.20 repositional stream [defns.repositional.stream]

a stream (described in Clause [input.output]) that can seek to a position that was previously encountered

20.3.21 required behavior [defns.required.behavior]

a description of replacement function and handler function semantics applicable to both the behavior provided by the implementation and the behavior of any such function definition in the program
[Note
:
If such a function defined in a C++ program fails to meet the required behavior when it executes, the behavior is undefined.
end note
]

20.3.22 reserved function [defns.reserved.function]

a function, specified as part of the C++ standard library, that must be defined by the implementation
[Note
:
If a C++ program provides a definition for any reserved function, the results are undefined.
end note
]

20.3.23 stable algorithm [defns.stable]

an algorithm that preserves, as appropriate to the particular algorithm, the order of elements
[Note
:
Requirements for stable algorithms are given in [algorithm.stable].
end note
]

20.3.24 traits class [defns.traits]

a class that encapsulates a set of types and functions necessary for class templates and function templates to manipulate objects of types for which they are instantiated

20.3.25 valid but unspecified state [defns.valid]

a value of an object that is not specified except that the object's invariants are met and operations on the object behave as specified for its type
[Example
:
If an object x of type std​::​vector<int> is in a valid but unspecified state, x.empty() can be called unconditionally, and x.front() can be called only if x.empty() returns false.
end example
]

20.4 Method of description (Informative) [description]

This subclause describes the conventions used to specify the C++ standard library.
[structure] describes the structure of the normative Clauses [language.support] through [thread] and Annex [depr].
[conventions] describes other editorial conventions.

20.4.1 Structure of each clause [structure]

20.4.1.1 Elements [structure.elements]

Each library clause contains the following elements, as applicable:155
To save space, items that do not apply to a Clause are omitted.
For example, if a Clause does not specify any requirements, there will be no “Requirements” subclause.

20.4.1.2 Summary [structure.summary]

The Summary provides a synopsis of the category, and introduces the first-level subclauses.
Each subclause also provides a summary, listing the headers specified in the subclause and the library entities provided in each header.
Paragraphs labeled “Note(s):” or “Example(s):” are informative, other paragraphs are normative.
The contents of the summary and the detailed specifications include:

20.4.1.3 Requirements [structure.requirements]

Requirements describe constraints that shall be met by a C++ program that extends the standard library.
Such extensions are generally one of the following:
  • Template arguments
  • Derived classes
  • Containers, iterators, and algorithms that meet an interface convention
The string and iostream components use an explicit representation of operations required of template arguments.
They use a class template char_­traits to define these constraints.
Interface convention requirements are stated as generally as possible.
Instead of stating “class X has to define a member function operator++()”, the interface requires “for any object x of class X, ++x is defined”.
That is, whether the operator is a member is unspecified.
Requirements are stated in terms of well-defined expressions that define valid terms of the types that satisfy the requirements.
For every set of well-defined expression requirements there is a table that specifies an initial set of the valid expressions and their semantics.
Any generic algorithm (Clause [algorithms]) that uses the well-defined expression requirements is described in terms of the valid expressions for its template type parameters.
Template argument requirements are sometimes referenced by name.
In some cases the semantic requirements are presented as C++ code.
Such code is intended as a specification of equivalence of a construct to another construct, not necessarily as the way the construct must be implemented.156
Although in some cases the code given is unambiguously the optimum implementation.

20.4.1.4 Detailed specifications [structure.specifications]

The detailed specifications each contain the following elements:
  • name and brief description
  • synopsis (class definition or function declaration, as appropriate)
  • restrictions on template arguments, if any
  • description of class invariants
  • description of function semantics
Descriptions of class member functions follow the order (as appropriate):157
  • constructor(s) and destructor
  • copying, moving & assignment functions
  • comparison functions
  • modifier functions
  • observer functions
  • operators and other non-member functions
Descriptions of function semantics contain the following elements (as appropriate):158
  • Requires: the preconditions for calling the function
  • Effects: the actions performed by the function
  • Synchronization: the synchronization operations ([intro.multithread]) applicable to the function
  • Postconditions: the observable results established by the function
  • Returns: a description of the value(s) returned by the function
  • Throws: any exceptions thrown by the function, and the conditions that would cause the exception
  • Complexity: the time and/or space complexity of the function
  • Remarks: additional semantic constraints on the function
  • Error conditions: the error conditions for error codes reported by the function
Whenever the Effects: element specifies that the semantics of some function F are Equivalent to some code sequence, then the various elements are interpreted as follows.
If F's semantics specifies a Requires: element, then that requirement is logically imposed prior to the equivalent-to semantics.
Next, the semantics of the code sequence are determined by the Requires:, Effects:, Synchronization:, Postconditions:, Returns:, Throws:, Complexity:, Remarks:, and Error conditions: specified for the function invocations contained in the code sequence.
The value returned from F is specified by F's Returns: element, or if F has no Returns: element, a non-void return from F is specified by the return statements in the code sequence.
If F's semantics contains a Throws:, Postconditions:, or Complexity: element, then that supersedes any occurrences of that element in the code sequence.
For non-reserved replacement and handler functions, Clause [language.support] specifies two behaviors for the functions in question: their required and default behavior.
The default behavior describes a function definition provided by the implementation.
The required behavior describes the semantics of a function definition provided by either the implementation or a C++ program.
Where no distinction is explicitly made in the description, the behavior described is the required behavior.
If the formulation of a complexity requirement calls for a negative number of operations, the actual requirement is zero operations.159
Complexity requirements specified in the library clauses are upper bounds, and implementations that provide better complexity guarantees satisfy the requirements.
Error conditions specify conditions where a function may fail.
The conditions are listed, together with a suitable explanation, as the enum class errc constants ([syserr]).
To save space, items that do not apply to a class are omitted.
For example, if a class does not specify any comparison functions, there will be no “Comparison functions” subclause.
To save space, items that do not apply to a function are omitted.
For example, if a function does not specify any further preconditions, there will be no Requires: paragraph.
This simplifies the presentation of complexity requirements in some cases.

20.4.1.5 C library [structure.see.also]

Paragraphs labeled “See also:” contain cross-references to the relevant portions of this International Standard and the ISO C standard.

20.4.2 Other conventions [conventions]

This subclause describes several editorial conventions used to describe the contents of the C++ standard library.
These conventions are for describing implementation-defined types ([type.descriptions]), and member functions ([functions.within.classes]).

20.4.2.1 Type descriptions [type.descriptions]

20.4.2.1.1 General [type.descriptions.general]

The Requirements subclauses may describe names that are used to specify constraints on template arguments.160
These names are used in library Clauses to describe the types that may be supplied as arguments by a C++ program when instantiating template components from the library.
Certain types defined in Clause [input.output] are used to describe implementation-defined types.
They are based on other types, but with added constraints.
Examples from [utility.requirements] include: EqualityComparable, LessThanComparable, CopyConstructible.
Examples from [iterator.requirements] include: InputIterator, ForwardIterator.

20.4.2.1.2 Exposition-only types [expos.only.types]

Several types defined in Clauses [language.support] through [thread] and Annex [depr] that are used as function parameter or return types are defined for the purpose of exposition only in order to capture their language linkage.
The declarations of such types are followed by a comment ending in exposition only.
[Example
:
namespace std {
  extern "C" using some-handler = int(int, void*, double);  // exposition only
}
The type placeholder some-handler can now be used to specify a function that takes a callback parameter with C language linkage.
end example
]

20.4.2.1.3 Enumerated types [enumerated.types]

Several types defined in Clause [input.output] are enumerated types.
Each enumerated type may be implemented as an enumeration or as a synonym for an enumeration.161
The enumerated type enumerated can be written:
enum enumerated { , , , , ..... };

inline const ();
inline const ();
inline const ();
inline const ();
  .....
Here, the names , , etc.
 represent enumerated elements for this particular enumerated type.
All such elements have distinct values.
Such as an integer type, with constant integer values ([basic.fundamental]).

20.4.2.1.4 Bitmask types [bitmask.types]

Several types defined in Clauses [language.support] through [thread] and Annex [depr] are bitmask types.
Each bitmask type can be implemented as an enumerated type that overloads certain operators, as an integer type, or as a bitset ([template.bitset]).
The bitmask type bitmask can be written:
// For exposition only.
// int_­type is an integral type capable of representing all values of the bitmask type.
enum bitmask : int_type {
   = 1 << 0,  = 1 << 1,  = 1 << 2,  = 1 << 3, .....
};

inline constexpr ();
inline constexpr ();
inline constexpr ();
inline constexpr ();
  .....

constexpr bitmask operator&(bitmask X, bitmask Y) {
  return static_cast<bitmask>(
    static_cast<int_type>(X) & static_cast<int_type>(Y));
}
constexpr bitmask operator|(bitmask X, bitmask Y) {
  return static_cast<bitmask>(
    static_cast<int_type>(X) | static_cast<int_type>(Y));
}
constexpr bitmask operator^(bitmask X, bitmask Y){
  return static_cast<bitmask>(
    static_cast<int_type>(X) ^ static_cast<int_type>(Y));
}
constexpr bitmask operator~(bitmask X){
  return static_cast<bitmask>(~static_cast<int_type>(X));
}
bitmask& operator&=(bitmask& X, bitmask Y){
  X = X & Y; return X;
}
bitmask& operator|=(bitmask& X, bitmask Y) {
  X = X | Y; return X;
}
bitmask& operator^=(bitmask& X, bitmask Y) {
  X = X ^ Y; return X;
}
Here, the names , , etc.
 represent bitmask elements for this particular bitmask type.
All such elements have distinct, nonzero values such that, for any pair and where , & is nonzero and & is zero.
Additionally, the value 0 is used to represent an empty bitmask, in which no bitmask elements are set.
The following terms apply to objects and values of bitmask types:
  • To set a value Y in an object X is to evaluate the expression X |= Y.
  • To clear a value Y in an object X is to evaluate the expression X &= ~Y.
  • The value Y is set in the object X if the expression X & Y is nonzero.

20.4.2.1.5 Character sequences [character.seq]

The C standard library makes widespread use of characters and character sequences that follow a few uniform conventions:
  • A letter is any of the 26 lowercase or 26 uppercase letters in the basic execution character set.
  • The decimal-point character is the (single-byte) character used by functions that convert between a (single-byte) character sequence and a value of one of the floating-point types.
    It is used in the character sequence to denote the beginning of a fractional part.
    It is represented in Clauses [language.support] through [thread] and Annex [depr] by a period, '.', which is also its value in the "C" locale, but may change during program execution by a call to setlocale(int, const char*),162 or by a change to a locale object, as described in Clauses [locales] and [input.output].
  • A character sequence is an array object ([dcl.array]) A that can be declared as T A[N], where T is any of the types char, unsigned char, or signed char ([basic.fundamental]), optionally qualified by any combination of const or volatile.
    The initial elements of the array have defined contents up to and including an element determined by some predicate.
    A character sequence can be designated by a pointer value S that points to its first element.
declared in <clocale> ([c.locales]).

20.4.2.1.5.1 Byte strings [byte.strings]

A null-terminated byte string, or ntbs, is a character sequence whose highest-addressed element with defined content has the value zero (the terminating null character); no other element in the sequence has the value zero.
The length of an ntbs is the number of elements that precede the terminating null character.
An empty ntbs has a length of zero.
The value of an ntbs is the sequence of values of the elements up to and including the terminating null character.
A static ntbs is an ntbs with static storage duration.164
Many of the objects manipulated by function signatures declared in <cstring> ([c.strings]) are character sequences or ntbss.
The size of some of these character sequences is limited by a length value, maintained separately from the character sequence.
A string literal, such as "abc", is a static ntbs.

20.4.2.1.5.2 Multibyte strings [multibyte.strings]

A null-terminated multibyte string, or ntmbs, is an ntbs that constitutes a sequence of valid multibyte characters, beginning and ending in the initial shift state.165
A static ntmbs is an ntmbs with static storage duration.
An ntbs that contains characters only from the basic execution character set is also an ntmbs.
Each multibyte character then consists of a single byte.

20.4.2.2 Functions within classes [functions.within.classes]

For the sake of exposition, Clauses [language.support] through [thread] and Annex [depr] do not describe copy/move constructors, assignment operators, or (non-virtual) destructors with the same apparent semantics as those that can be generated by default ([class.ctor], [class.dtor], [class.copy]).
It is unspecified whether the implementation provides explicit definitions for such member function signatures, or for virtual destructors that can be generated by default.
For the sake of exposition, the library clauses sometimes annotate constructors with EXPLICIT.
Such a constructor is conditionally declared as either explicit or non-explicit ([class.conv.ctor]).
[Note
:
This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution.
end note
]

20.4.2.3 Private members [objects.within.classes]

Clauses [language.support] through [thread] and Annex [depr] do not specify the representation of classes, and intentionally omit specification of class members ([class.mem]).
An implementation may define static or non-static class members, or both, as needed to implement the semantics of the member functions specified in Clauses [language.support] through [thread] and Annex [depr].
For the sake of exposition, some subclauses provide representative declarations, and semantic requirements, for private members of classes that meet the external specifications of the classes.
The declarations for such members are followed by a comment that ends with exposition only, as in:
streambuf* sb;  // exposition only
An implementation may use any technique that provides equivalent observable behavior.

20.5 Library-wide requirements [requirements]

This subclause specifies requirements that apply to the entire C++ standard library.
Clauses [language.support] through [thread] and Annex [depr] specify the requirements of individual entities within the library.
Requirements specified in terms of interactions between threads do not apply to programs having only a single thread of execution.
Within this subclause, [organization] describes the library's contents and organization, [using] describes how well-formed C++ programs gain access to library entities, [utility.requirements] describes constraints on types and functions used with the C++ standard library, [constraints] describes constraints on well-formed C++ programs, and [conforming] describes constraints on conforming implementations.

20.5.1 Library contents and organization [organization]

[contents] describes the entities and macros defined in the C++ standard library.
[headers] lists the standard library headers and some constraints on those headers.
[compliance] lists requirements for a freestanding implementation of the C++ standard library.

20.5.1.1 Library contents [contents]

The C++ standard library provides definitions for the entities and macros described in the synopses of the C++ standard library headers ([headers]).
All library entities except operator new and operator delete are defined within the namespace std or namespaces nested within namespace std.166
It is unspecified whether names declared in a specific namespace are declared directly in that namespace or in an inline namespace inside that namespace.167
Whenever a name x defined in the standard library is mentioned, the name x is assumed to be fully qualified as ​::​std​::​x, unless explicitly described otherwise.
For example, if the Effects: section for library function F is described as calling library function G, the function ​::​std​::​G is meant.
The C standard library headers (Annex [depr.c.headers]) also define names within the global namespace, while the C++ headers for C library facilities ([headers]) may also define names within the global namespace.
This gives implementers freedom to use inline namespaces to support multiple configurations of the library.

20.5.1.2 Headers [headers]

Each element of the C++ standard library is declared or defined (as appropriate) in a header.168
The C++ standard library provides the C++ library headers, shown in Table 16.
Table 16 — C++ library headers
<algorithm>
<future>
<numeric>
<strstream>
<any>
<initializer_­list>
<optional>
<system_­error>
<array>
<iomanip>
<ostream>
<thread>
<atomic>
<ios>
<queue>
<tuple>
<bitset>
<iosfwd>
<random>
<type_­traits>
<chrono>
<iostream>
<ratio>
<typeindex>
<codecvt>
<istream>
<regex>
<typeinfo>
<complex>
<iterator>
<scoped_­allocator>
<unordered_­map>
<condition_­variable>
<limits>
<set>
<unordered_­set>
<deque>
<list>
<shared_­mutex>
<utility>
<exception>
<locale>
<sstream>
<valarray>
<execution>
<map>
<stack>
<variant>
<filesystem>
<memory>
<stdexcept>
<vector>
<forward_­list>
<memory_­resource>
<streambuf>
<fstream>
<mutex>
<string>
<functional>
<new>
<string_­view>
The facilities of the C standard library are provided in the additional headers shown in Table 17.169
Table 17 — C++ headers for C library facilities
<cassert>
<cinttypes>
<csignal>
<cstdio>
<cwchar>
<ccomplex>
<ciso646>
<cstdalign>
<cstdlib>
<cwctype>
<cctype>
<climits>
<cstdarg>
<cstring>
<cerrno>
<clocale>
<cstdbool>
<ctgmath>
<cfenv>
<cmath>
<cstddef>
<ctime>
<cfloat>
<csetjmp>
<cstdint>
<cuchar>
Except as noted in Clauses [library] through [thread] and Annex [depr], the contents of each header cname is the same as that of the corresponding header name.h as specified in the C standard library (Clause [intro.refs]).
In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope ([basic.scope.namespace]) of the namespace std.
It is unspecified whether these names (including any overloads added in Clauses [language.support] through [thread] and Annex [depr]) are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations.
Names which are defined as macros in C shall be defined as macros in the C++ standard library, even if C grants license for implementation as functions.
[Note
:
The names defined as macros in C include the following: assert, offsetof, setjmp, va_­arg, va_­end, and va_­start.
end note
]
Names that are defined as functions in C shall be defined as functions in the C++ standard library.170
Identifiers that are keywords or operators in C++ shall not be defined as macros in C++ standard library headers.171
[depr.c.headers], C standard library headers, describes the effects of using the name.h (C header) form in a C++ program.172
Annex K of the C standard describes a large number of functions, with associated types and macros, which “promote safer, more secure programming” than many of the traditional C library functions.
The names of the functions have a suffix of _­s; most of them provide the same service as the C library function with the unsuffixed name, but generally take an additional argument whose value is the size of the result array.
If any C++ header is included, it is implementation-defined whether any of these names is declared in the global namespace.
(None of them is declared in namespace std.)
Table 18 lists the Annex K names that may be declared in some header.
These names are also subject to the restrictions of [macro.names].
Table 18 — C standard Annex K names
abort_­handler_­s
mbstowcs_­s
strncat_­s
vswscanf_­s
asctime_­s
memcpy_­s
strncpy_­s
vwprintf_­s
bsearch_­s
memmove_­s
strtok_­s
vwscanf_­s
constraint_­handler_­t
memset_­s
swprintf_­s
wcrtomb_­s
ctime_­s
printf_­s
swscanf_­s
wcscat_­s
errno_­t
qsort_­s
tmpfile_­s
wcscpy_­s
fopen_­s
RSIZE_­MAX
TMP_­MAX_­S
wcsncat_­s
fprintf_­s
rsize_­t
tmpnam_­s
wcsncpy_­s
freopen_­s
scanf_­s
vfprintf_­s
wcsnlen_­s
fscanf_­s
set_­constraint_­handler_­s
vfscanf_­s
wcsrtombs_­s
fwprintf_­s
snprintf_­s
vfwprintf_­s
wcstok_­s
fwscanf_­s
snwprintf_­s
vfwscanf_­s
wcstombs_­s
getenv_­s
sprintf_­s
vprintf_­s
wctomb_­s
gets_­s
sscanf_­s
vscanf_­s
wmemcpy_­s
gmtime_­s
strcat_­s
vsnprintf_­s
wmemmove_­s
ignore_­handler_­s
strcpy_­s
vsnwprintf_­s
wprintf_­s
L_­tmpnam_­s
strerror_­s
vsprintf_­s
wscanf_­s
localtime_­s
strerrorlen_­s
vsscanf_­s
mbsrtowcs_­s
strlen_­s
vswprintf_­s
A header is not necessarily a source file, nor are the sequences delimited by < and > in header names necessarily valid source file names ([cpp.include]).
It is intentional that there is no C++ header for any of these C headers: <stdatomic.h>, <stdnoreturn.h>, <threads.h>.
This disallows the practice, allowed in C, of providing a masking macro in addition to the function prototype.
The only way to achieve equivalent inline behavior in C++ is to provide a definition as an extern inline function.
In particular, including the standard header <iso646.h> or <ciso646> has no effect.
The ".h" headers dump all their names into the global namespace, whereas the newer forms keep their names in namespace std.
Therefore, the newer forms are the preferred forms for all uses except for C++ programs which are intended to be strictly compatible with C.

20.5.1.3 Freestanding implementations [compliance]

Two kinds of implementations are defined: hosted and freestanding ([intro.compliance]).
For a hosted implementation, this International Standard describes the set of available headers.
A freestanding implementation has an implementation-defined set of headers.
This set shall include at least the headers shown in Table 19.
Table 19 — C++ headers for freestanding implementations
Subclause
Header(s)
<ciso646>
Types
<cstddef>
Implementation properties
<cfloat> <limits> <climits>
Integer types
<cstdint>
Start and termination
<cstdlib>
Dynamic memory management
<new>
Type identification
<typeinfo>
Exception handling
<exception>
Initializer lists
<initializer_­list>
Other runtime support
<cstdarg>
Type traits
<type_­traits>
Atomics
<atomic>
Deprecated headers
<cstdalign> <cstdbool>
The supplied version of the header <cstdlib> shall declare at least the functions abort, atexit, at_­quick_­exit, exit, and quick_­exit ([support.start.term]).
The other headers listed in this table shall meet the same requirements as for a hosted implementation.

20.5.2 Using the library [using]

20.5.2.1 Overview [using.overview]

This section describes how a C++ program gains access to the facilities of the C++ standard library.
[using.headers] describes effects during translation phase 4, while [using.linkage] describes effects during phase 8 ([lex.phases]).

20.5.2.2 Headers [using.headers]

The entities in the C++ standard library are defined in headers, whose contents are made available to a translation unit when it contains the appropriate #include preprocessing directive ([cpp.include]).
A translation unit may include library headers in any order (Clause [lex]).
Each may be included more than once, with no effect different from being included exactly once, except that the effect of including either <cassert> or <assert.h> depends each time on the lexically current definition of NDEBUG.173
A translation unit shall include a header only outside of any declaration or definition, and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.
No diagnostic is required.
This is the same as the C standard library.

20.5.2.3 Linkage [using.linkage]

Entities in the C++ standard library have external linkage ([basic.link]).
Unless otherwise specified, objects and functions have the default extern "C++" linkage ([dcl.link]).
Whether a name from the C standard library declared with external linkage has extern "C" or extern "C++" linkage is implementation-defined.
It is recommended that an implementation use extern "C++" linkage for this purpose.174
Objects and functions defined in the library and required by a C++ program are included in the program prior to program startup.
See also replacement functions ([replacement.functions]), runtime changes ([handler.functions]).
The only reliable way to declare an object or function signature from the C standard library is by including the header that declares it, notwithstanding the latitude granted in 7.
1.
4 of the C Standard.

20.5.3 Requirements on types and expressions [utility.requirements]

[utility.arg.requirements] describes requirements on types and expressions used to instantiate templates defined in the C++ standard library.
[swappable.requirements] describes the requirements on swappable types and swappable expressions.
[nullablepointer.requirements] describes the requirements on pointer-like types that support null values.
[hash.requirements] describes the requirements on hash function objects.
[allocator.requirements] describes the requirements on storage allocators.

20.5.3.1 Template argument requirements [utility.arg.requirements]

The template definitions in the C++ standard library refer to various named requirements whose details are set out in Tables 2027.
In these tables, T is an object or reference type to be supplied by a C++ program instantiating a template; a, b, and c are values of type (possibly const) T; s and t are modifiable lvalues of type T; u denotes an identifier; rv is an rvalue of type T; and v is an lvalue of type (possibly const) T or an rvalue of type const T.
In general, a default constructor is not required.
Certain container class member function signatures specify T() as a default argument.
T() shall be a well-defined expression ([dcl.init]) if one of those signatures is called using the default argument ([dcl.fct.default]).
Table 20EqualityComparable requirements
Expression
Return type
Requirement
a == b
convertible to bool
== is an equivalence relation, that is, it has the following properties:
  • For all a, a == a.
  • If a == b, then b == a.
  • If a == b and b == c, then a == c.
Table 21LessThanComparable requirements
Expression
Return type
Requirement
a < b
convertible to bool
< is a strict weak ordering relation ([alg.sorting])
Table 22DefaultConstructible requirements
Expression
Post-condition
T t;
object t is default-initialized
T u{};
object u is value-initialized or aggregate-initialized
T()
T{}
an object of type T is value-initialized or aggregate-initialized
Table 23MoveConstructible requirements
Expression
Post-condition
T u = rv;
u is equivalent to the value of rv before the construction
T(rv)
T(rv) is equivalent to the value of rv before the construction
rv's state is unspecified
[Note
:
rv must still meet the requirements of the library component that is using it.
The operations listed in those requirements must work as specified whether rv has been moved from or not.
end note
]
Table 24CopyConstructible requirements (in addition to MoveConstructible)
Expression
Post-condition
T u = v;
the value of v is unchanged and is equivalent to u
T(v)
the value of v is unchanged and is equivalent to T(v)
Table 25MoveAssignable requirements
Expression
Return type
Return value
Post-condition
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
rv's state is unspecified.
[Note
:
 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.
The operations listed in those requirements must work as specified whether rv has been moved from or not.
end note
]
Table 26CopyAssignable requirements (in addition to MoveAssignable)
Expression
Return type
Return value
Post-condition
t = v
T&
t
t is equivalent to v, the value of v is unchanged
Table 27Destructible requirements
Expression
Post-condition
u.~T()
All resources owned by u are reclaimed, no exception is propagated.

20.5.3.2 Swappable requirements [swappable.requirements]

This subclause provides definitions for swappable types and expressions.
In these definitions, let t denote an expression of type T, and let u denote an expression of type U.
An object t is swappable with an object u if and only if:
  • the expressions swap(t, u) and swap(u, t) are valid when evaluated in the context described below, and
  • these expressions have the following effects:
    • the object referred to by t has the value originally held by u and
    • the object referred to by u has the value originally held by t.
The context in which swap(t, u) and swap(u, t) are evaluated shall ensure that a binary non-member function named “swap” is selected via overload resolution ([over.match]) on a candidate set that includes:
[Note
:
If T and U are both fundamental types or arrays of fundamental types and the declarations from the header <utility> are in scope, the overall lookup set described above is equivalent to that of the qualified name lookup applied to the expression std​::​swap(t, u) or std​::​swap(u, t) as appropriate.
end note
]
[Note
:
It is unspecified whether a library component that has a swappable requirement includes the header <utility> to ensure an appropriate evaluation context.
end note
]
An rvalue or lvalue t is swappable if and only if t is swappable with any rvalue or lvalue, respectively, of type T.
A type X satisfying any of the iterator requirements ([iterator.requirements]) satisfies the requirements of ValueSwappable if, for any dereferenceable object x of type X, *x is swappable.
[Example
:
User code can ensure that the evaluation of swap calls is performed in an appropriate context under the various conditions as follows:
#include <utility>

// Requires: std​::​forward<T>(t) shall be swappable with std​::​forward<U>(u).
template <class T, class U>
void value_swap(T&& t, U&& u) {
  using std::swap;
  swap(std::forward<T>(t), std::forward<U>(u)); // OK: uses “swappable with” conditions
                                                // for rvalues and lvalues
}

// Requires: lvalues of T shall be swappable.
template <class T>
void lv_swap(T& t1, T& t2) {
  using std::swap;
  swap(t1, t2);                                 // OK: uses swappable conditions for
}                                               // lvalues of type T

namespace N {
  struct A { int m; };
  struct Proxy { A* a; };
  Proxy proxy(A& a) { return Proxy{ &a }; }

  void swap(A& x, Proxy p) {
    std::swap(x.m, p.a->m);                     // OK: uses context equivalent to swappable
                                                // conditions for fundamental types
  }
  void swap(Proxy p, A& x) { swap(x, p); }      // satisfy symmetry constraint
}

int main() {
  int i = 1, j = 2;
  lv_swap(i, j);
  assert(i == 2 && j == 1);

  N::A a1 = { 5 }, a2 = { -5 };
  value_swap(a1, proxy(a2));
  assert(a1.m == -5 && a2.m == 5);
}
end example
]

20.5.3.3 NullablePointer requirements [nullablepointer.requirements]

A NullablePointer type is a pointer-like type that supports null values.
A type P meets the requirements of NullablePointer if:
  • P satisfies the requirements of EqualityComparable, DefaultConstructible, CopyConstructible, CopyAssignable, and Destructible,
  • lvalues of type P are swappable ([swappable.requirements]),
  • the expressions shown in Table 28 are valid and have the indicated semantics, and
  • P satisfies all the other requirements of this subclause.
A value-initialized object of type P produces the null value of the type.
The null value shall be equivalent only to itself.
A default-initialized object of type P may have an indeterminate value.
[Note
:
Operations involving indeterminate values may cause undefined behavior.
end note
]
An object p of type P can be contextually converted to bool (Clause [conv]).
The effect shall be as if p != nullptr had been evaluated in place of p.
No operation which is part of the NullablePointer requirements shall exit via an exception.
In Table 28, u denotes an identifier, t denotes a non-const lvalue of type P, a and b denote values of type (possibly const) P, and np denotes a value of type (possibly const) std​::​nullptr_­t.
Table 28NullablePointer requirements
Expression
Return type
Operational semantics
P u(np);
Postconditions: u == nullptr
P u = np;
P(np)
Postconditions: P(np) == nullptr
t = np
P&
Postconditions: t == nullptr
a != b
contextually convertible to bool
!(a == b)
a == np
contextually convertible to bool
a == P()
np == a
a != np
contextually convertible to bool
!(a == np)
np != a

20.5.3.4 Hash requirements [hash.requirements]

A type H meets the Hash requirements if:
Given Key is an argument type for function objects of type H, in Table 29 h is a value of type (possibly const) H, u is an lvalue of type Key, and k is a value of a type convertible to (possibly const) Key.
Table 29Hash requirements
Expression
Return type
Requirement
h(k)
size_­t
The value returned shall depend only on the argument k for the duration of the program.
[Note
:
Thus all evaluations of the expression h(k) with the same value for k yield the same result for a given execution of the program.
end note
]
[Note
:
For two different values t1 and t2, the probability that h(t1) and h(t2) compare equal should be very small, approaching 1.0 / numeric_­limits<size_­t>​::​max().
end note
]
h(u)
size_­t
Shall not modify u.

20.5.3.5 Allocator requirements [allocator.requirements]

The library describes a standard set of requirements for allocators, which are class-type objects that encapsulate the information about an allocation model.
This information includes the knowledge of pointer types, the type of their difference, the type of the size of objects in this allocation model, as well as the memory allocation and deallocation primitives for it.
All of the string types (Clause [strings]), containers (Clause [containers]) (except array), string buffers and string streams (Clause [input.output]), and match_­results (Clause [re]) are parameterized in terms of allocators.
The class template allocator_­traits ([allocator.traits]) supplies a uniform interface to all allocator types.
Table 30 describes the types manipulated through allocators.
Table 31 describes the requirements on allocator types and thus on types used to instantiate allocator_­traits.
A requirement is optional if the last column of Table 31 specifies a default for a given expression.
Within the standard library allocator_­traits template, an optional requirement that is not supplied by an allocator is replaced by the specified default expression.
A user specialization of allocator_­traits may provide different defaults and may provide defaults for different requirements than the primary template.
Within Tables 30 and 31, the use of move and forward always refers to std​::​move and std​::​forward, respectively.
Table 30 — Descriptive variable definitions
Variable
Definition
T, U, C
any cv-unqualified object type ([basic.types])
X
an Allocator class for type T
Y
the corresponding Allocator class for type U
XX
the type allocator_­traits<X>
YY
the type allocator_­traits<Y>
a, a1, a2
lvalues of type X
u
the name of a variable being declared
b
a value of type Y
c
a pointer of type C* through which indirection is valid
p
a value of type XX​::​pointer, obtained by calling a1.allocate, where a1 == a
q
a value of type XX​::​const_­pointer obtained by conversion from a value p.
w
a value of type XX​::​void_­pointer obtained by conversion from a value p
x
a value of type XX​::​const_­void_­pointer obtained by conversion from a value q or a value w
y
a value of type XX​::​const_­void_­pointer obtained by conversion from a result value of YY​::​allocate, or else a value of type (possibly const) std​::​nullptr_­t.
n
a value of type XX​::​size_­type.
Args
a template parameter pack
args
a function parameter pack with the pattern Args&&
Table 31 — Allocator requirements
Expression
Return type
Assertion/note
Default
pre-/post-condition
X​::​pointer
T*
X​::​const_­pointer
X​::​pointer is convertible to X​::​const_­pointer
pointer_­traits<X​::​​pointer>​::​​rebind<const T>
X​::​void_­pointer
Y​::​void_­pointer
X​::​pointer is convertible to X​::​void_­pointer.
X​::​void_­pointer and Y​::​void_­pointer are the same type.
pointer_­traits<X​::​​pointer>​::​​rebind<void>
X​::​const_­void_­pointer
Y​::​const_­void_­pointer
X​::​pointer, X​::​const_­pointer, and X​::​void_­pointer are convertible to X​::​const_­void_­pointer.
X​::​const_­void_­pointer and Y​::​const_­void_­pointer are the same type.
pointer_­traits<X​::​​pointer>​::​​rebind<const void>
X​::​value_­type
Identical to T
X​::​size_­type
unsigned integer type
a type that can represent the size of the largest object in the allocation model.
make_­unsigned_­t<X​::​​difference_­type>
X​::​difference_­type
signed integer type
a type that can represent the difference between any two pointers in the allocation model.
pointer_­traits<X​::​​pointer>​::​​difference_­type
typename X​::​template rebind<U>​::​other
Y
For all U (including T), Y​::​template rebind<T>​::​other is X.
See Note A, below.
*p
T&
*q
const T&
*q refers to the same object as *p
p->m
type of T​::​m
Requires: (*p).m is well-defined.
equivalent to (*p).m
q->m
type of T​::​m
Requires: (*q).m is well-defined.
equivalent to (*q).m
static_­cast<​X​::​pointer​>(w)
X​::​pointer
static_­cast<X​::​pointer>(w) == p
static_­cast<​X​::​const_­pointer​>(x)
X​::​const_­pointer
static_­cast< X​::​const_­pointer​>(x) == q
pointer_­traits<​X​::​pointer​>​::​pointer_­to(r)
X​::​pointer
a.allocate(n)
X​::​pointer
Memory is allocated for n objects of type T but objects are not constructed.
allocate may throw an appropriate exception.175
[Note
:
If n == 0, the return value is unspecified.
end note
]
a.allocate(n, y)
X​::​pointer
Same as a.allocate(n).
The use of y is unspecified, but it is intended as an aid to locality.
a.allocate(n)
a.deallocate(p,n)
(not used)
Requires: p shall be a value returned by an earlier call to allocate that has not been invalidated by an intervening call to deallocate.
n shall match the value passed to allocate to obtain this memory.

Throws: Nothing.
a.max_­size()
X​::​size_­type
the largest value that can meaningfully be passed to X​::​allocate()
numeric_­limits<size_­type>​::​max() / sizeof​(value_­type)
a1 == a2
bool
returns true only if storage allocated from each can be deallocated via the other.
operator== shall be reflexive, symmetric, and transitive, and shall not exit via an exception.
a1 != a2
bool
same as !(a1 == a2)
a == b
bool
same as a == Y​::​rebind<T>​::​other(b)
a != b
bool
same as !(a == b)
X u(a);
X u = a;
Shall not exit via an exception.

Postconditions: u == a
X u(b);
Shall not exit via an exception.

Postconditions: Y(u) == b, u == X(b)
X u(std​::​move(a));
X u = std​::​move(a);
Shall not exit via an exception.

Postconditions: u is equal to the prior value of a.
X u(std​::​move(b));
Shall not exit via an exception.

Postconditions: u is equal to the prior value of X(b).
a.construct(c, args)
(not used)
Effects: Constructs an object of type C at c
​::​new ((void*)c) C(forward<​Args>​(args)...)
a.destroy(c)
(not used)
Effects: Destroys the object at c
c->~C()
a.select_­on_­container_­copy_­construction()
X
Typically returns either a or X()
return a;
X​::​propagate_­on_­container_­copy_­assignment
Identical to or derived from true_­type or false_­type
true_­type only if an allocator of type X should be copied when the client container is copy-assigned.
See Note B, below.
false_­type
X​::​propagate_­on_­container_­move_­assignment
Identical to or derived from true_­type or false_­type
true_­type only if an allocator of type X should be moved when the client container is move-assigned.
See Note B, below.
false_­type
X​::​propagate_­on_­- container_­swap
Identical to or derived from true_­type or false_­type
true_­type only if an allocator of type X should be swapped when the client container is swapped.
See Note B, below.
false_­type
X​::​is_­always_­equal
Identical to or derived from true_­type or false_­type
true_­type only if the expression a1 == a2 is guaranteed to be true for any two (possibly const) values a1, a2 of type X.
is_­empty<X>​::​​type
Note A: The member class template rebind in the table above is effectively a typedef template.
[Note
:
In general, if the name Allocator is bound to SomeAllocator<T>, then Allocator​::​rebind<U>​::​other is the same type as SomeAllocator<U>, where SomeAllocator<T>​::​value_­type is T and SomeAllocator<U>​::​​value_­type is U.
end note
]
If Allocator is a class template instantiation of the form SomeAllocator<T, Args>, where Args is zero or more type arguments, and Allocator does not supply a rebind member template, the standard allocator_­traits template uses SomeAllocator<U, Args> in place of Allocator​::​​rebind<U>​::​other by default.
For allocator types that are not template instantiations of the above form, no default is provided.
Note B: If X​::​propagate_­on_­container_­copy_­assignment​::​value is true, X shall satisfy the CopyAssignable requirements (Table 26) and the copy operation shall not throw exceptions.
If X​::​propagate_­on_­container_­move_­assignment​::​value is true, X shall satisfy the MoveAssignable requirements (Table 25) and the move operation shall not throw exceptions.
If X​::​propagate_­on_­container_­swap​::​value is true, lvalues of type X shall be swappable ([swappable.requirements]) and the swap operation shall not throw exceptions.
An allocator type X shall satisfy the requirements of CopyConstructible ([utility.arg.requirements]).
The X​::​pointer, X​::​const_­pointer, X​::​void_­pointer, and X​::​const_­void_­pointer types shall satisfy the requirements of NullablePointer ([nullablepointer.requirements]).
No constructor, comparison function, copy operation, move operation, or swap operation on these pointer types shall exit via an exception.
X​::​pointer and X​::​const_­pointer shall also satisfy the requirements for a random access iterator ([random.access.iterators]) and of a contiguous iterator ([iterator.requirements.general]).
Let x1 and x2 denote objects of (possibly different) types X​::​void_­pointer, X​::​const_­void_­pointer, X​::​pointer, or X​::​const_­pointer.
Then, x1 and x2 are equivalently-valued pointer values, if and only if both x1 and x2 can be explicitly converted to the two corresponding objects px1 and px2 of type X​::​const_­pointer, using a sequence of static_­casts using only these four types, and the expression px1 == px2 evaluates to true.
Let w1 and w2 denote objects of type X​::​void_­pointer.
Then for the expressions
w1 == w2
w1 != w2
either or both objects may be replaced by an equivalently-valued object of type X​::​const_­void_­pointer with no change in semantics.
Let p1 and p2 denote objects of type X​::​pointer.
Then for the expressions
p1 == p2
p1 != p2
p1 < p2
p1 <= p2
p1 >= p2
p1 > p2
p1 - p2
either or both objects may be replaced by an equivalently-valued object of type X​::​const_­pointer with no change in semantics.
An allocator may constrain the types on which it can be instantiated and the arguments for which its construct or destroy members may be called.
If a type cannot be used with a particular allocator, the allocator class or the call to construct or destroy may fail to instantiate.
[Example
:
The following is an allocator class template supporting the minimal interface that satisfies the requirements of Table 31:
template <class Tp>
struct SimpleAllocator {
  typedef Tp value_type;
  SimpleAllocator(ctor args);

  template <class T> SimpleAllocator(const SimpleAllocator<T>& other);

  Tp* allocate(std::size_t n);
  void deallocate(Tp* p, std::size_t n);
};

template <class T, class U>
bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
template <class T, class U>
bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
end example
]
If the alignment associated with a specific over-aligned type is not supported by an allocator, instantiation of the allocator for that type may fail.
The allocator also may silently ignore the requested alignment.
[Note
:
Additionally, the member function allocate for that type may fail by throwing an object of type bad_­alloc.
end note
]
It is intended that a.allocate be an efficient means of allocating a single object of type T, even when sizeof(T) is small.
That is, there is no need for a container to maintain its own free list.

20.5.3.5.1 Allocator completeness requirements [allocator.requirements.completeness]

If X is an allocator class for type T, X additionally satisfies the allocator completeness requirements if, whether or not T is a complete type:
  • X is a complete type, and
  • all the member types of allocator_­traits<X> ([allocator.traits]) other than value_­type are complete types.

20.5.4 Constraints on programs [constraints]

20.5.4.1 Overview [constraints.overview]

This section describes restrictions on C++ programs that use the facilities of the C++ standard library.
The following subclauses specify constraints on the program's use of namespaces ([namespace.std]), its use of various reserved names ([reserved.names]), its use of headers ([alt.headers]), its use of standard library classes as base classes ([derived.classes]), its definitions of replacement functions ([replacement.functions]), and its installation of handler functions during execution ([handler.functions]).

20.5.4.2 Namespace use [namespace.constraints]

20.5.4.2.1 Namespace std [namespace.std]

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified.
A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.176
The behavior of a C++ program is undefined if it declares
  • an explicit specialization of any member function of a standard library class template, or
  • an explicit specialization of any member function template of a standard library class or class template, or
  • an explicit or partial specialization of any member class template of a standard library class or class template, or
  • a deduction guide for any standard library class template.
A program may explicitly instantiate a template defined in the standard library only if the declaration depends on the name of a user-defined type and the instantiation meets the standard library requirements for the original template.
A translation unit shall not declare namespace std to be an inline namespace ([namespace.def]).
Any library code that instantiates other library templates must be prepared to work adequately with any user-supplied specialization that meets the minimum requirements of this International Standard.

20.5.4.2.2 Namespace posix [namespace.posix]

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace posix or to a namespace within namespace posix unless otherwise specified.
The namespace posix is reserved for use by ISO/IEC 9945 and other POSIX standards.

20.5.4.2.3 Namespaces for future standardization [namespace.future]

Top level namespaces with a name starting with std and followed by a non-empty sequence of digits are reserved for future standardization.
The behavior of a C++ program is undefined if it adds declarations or definitions to such a namespace.
[Example
:
The top level namespace std2 is reserved for use by future revisions of this International Standard.
end example
]

20.5.4.3 Reserved names [reserved.names]

The C++ standard library reserves the following kinds of names:
If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined.

20.5.4.3.1 Zombie names [zombie.names]

In namespace std, the following names are reserved for previous standardization:

20.5.4.3.2 Macro names [macro.names]

A translation unit that includes a standard library header shall not #define or #undef names declared in any standard library header.
A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 4, or to the attribute-tokens described in [dcl.attr].

20.5.4.3.3 External linkage [extern.names]

Each name declared as an object with external linkage in a header is reserved to the implementation to designate that library object with external linkage,177 both in namespace std and in the global namespace.
Each global function signature declared with external linkage in a header is reserved to the implementation to designate that function signature with external linkage.178
Each name from the C standard library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace.
Each function signature from the C standard library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage,179 or as a name of namespace scope in the global namespace.
The list of such reserved names includes errno, declared or defined in <cerrno>.
The list of such reserved function signatures with external linkage includes setjmp(jmp_­buf), declared or defined in <csetjmp>, and va_­end(va_­list), declared or defined in <cstdarg>.
The function signatures declared in <cuchar>, <cwchar>, and <cwctype> are always reserved, notwithstanding the restrictions imposed in subclause 4.
5.
1 of Amendment 1 to the C Standard for these headers.

20.5.4.3.4 Types [extern.types]

For each type T from the C standard library,180 the types ​::​T and std​::​T are reserved to the implementation and, when defined, ​::​T shall be identical to std​::​T.
These types are clock_­t, div_­t, FILE, fpos_­t, lconv, ldiv_­t, mbstate_­t, ptrdiff_­t, sig_­atomic_­t, size_­t, time_­t, tm, va_­list, wctrans_­t, wctype_­t, and wint_­t.

20.5.4.3.5 User-defined literal suffixes [usrlit.suffix]

Literal suffix identifiers ([over.literal]) that do not start with an underscore are reserved for future standardization.

20.5.4.4 Headers [alt.headers]

If a file with a name equivalent to the derived file name for one of the C++ standard library headers is not provided as part of the implementation, and a file with that name is placed in any of the standard places for a source file to be included ([cpp.include]), the behavior is undefined.

20.5.4.5 Derived classes [derived.classes]

Virtual member function signatures defined for a base class in the C++ standard library may be overridden in a derived class defined in the program ([class.virtual]).

20.5.4.6 Replacement functions [replacement.functions]

Clauses [language.support] through [thread] and Annex [depr] describe the behavior of numerous functions defined by the C++ standard library.
Under some circumstances, however, certain of these function descriptions also apply to replacement functions defined in the program ([definitions]).
A C++ program may provide the definition for any of the following dynamic memory allocation function signatures declared in header <new> ([basic.stc.dynamic], [support.dynamic]):
operator new(std::size_t)
operator new(std::size_t, std::align_val_t)
operator new(std::size_t, const std::nothrow_t&)
operator new(std::size_t, std::align_val_t, const std::nothrow_t&)
operator delete(void*)
operator delete(void*, std::size_t)
operator delete(void*, std::align_val_t)
operator delete(void*, std::size_t, std::align_val_t)
operator delete(void*, const std::nothrow_t&)
operator delete(void*, std::align_val_t, const std::nothrow_t&)
operator new[](std::size_t)
operator new[](std::size_t, std::align_val_t)
operator new[](std::size_t, const std::nothrow_t&)
operator new[](std::size_t, std::align_val_t, const std::nothrow_t&)
operator delete[](void*)
operator delete[](void*, std::size_t)
operator delete[](void*, std::align_val_t)
operator delete[](void*, std::size_t, std::align_val_t)
operator delete[](void*, const std::nothrow_t&)
operator delete[](void*, std::align_val_t, const std::nothrow_t&)
The program's definitions are used instead of the default versions supplied by the implementation ([support.dynamic]).
Such replacement occurs prior to program startup ([basic.def.odr], [basic.start]).
The program's declarations shall not be specified as inline.
No diagnostic is required.

20.5.4.7 Handler functions [handler.functions]

The C++ standard library provides a default version of the following handler function (Clause [language.support]):
A C++ program may install different handler functions during execution, by supplying a pointer to a function defined in the program or the library as an argument to (respectively): See also subclauses [alloc.errors], Storage allocation errors, and [support.exception], Exception handling.
A C++ program can get a pointer to the current handler function by calling the following functions:
Calling the set_­* and get_­* functions shall not incur a data race.
A call to any of the set_­* functions shall synchronize with subsequent calls to the same set_­* function and to the corresponding get_­* function.

20.5.4.8 Other functions [res.on.functions]

In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program.
If these components do not meet their requirements, this International Standard places no requirements on the implementation.
In particular, the effects are undefined in the following cases:
  • for replacement functions ([new.delete]), if the installed replacement function does not implement the semantics of the applicable Required behavior: paragraph.
  • for handler functions ([new.handler], [terminate.handler]), if the installed handler function does not implement the semantics of the applicable Required behavior: paragraph
  • for types used as template arguments when instantiating a template component, if the operations on the type do not implement the semantics of the applicable Requirements subclause ([allocator.requirements], [container.requirements], [iterator.requirements], [algorithms.requirements], [numeric.requirements]).
    Operations on such types can report a failure by throwing an exception unless otherwise specified.
  • if any replacement function or handler function or destructor operation exits via an exception, unless specifically allowed in the applicable Required behavior: paragraph.
  • if an incomplete type ([basic.types]) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

20.5.4.9 Function arguments [res.on.arguments]

Each of the following applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.
  • If an argument to a function has an invalid value (such as a value outside the domain of the function or a pointer invalid for its intended use), the behavior is undefined.
  • If a function argument is described as being an array, the pointer actually passed to the function shall have a value such that all address computations and accesses to objects (that would be valid if the pointer did point to the first element of such an array) are in fact valid.
  • If a function argument binds to an rvalue reference parameter, the implementation may assume that this parameter is a unique reference to this argument.
    [Note
    :
    If the parameter is a generic parameter of the form T&& and an lvalue of type A is bound, the argument binds to an lvalue reference ([temp.deduct.call]) and thus is not covered by the previous sentence.
    end note
    ]
    [Note
    :
    If a program casts an lvalue to an xvalue while passing that lvalue to a library function (e.g. by calling the function with the argument std​::​move(x)), the program is effectively asking that function to treat that lvalue as a temporary.
    The implementation is free to optimize away aliasing checks which might be needed if the argument was an lvalue.
    end note
    ]

20.5.4.10 Library object access [res.on.objects]

The behavior of a program is undefined if calls to standard library functions from different threads may introduce a data race.
The conditions under which this may occur are specified in [res.on.data.races].
[Note
:
Modifying an object of a standard library type that is shared between threads risks undefined behavior unless objects of that type are explicitly specified as being sharable without data races or the user supplies a locking mechanism.
end note
]
If an object of a standard library type is accessed, and the beginning of the object's lifetime ([basic.life]) does not happen before the access, or the access does not happen before the end of the object's lifetime, the behavior is undefined unless otherwise specified.
[Note
:
This applies even to objects such as mutexes intended for thread synchronization.
end note
]

20.5.4.11 Requires paragraph [res.on.required]

Violation of the preconditions specified in a function's Requires: paragraph results in undefined behavior unless the function's Throws: paragraph specifies throwing an exception when the precondition is violated.

20.5.5 Conforming implementations [conforming]

20.5.5.1 Overview [conforming.overview]

This section describes the constraints upon, and latitude of, implementations of the C++ standard library.
An implementation's use of headers is discussed in [res.on.headers], its use of macros in [res.on.macro.definitions], non-member functions in [global.functions], member functions in [member.functions], data race avoidance in [res.on.data.races], access specifiers in [protection.within.classes], class derivation in [derivation], and exceptions in [res.on.exception.handling].

20.5.5.2 Headers [res.on.headers]

A C++ header may include other C++ headers.
A C++ header shall provide the declarations and definitions that appear in its synopsis.
A C++ header shown in its synopsis as including other C++ headers shall provide the declarations and definitions that appear in the synopses of those other headers.
Certain types and macros are defined in more than one header.
Every such entity shall be defined such that any header that defines it may be included after any other header that also defines it ([basic.def.odr]).
The C standard library headers ([depr.c.headers]) shall include only their corresponding C++ standard library header, as described in [headers].

20.5.5.3 Restrictions on macro definitions [res.on.macro.definitions]

The names and global function signatures described in [contents] are reserved to the implementation.
All object-like macros defined by the C standard library and described in this Clause as expanding to integral constant expressions are also suitable for use in #if preprocessing directives, unless explicitly stated otherwise.

20.5.5.4 Non-member functions [global.functions]

It is unspecified whether any non-member functions in the C++ standard library are defined as inline ([dcl.inline]).
A call to a non-member function signature described in Clauses [language.support] through [thread] and Annex [depr] shall behave as if the implementation declared no additional non-member function signatures.181
An implementation shall not declare a non-member function signature with additional default arguments.
Unless otherwise specified, calls made by functions in the standard library to non-operator, non-member functions do not use functions from another namespace which are found through argument-dependent name lookup ([basic.lookup.argdep]).
[Note
:
The phrase “unless otherwise specified” applies to cases such as the swappable with requirements ([swappable.requirements]).
The exception for overloaded operators allows argument-dependent lookup in cases like that of ostream_­iterator​::​operator= ([ostream.iterator.ops]):
Effects:
*out_stream << value;
if (delim != 0)
  *out_stream << delim;
return *this;
end note
]
A valid C++ program always calls the expected library non-member function.
An implementation may also define additional non-member functions that would otherwise not be called by a valid C++ program.

20.5.5.5 Member functions [member.functions]

It is unspecified whether any member functions in the C++ standard library are defined as inline ([dcl.inline]).
For a non-virtual member function described in the C++ standard library, an implementation may declare a different set of member function signatures, provided that any call to the member function that would select an overload from the set of declarations described in this International Standard behaves as if that overload were selected.
[Note
:
For instance, an implementation may add parameters with default values, or replace a member function with default arguments with two or more member functions with equivalent behavior, or add additional signatures for a member function name.
end note
]

20.5.5.6 Constexpr functions and constructors [constexpr.functions]

This International Standard explicitly requires that certain standard library functions are constexpr ([dcl.constexpr]).
An implementation shall not declare any standard library function signature as constexpr except for those where it is explicitly required.
Within any header that provides any non-defining declarations of constexpr functions or constructors an implementation shall provide corresponding definitions.

20.5.5.7 Requirements for stable algorithms [algorithm.stable]

When the requirements for an algorithm state that it is “stable” without further elaboration, it means:
  • For the sort algorithms the relative order of equivalent elements is preserved.
  • For the remove and copy algorithms the relative order of the elements that are not removed is preserved.
  • For the merge algorithms, for equivalent elements in the original two ranges, the elements from the first range (preserving their original order) precede the elements from the second range (preserving their original order).

20.5.5.8 Reentrancy [reentrancy]

Except where explicitly specified in this International Standard, it is implementation-defined which functions in the C++ standard library may be recursively reentered.

20.5.5.9 Data race avoidance [res.on.data.races]

This section specifies requirements that implementations shall meet to prevent data races ([intro.multithread]).
Every standard library function shall meet each requirement unless otherwise specified.
Implementations may prevent data races in cases other than those specified below.
A C++ standard library function shall not directly or indirectly access objects ([intro.multithread]) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments, including this.
A C++ standard library function shall not directly or indirectly modify objects ([intro.multithread]) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's non-const arguments, including this.
[Note
:
This means, for example, that implementations can't use a static object for internal purposes without synchronization because it could cause a data race even in programs that do not explicitly share objects between threads.
end note
]
A C++ standard library function shall not access objects indirectly accessible via its arguments or via elements of its container arguments except by invoking functions required by its specification on those container elements.
Operations on iterators obtained by calling a standard library container or string member function may access the underlying container, but shall not modify it.
[Note
:
In particular, container operations that invalidate iterators conflict with operations on iterators associated with that container.
end note
]
Implementations may share their own internal objects between threads if the objects are not visible to users and are protected against data races.
Unless otherwise specified, C++ standard library functions shall perform all operations solely within the current thread if those operations have effects that are visible ([intro.multithread]) to users.
[Note
:
This allows implementations to parallelize operations if there are no visible side effects.
end note
]

20.5.5.10 Protection within classes [protection.within.classes]

It is unspecified whether any function signature or class described in Clauses [language.support] through [thread] and Annex [depr] is a friend of another class in the C++ standard library.

20.5.5.11 Derived classes [derivation]

An implementation may derive any class in the C++ standard library from a class with a name reserved to the implementation.
Certain classes defined in the C++ standard library are required to be derived from other classes in the C++ standard library.
An implementation may derive such a class directly from the required base or indirectly through a hierarchy of base classes with names reserved to the implementation.
In any case:
  • Every base class described as virtual shall be virtual;
  • Every base class not specified as virtual shall not be virtual;
  • Unless explicitly stated otherwise, types with distinct names shall be distinct types.182
All types specified in the C++ standard library shall be non-final types unless otherwise specified.
There is an implicit exception to this rule for types that are described as synonyms for basic integral types, such as size_­t ([support.types]) and streamoff ([stream.types]).

20.5.5.12 Restrictions on exception handling [res.on.exception.handling]

Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraph, or of a type derived from a type named in the Throws: paragraph that would be caught by an exception handler for the base type.
Functions from the C standard library shall not throw exceptions183 except when such a function calls a program-supplied function that throws an exception.184
Destructor operations defined in the C++ standard library shall not throw exceptions.
Every destructor in the C++ standard library shall behave as if it had a non-throwing exception specification.
Functions defined in the C++ standard library that do not have a Throws: paragraph but do have a potentially-throwing exception specification may throw implementation-defined exceptions.185
Implementations should report errors by throwing exceptions of or derived from the standard exception classes ([bad.alloc], [support.exception], [std.exceptions]).
An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing exception specification.
That is, the C library functions can all be treated as if they are marked noexcept.
This allows implementations to make performance optimizations based on the absence of exceptions at runtime.
The functions qsort() and bsearch() ([alg.c.library]) meet this condition.
In particular, they can report a failure to allocate storage by throwing an exception of type bad_­alloc, or a class derived from bad_­alloc ([bad.alloc]).

20.5.5.13 Restrictions on storage of pointers [res.on.pointer.storage]

Objects constructed by the standard library that may hold a user-supplied pointer value or an integer of type std​::​intptr_­t shall store such values in a traceable pointer location ([basic.stc.dynamic.safety]).
[Note
:
Other libraries are strongly encouraged to do the same, since not doing so may result in accidental use of pointers that are not safely derived.
Libraries that store pointers outside the user's address space should make it appear that they are stored and retrieved from a traceable pointer location.
end note
]

20.5.5.14 Value of error codes [value.error.codes]

Certain functions in the C++ standard library report errors via a std​::​error_­code ([syserr.errcode.overview]) object.
That object's category() member shall return std​::​system_­category() for errors originating from the operating system, or a reference to an implementation-defined error_­category object for errors originating elsewhere.
The implementation shall define the possible values of value() for each of these error categories.
[Example
:
For operating systems that are based on POSIX, implementations are encouraged to define the std​::​system_­category() values as identical to the POSIX errno values, with additional values as defined by the operating system's documentation.
Implementations for operating systems that are not based on POSIX are encouraged to define values identical to the operating system's values.
For errors that do not originate from the operating system, the implementation may provide enums for the associated values.
end example
]

20.5.5.15 Moved-from state of library types [lib.types.movedfrom]

Objects of types defined in the C++ standard library may be moved from ([class.copy]).
Move operations may be explicitly specified or implicitly generated.
Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

21 Language support library [language.support]

21.1 General [support.general]

This Clause describes the function signatures that are called implicitly, and the types of objects generated implicitly, during the execution of some C++ programs.
It also describes the headers that declare these function signatures and define any related types.
The following subclauses describe common type definitions used throughout the library, characteristics of the predefined types, functions supporting start and termination of a C++ program, support for dynamic memory management, support for dynamic type identification, support for exception processing, support for initializer lists, and other runtime support, as summarized in Table 32.
Table 32 — Language support library summary
Subclause
Header(s)
Common definitions
<cstddef>
<cstdlib>
Implementation properties
<limits>
<climits>
<cfloat>
Integer types
<cstdint>
Start and termination
<cstdlib>
Dynamic memory management
<new>
Type identification
<typeinfo>
Exception handling
<exception>
Initializer lists
<initializer_­list>
Other runtime support
<csignal>
<csetjmp>
<cstdarg>
<cstdlib>

21.2 Common definitions [support.types]

21.2.1 Header <cstddef> synopsis [cstddef.syn]

namespace std {
  using ptrdiff_t = see below;
  using size_t = see below;
  using max_align_t = see below;
  using nullptr_t = decltype(nullptr);

  enum class byte : unsigned char {};

  // [support.types.byteops], byte type operations
  template <class IntType>
    constexpr byte& operator<<=(byte& b, IntType shift) noexcept;
  template <class IntType>
    constexpr byte operator<<(byte b, IntType shift) noexcept;
  template <class IntType>
    constexpr byte& operator>>=(byte& b, IntType shift) noexcept;
  template <class IntType>
    constexpr byte operator>>(byte b, IntType shift) noexcept;
  constexpr byte& operator|=(byte& l, byte r) noexcept;
  constexpr byte operator|(byte l, byte r) noexcept;
  constexpr byte& operator&=(byte& l, byte r) noexcept;
  constexpr byte operator&(byte l, byte r) noexcept;
  constexpr byte& operator^=(byte& l, byte r) noexcept;
  constexpr byte operator^(byte l, byte r) noexcept;
  constexpr byte operator~(byte b) noexcept;
  template <class IntType>
    constexpr IntType to_integer(byte b) noexcept;
}

#define NULL see below
#define offsetof(P, D) see below
The contents and meaning of the header <cstddef> are the same as the C standard library header <stddef.h>, except that it does not declare the type wchar_­t, that it also declares the type byte and its associated operations ([support.types.byteops]), and as noted in [support.types.nullptr] and [support.types.layout].
See also: ISO C 7.
19

21.2.2 Header <cstdlib> synopsis [cstdlib.syn]

namespace std {
  using size_t = see below;
  using div_t = see below;
  using ldiv_t = see below;
  using lldiv_t = see below;
}

#define NULL see below
#define EXIT_FAILURE see below
#define EXIT_SUCCESS see below
#define RAND_MAX see below
#define MB_CUR_MAX see below

namespace std {
  // Exposition-only function type aliases
  extern "C" using c-atexit-handler = void();                        // exposition only
  extern "C++" using atexit-handler = void();                        // exposition only
  extern "C" using c-compare-pred = int(const void*, const void*);   // exposition only
  extern "C++" using compare-pred = int(const void*, const void*);   // exposition only

  // [support.start.term], start and termination
  [[noreturn]] void abort() noexcept;
  int atexit(c-atexit-handler* func) noexcept;
  int atexit(atexit-handler* func) noexcept;
  int at_quick_exit(c-atexit-handler* func) noexcept;
  int at_quick_exit(atexit-handler* func) noexcept;
  [[noreturn]] void exit(int status);
  [[noreturn]] void _Exit(int status) noexcept;
  [[noreturn]] void quick_exit(int status) noexcept;

  char* getenv(const char* name);
  int system(const char* string);

  // [c.malloc], C library memory allocation
  void* aligned_alloc(size_t alignment, size_t size);
  void* calloc(size_t nmemb, size_t size);
  void free(void* ptr);
  void* malloc(size_t size);
  void* realloc(void* ptr, size_t size);

  double atof(const char* nptr);
  int atoi(const char* nptr);
  long int atol(const char* nptr);
  long long int atoll(const char* nptr);
  double strtod(const char* nptr, char** endptr);
  float strtof(const char* nptr, char** endptr);
  long double strtold(const char* nptr, char** endptr);
  long int strtol(const char* nptr, char** endptr, int base);
  long long int strtoll(const char* nptr, char** endptr, int base);
  unsigned long int strtoul(const char* nptr, char** endptr, int base);
  unsigned long long int strtoull(const char* nptr, char** endptr, int base);

  // [c.mb.wcs], multibyte / wide string and character conversion functions
  int mblen(const char* s, size_t n);
  int mbtowc(wchar_t* pwc, const char* s, size_t n);
  int wctomb(char* s, wchar_t wchar);
  size_t mbstowcs(wchar_t* pwcs, const char* s, size_t n);
  size_t wcstombs(char* s, const wchar_t* pwcs, size_t n);

  // [alg.c.library], C standard library algorithms
  void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
                c-compare-pred* compar);
  void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
                compare-pred* compar);
  void qsort(void* base, size_t nmemb, size_t size, c-compare-pred* compar);
  void qsort(void* base, size_t nmemb, size_t size, compare-pred* compar);

  // [c.math.rand], low-quality random number generation
  int rand();
  void srand(unsigned int seed);

  // [c.math.abs], absolute values
  int abs(int j);
  long int abs(long int j);
  long long int abs(long long int j);
  float abs(float j);
  double abs(double j);
  long double abs(long double j);

  long int labs(long int j);
  long long int llabs(long long int j);

  div_t div(int numer, int denom);
  ldiv_t div(long int numer, long int denom);             // see [library.c]
  lldiv_t div(long long int numer, long long int denom);  // see [library.c]
  ldiv_t ldiv(long int numer, long int denom);
  lldiv_t lldiv(long long int numer, long long int denom);
}
The contents and meaning of the header <cstdlib> are the same as the C standard library header <stdlib.h>, except that it does not declare the type wchar_­t, and except as noted in [support.types.nullptr], [support.types.layout], [support.start.term], [c.malloc], [c.mb.wcs], [alg.c.library], [c.math.rand], and [c.math.abs].
[Note
:
Several functions have additional overloads in this International Standard, but they have the same behavior as in the C standard library ([library.c]).
end note
]
See also: ISO C 7.
22

21.2.3 Null pointers [support.types.nullptr]

The type nullptr_­t is a synonym for the type of a nullptr expression, and it has the characteristics described in [basic.fundamental] and [conv.ptr].
[Note
:
Although nullptr's address cannot be taken, the address of another nullptr_­t object that is an lvalue can be taken.
end note
]
The macro NULL is an implementation-defined null pointer constant.186
Possible definitions include 0 and 0L, but not (void*)0.

21.2.4 Sizes, alignments, and offsets [support.types.layout]

The macro offsetof(type, member-designator) has the same semantics as the corresponding macro in the C standard library header <stddef.h>, but accepts a restricted set of type arguments in this International Standard.
Use of the offsetof macro with a type other than a standard-layout class (Clause [class]) is conditionally-supported.187
The expression offsetof(type, member-designator) is never type-dependent ([temp.dep.expr]) and it is value-dependent ([temp.dep.constexpr]) if and only if type is dependent.
The result of applying the offsetof macro to a static data member or a function member is undefined.
No operation invoked by the offsetof macro shall throw an exception and noexcept(offsetof(type, member-designator)) shall be true.
The type ptrdiff_­t is an implementation-defined signed integer type that can hold the difference of two subscripts in an array object, as described in [expr.add].
The type size_­t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.
[Note
:
It is recommended that implementations choose types for ptrdiff_­t and size_­t whose integer conversion ranks ([conv.rank]) are no greater than that of signed long int unless a larger size is necessary to contain all the possible values.
end note
]
The type max_­align_­t is a POD type whose alignment requirement is at least as great as that of every scalar type, and whose alignment requirement is supported in every context.
See also: Alignment ([basic.align]), Sizeof ([expr.sizeof]), Additive operators ([expr.add]), Free store ([class.free]), and ISO C 7.
19.
Note that offsetof is required to work as specified even if unary operator& is overloaded for any of the types involved.

21.2.5 byte type operations [support.types.byteops]

template <class IntType> constexpr byte& operator<<=(byte& b, IntType shift) noexcept;
Remarks: This function shall not participate in overload resolution unless is_­integral_­v<IntType> is true.
Effects: Equivalent to: return b = byte(static_­cast<unsigned char>(b) << shift);
template <class IntType> constexpr byte operator<<(byte b, IntType shift) noexcept;
Remarks: This function shall not participate in overload resolution unless is_­integral_­v<IntType> is true.
Effects: Equivalent to: return byte(static_­cast<unsigned char>(b) << shift);
template <class IntType> constexpr byte& operator>>=(byte& b, IntType shift) noexcept;
Remarks: This function shall not participate in overload resolution unless is_­integral_­v<IntType> is true.
Effects: Equivalent to: return b = byte(static_­cast<unsigned char>(b) >> shift);
template <class IntType> constexpr byte operator>>(byte b, IntType shift) noexcept;
Remarks: This function shall not participate in overload resolution unless is_­integral_­v<IntType> is true.
Effects: Equivalent to: return byte(static_­cast<unsigned char>(b) >> shift);
constexpr byte& operator|=(byte& l, byte r) noexcept;
Effects: Equivalent to:
return l = byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r));
constexpr byte operator|(byte l, byte r) noexcept;
Effects: Equivalent to:
return byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r));
constexpr byte& operator&=(byte& l, byte r) noexcept;
Effects: Equivalent to:
return l = byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
constexpr byte operator&(byte l, byte r) noexcept;
Effects: Equivalent to:
return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
constexpr byte& operator^=(byte& l, byte r) noexcept;
Effects: Equivalent to:
return l = byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
constexpr byte operator^(byte l, byte r) noexcept;
Effects: Equivalent to:
return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
constexpr byte operator~(byte b) noexcept;
Effects: Equivalent to: return byte(~static_­cast<unsigned char>(b));
template <class IntType> constexpr IntType to_integer(byte b) noexcept;
Remarks: This function shall not participate in overload resolution unless is_­integral_­v<IntType> is true.
Effects: Equivalent to: return IntType(b);

21.3 Implementation properties [support.limits]

21.3.1 General [support.limits.general]

The headers <limits> ([limits.syn]), <climits> ([climits.syn]), and <cfloat> ([cfloat.syn]) supply characteristics of implementation-dependent arithmetic types ([basic.fundamental]).

21.3.2 Header <limits> synopsis [limits.syn]

namespace std {
  // [fp.style], floating-point type properties
  enum float_round_style;
  enum float_denorm_style;

  // [numeric.limits], class template numeric_­limits
  template<class T> class numeric_limits;

  template<> class numeric_limits<bool>;

  template<> class numeric_limits<char>;
  template<> class numeric_limits<signed char>;
  template<> class numeric_limits<unsigned char>;
  template<> class numeric_limits<char16_t>;
  template<> class numeric_limits<char32_t>;
  template<> class numeric_limits<wchar_t>;

  template<> class numeric_limits<short>;
  template<> class numeric_limits<int>;
  template<> class numeric_limits<long>;
  template<> class numeric_limits<long long>;
  template<> class numeric_limits<unsigned short>;
  template<> class numeric_limits<unsigned int>;
  template<> class numeric_limits<unsigned long>;
  template<> class numeric_limits<unsigned long long>;

  template<> class numeric_limits<float>;
  template<> class numeric_limits<double>;
  template<> class numeric_limits<long double>;
}

21.3.3 Floating-point type properties [fp.style]

21.3.3.1 Type float_­round_­style [round.style]

namespace std {
  enum float_round_style {
    round_indeterminate       = -1,
    round_toward_zero         =  0,
    round_to_nearest          =  1,
    round_toward_infinity     =  2,
    round_toward_neg_infinity =  3
  };
}
The rounding mode for floating-point arithmetic is characterized by the values:
  • round_­indeterminate if the rounding style is indeterminable
  • round_­toward_­zero if the rounding style is toward zero
  • round_­to_­nearest if the rounding style is to the nearest representable value
  • round_­toward_­infinity if the rounding style is toward infinity
  • round_­toward_­neg_­infinity if the rounding style is toward negative infinity

21.3.3.2 Type float_­denorm_­style [denorm.style]

namespace std {
  enum float_denorm_style {
    denorm_indeterminate = -1,
    denorm_absent = 0,
    denorm_present = 1
  };
}
The presence or absence of subnormal numbers (variable number of exponent bits) is characterized by the values:
  • denorm_­indeterminate if it cannot be determined whether or not the type allows subnormal values
  • denorm_­absent if the type does not allow subnormal values
  • denorm_­present if the type does allow subnormal values

21.3.4 Class template numeric_­limits [numeric.limits]

The numeric_­limits class template provides a C++ program with information about various properties of the implementation's representation of the arithmetic types.
namespace std {
  template<class T> class numeric_limits {
  public:
    static constexpr bool is_specialized = false;
    static constexpr T min() noexcept { return T(); }
    static constexpr T max() noexcept { return T(); }
    static constexpr T lowest() noexcept { return T(); }

    static constexpr int  digits = 0;
    static constexpr int  digits10 = 0;
    static constexpr int  max_digits10 = 0;
    static constexpr bool is_signed = false;
    static constexpr bool is_integer = false;
    static constexpr bool is_exact = false;
    static constexpr int  radix = 0;
    static constexpr T epsilon() noexcept { return T(); }
    static constexpr T round_error() noexcept { return T(); }

    static constexpr int  min_exponent = 0;
    static constexpr int  min_exponent10 = 0;
    static constexpr int  max_exponent = 0;
    static constexpr int  max_exponent10 = 0;

    static constexpr bool has_infinity = false;
    static constexpr bool has_quiet_NaN = false;
    static constexpr bool has_signaling_NaN = false;
    static constexpr float_denorm_style has_denorm = denorm_absent;
    static constexpr bool has_denorm_loss = false;
    static constexpr T infinity() noexcept { return T(); }
    static constexpr T quiet_NaN() noexcept { return T(); }
    static constexpr T signaling_NaN() noexcept { return T(); }
    static constexpr T denorm_min() noexcept { return T(); }

    static constexpr bool is_iec559 = false;
    static constexpr bool is_bounded = false;
    static constexpr bool is_modulo = false;

    static constexpr bool traps = false;
    static constexpr bool tinyness_before = false;
    static constexpr float_round_style round_style = round_toward_zero;
  };

  template<class T> class numeric_limits<const T>;
  template<class T> class numeric_limits<volatile T>;
  template<class T> class numeric_limits<const volatile T>;
}
For all members declared static constexpr in the numeric_­limits template, specializations shall define these values in such a way that they are usable as constant expressions.
The default numeric_­limits<T> template shall have all members, but with 0 or false values.
Specializations shall be provided for each arithmetic type, both floating-point and integer, including bool.
The member is_­specialized shall be true for all such specializations of numeric_­limits.
The value of each member of a specialization of numeric_­limits on a cv-qualified type cv T shall be equal to the value of the corresponding member of the specialization on the unqualified type T.
Non-arithmetic standard types, such as complex<T> ([complex]), shall not have specializations.

21.3.4.1 numeric_­limits members [numeric.limits.members]

Each member function defined in this subclause is signal-safe ([csignal.syn]).
static constexpr T min() noexcept;
Minimum finite value.188
For floating types with subnormal numbers, returns the minimum positive normalized value.
Meaningful for all specializations in which is_­bounded != false, or is_­bounded == false && is_­signed == false.
static constexpr T max() noexcept;
Maximum finite value.189
Meaningful for all specializations in which is_­bounded != false.
static constexpr T lowest() noexcept;
A finite value x such that there is no other finite value y where y < x.190
Meaningful for all specializations in which is_­bounded != false.
static constexpr int digits;
Number of radix digits that can be represented without change.
For integer types, the number of non-sign bits in the representation.
For floating-point types, the number of radix digits in the mantissa.191
static constexpr int digits10;
Number of base 10 digits that can be represented without change.192
Meaningful for all specializations in which is_­bounded != false.
static constexpr int max_digits10;
Number of base 10 digits required to ensure that values which differ are always differentiated.
Meaningful for all floating-point types.
static constexpr bool is_signed;
true if the type is signed.
Meaningful for all specializations.
static constexpr bool is_integer;
true if the type is integer.
Meaningful for all specializations.
static constexpr bool is_exact;
true if the type uses an exact representation.
All integer types are exact, but not all exact types are integer.
For example, rational and fixed-exponent representations are exact but not integer.
Meaningful for all specializations.
static constexpr int radix;
For floating types, specifies the base or radix of the exponent representation (often 2).193
For integer types, specifies the base of the representation.194
Meaningful for all specializations.
static constexpr T epsilon() noexcept;
Machine epsilon: the difference between 1 and the least value greater than 1 that is representable.195
Meaningful for all floating-point types.
static constexpr T round_error() noexcept;
Measure of the maximum rounding error.196
static constexpr int min_exponent;
Minimum negative integer such that radix raised to the power of one less than that integer is a normalized floating-point number.197
Meaningful for all floating-point types.
static constexpr int min_exponent10;
Minimum negative integer such that 10 raised to that power is in the range of normalized floating-point numbers.198
Meaningful for all floating-point types.
static constexpr int max_exponent;
Maximum positive integer such that radix raised to the power one less than that integer is a representable finite floating-point number.199
Meaningful for all floating-point types.
static constexpr int max_exponent10;
Maximum positive integer such that 10 raised to that power is in the range of representable finite floating-point numbers.200
Meaningful for all floating-point types.
static constexpr bool has_infinity;
true if the type has a representation for positive infinity.
Meaningful for all floating-point types.
Shall be true for all specializations in which is_­iec559 != false.
static constexpr bool has_quiet_NaN;
true if the type has a representation for a quiet (non-signaling) “Not a Number”.201
Meaningful for all floating-point types.
Shall be true for all specializations in which is_­iec559 != false.
static constexpr bool has_signaling_NaN;
true if the type has a representation for a signaling “Not a Number”.202
Meaningful for all floating-point types.
Shall be true for all specializations in which is_­iec559 != false.
static constexpr float_denorm_style has_denorm;
denorm_­present if the type allows subnormal values (variable number of exponent bits)203, denorm_­absent if the type does not allow subnormal values, and denorm_­indeterminate if it is indeterminate at compile time whether the type allows subnormal values.
Meaningful for all floating-point types.
static constexpr bool has_denorm_loss;
true if loss of accuracy is detected as a denormalization loss, rather than as an inexact result.204
static constexpr T infinity() noexcept;
Representation of positive infinity, if available.205
Meaningful for all specializations for which has_­infinity != false.
Required in specializations for which is_­iec559 != false.
static constexpr T quiet_NaN() noexcept;
Representation of a quiet “Not a Number”, if available.206
Meaningful for all specializations for which has_­quiet_­NaN != false.
Required in specializations for which is_­iec559 != false.
static constexpr T signaling_NaN() noexcept;
Representation of a signaling “Not a Number”, if available.207
Meaningful for all specializations for which has_­signaling_­NaN != false.
Required in specializations for which is_­iec559 != false.
static constexpr T denorm_min() noexcept;
Minimum positive subnormal value.208
Meaningful for all floating-point types.
In specializations for which has_­denorm == false, returns the minimum positive normalized value.
static constexpr bool is_iec559;
true if and only if the type adheres to ISO/IEC/IEEE 60559.209
Meaningful for all floating-point types.
static constexpr bool is_bounded;
true if the set of values representable by the type is finite.210
[Note
:
All fundamental types ([basic.fundamental]) are bounded.
This member would be false for arbitrary precision types.
end note
]
Meaningful for all specializations.
static constexpr bool is_modulo;
true if the type is modulo.211
A type is modulo if, for any operation involving +, -, or * on values of that type whose result would fall outside the range [min(), max()], the value returned differs from the true value by an integer multiple of max() - min() + 1.
[Example
:
is_­modulo is false for signed integer types ([basic.fundamental]) unless an implementation, as an extension to this International Standard, defines signed integer overflow to wrap.
end example
]
Meaningful for all specializations.
static constexpr bool traps;
true if, at program startup, there exists a value of the type that would cause an arithmetic operation using that value to trap.212
Meaningful for all specializations.
static constexpr bool tinyness_before;
true if tinyness is detected before rounding.213
Meaningful for all floating-point types.
static constexpr float_round_style round_style;
The rounding style for the type.214
Meaningful for all floating-point types.
Specializations for integer types shall return round_­toward_­zero.
Equivalent to CHAR_­MIN, SHRT_­MIN, FLT_­MIN, DBL_­MIN, etc.
Equivalent to CHAR_­MAX, SHRT_­MAX, FLT_­MAX, DBL_­MAX, etc.
lowest() is necessary because not all floating-point representations have a smallest (most negative) value that is the negative of the largest (most positive) finite value.
Equivalent to FLT_­MANT_­DIG, DBL_­MANT_­DIG, LDBL_­MANT_­DIG.
Equivalent to FLT_­DIG, DBL_­DIG, LDBL_­DIG.
Equivalent to FLT_­RADIX.
Distinguishes types with bases other than 2 (e.g. BCD).
Equivalent to FLT_­EPSILON, DBL_­EPSILON, LDBL_­EPSILON.
Rounding error is described in LIA-1 Section 5.
2.
4 and Annex C Rationale Section C.
5.
2.
4 — Rounding and rounding constants.
Equivalent to FLT_­MIN_­EXP, DBL_­MIN_­EXP, LDBL_­MIN_­EXP.
Equivalent to FLT_­MIN_­10_­EXP, DBL_­MIN_­10_­EXP, LDBL_­MIN_­10_­EXP.
Equivalent to FLT_­MAX_­EXP, DBL_­MAX_­EXP, LDBL_­MAX_­EXP.
Equivalent to FLT_­MAX_­10_­EXP, DBL_­MAX_­10_­EXP, LDBL_­MAX_­10_­EXP.
Required by LIA-1.
Required by LIA-1.
Required by LIA-1.
See ISO/IEC/IEEE 60559.
Required by LIA-1.
Required by LIA-1.
Required by LIA-1.
Required by LIA-1.
ISO/IEC/IEEE 60559:2011 is the same as IEEE 754-2008.
Required by LIA-1.
Required by LIA-1.
Required by LIA-1.
Refer to ISO/IEC/IEEE 60559.
Required by LIA-1.
Equivalent to FLT_­ROUNDS.
Required by LIA-1.

21.3.4.2 numeric_­limits specializations [numeric.special]

All members shall be provided for all specializations.
However, many values are only required to be meaningful under certain conditions (for example, epsilon() is only meaningful if is_­integer is false).
Any value that is not “meaningful” shall be set to 0 or false.
[Example
:
namespace std {
  template<> class numeric_limits<float> {
  public:
    static constexpr bool is_specialized = true;

    static constexpr float min() noexcept { return 1.17549435E-38F; }
    static constexpr float max() noexcept { return 3.40282347E+38F; }
    static constexpr float lowest() noexcept { return -3.40282347E+38F; }

    static constexpr int digits   = 24;
    static constexpr int digits10 =  6;
    static constexpr int max_digits10 =  9;

    static constexpr bool is_signed  = true;
    static constexpr bool is_integer = false;
    static constexpr bool is_exact   = false;

    static constexpr int radix = 2;
    static constexpr float epsilon() noexcept     { return 1.19209290E-07F; }
    static constexpr float round_error() noexcept { return 0.5F; }

    static constexpr int min_exponent   = -125;
    static constexpr int min_exponent10 = - 37;
    static constexpr int max_exponent   = +128;
    static constexpr int max_exponent10 = + 38;

    static constexpr bool has_infinity             = true;
    static constexpr bool has_quiet_NaN            = true;
    static constexpr bool has_signaling_NaN        = true;
    static constexpr float_denorm_style has_denorm = denorm_absent;
    static constexpr bool has_denorm_loss          = false;

    static constexpr float infinity()      noexcept { return value; }
    static constexpr float quiet_NaN()     noexcept { return value; }
    static constexpr float signaling_NaN() noexcept { return value; }
    static constexpr float denorm_min()    noexcept { return min(); }

    static constexpr bool is_iec559  = true;
    static constexpr bool is_bounded = true;
    static constexpr bool is_modulo  = false;
    static constexpr bool traps      = true;
    static constexpr bool tinyness_before = true;

    static constexpr float_round_style round_style = round_to_nearest;
  };
}
end example
]
The specialization for bool shall be provided as follows:
namespace std {
   template<> class numeric_limits<bool> {
   public:
     static constexpr bool is_specialized = true;
     static constexpr bool min() noexcept { return false; }
     static constexpr bool max() noexcept { return true; }
     static constexpr bool lowest() noexcept { return false; }

     static constexpr int  digits = 1;
     static constexpr int  digits10 = 0;
     static constexpr int  max_digits10 = 0;

     static constexpr bool is_signed = false;
     static constexpr bool is_integer = true;
     static constexpr bool is_exact = true;
     static constexpr int  radix = 2;
     static constexpr bool epsilon() noexcept { return 0; }
     static constexpr bool round_error() noexcept { return 0; }

     static constexpr int  min_exponent = 0;
     static constexpr int  min_exponent10 = 0;
     static constexpr int  max_exponent = 0;
     static constexpr int  max_exponent10 = 0;

     static constexpr bool has_infinity = false;
     static constexpr bool has_quiet_NaN = false;
     static constexpr bool has_signaling_NaN = false;
     static constexpr float_denorm_style has_denorm = denorm_absent;
     static constexpr bool has_denorm_loss = false;
     static constexpr bool infinity() noexcept { return 0; }
     static constexpr bool quiet_NaN() noexcept { return 0; }
     static constexpr bool signaling_NaN() noexcept { return 0; }
     static constexpr bool denorm_min() noexcept { return 0; }

     static constexpr bool is_iec559 = false;
     static constexpr bool is_bounded = true;
     static constexpr bool is_modulo = false;

     static constexpr bool traps = false;
     static constexpr bool tinyness_before = false;
     static constexpr float_round_style round_style = round_toward_zero;
   };
}

21.3.5 Header <climits> synopsis [climits.syn]

#define CHAR_BIT see below
#define SCHAR_MIN see below
#define SCHAR_MAX see below
#define UCHAR_MAX see below
#define CHAR_MIN see below
#define CHAR_MAX see below
#define MB_LEN_MAX see below
#define SHRT_MIN see below
#define SHRT_MAX see below
#define USHRT_MAX see below
#define INT_MIN see below
#define INT_MAX see below
#define UINT_MAX see below
#define LONG_MIN see below
#define LONG_MAX see below
#define ULONG_MAX see below
#define LLONG_MIN see below
#define LLONG_MAX see below
#define ULLONG_MAX see below
The header <climits> defines all macros the same as the C standard library header <limits.h>.
[Note
:
The types of the constants defined by macros in <climits> are not required to match the types to which the macros refer.
end note
]
See also: ISO C 5.
2.
4.
2.
1

21.3.6 Header <cfloat> synopsis [cfloat.syn]

#define FLT_ROUNDS see below
#define FLT_EVAL_METHOD see below
#define FLT_HAS_SUBNORM see below
#define DBL_HAS_SUBNORM see below
#define LDBL_HAS_SUBNORM see below
#define FLT_RADIX see below
#define FLT_MANT_DIG see below
#define DBL_MANT_DIG see below
#define LDBL_MANT_DIG see below
#define FLT_DECIMAL_DIG see below
#define DBL_DECIMAL_DIG see below
#define LDBL_DECIMAL_DIG see below
#define DECIMAL_DIG see below
#define FLT_DIG see below
#define DBL_DIG see below
#define LDBL_DIG see below
#define FLT_MIN_EXP see below
#define DBL_MIN_EXP see below
#define LDBL_MIN_EXP see below
#define FLT_MIN_10_EXP see below
#define DBL_MIN_10_EXP see below
#define LDBL_MIN_10_EXP see below
#define FLT_MAX_EXP see below
#define DBL_MAX_EXP see below
#define LDBL_MAX_EXP see below
#define FLT_MAX_10_EXP see below
#define DBL_MAX_10_EXP see below
#define LDBL_MAX_10_EXP see below
#define FLT_MAX see below
#define DBL_MAX see below
#define LDBL_MAX see below
#define FLT_EPSILON see below
#define DBL_EPSILON see below
#define LDBL_EPSILON see below
#define FLT_MIN see below
#define DBL_MIN see below
#define LDBL_MIN see below
#define FLT_TRUE_MIN see below
#define DBL_TRUE_MIN see below
#define LDBL_TRUE_MIN see below
The header <cfloat> defines all macros the same as the C standard library header <float.h>.
See also: ISO C 5.
2.
4.
2.
2

21.4 Integer types [cstdint]

21.4.1 Header <cstdint> synopsis [cstdint.syn]

namespace std {
  using int8_t         = signed integer type;  // optional
  using int16_t        = signed integer type;  // optional
  using int32_t        = signed integer type;  // optional
  using int64_t        = signed integer type;  // optional

  using int_fast8_t    = signed integer type;
  using int_fast16_t   = signed integer type;
  using int_fast32_t   = signed integer type;
  using int_fast64_t   = signed integer type;

  using int_least8_t   = signed integer type;
  using int_least16_t  = signed integer type;
  using int_least32_t  = signed integer type;
  using int_least64_t  = signed integer type;

  using intmax_t       = signed integer type;
  using intptr_t       = signed integer type;   // optional

  using uint8_t        = unsigned integer type; // optional
  using uint16_t       = unsigned integer type; // optional
  using uint32_t       = unsigned integer type; // optional
  using uint64_t       = unsigned integer type; // optional

  using uint_fast8_t   = unsigned integer type;
  using uint_fast16_t  = unsigned integer type;
  using uint_fast32_t  = unsigned integer type;
  using uint_fast64_t  = unsigned integer type;

  using uint_least8_t  = unsigned integer type;
  using uint_least16_t = unsigned integer type;
  using uint_least32_t = unsigned integer type;
  using uint_least64_t = unsigned integer type;

  using uintmax_t      = unsigned integer type;
  using uintptr_t      = unsigned integer type; // optional
}
The header also defines numerous macros of the form:
  INT_[FAST LEAST]{8 16 32 64}_MIN
  [U]INT_[FAST LEAST]{8 16 32 64}_MAX
  INT{MAX PTR}_MIN
  [U]INT{MAX PTR}_MAX
  {PTRDIFF SIG_ATOMIC WCHAR WINT}{_MAX _MIN}
  SIZE_MAX
plus function macros of the form:
  [U]INT{8 16 32 64 MAX}_C
The header defines all types and macros the same as the C standard library header <stdint.h>.
See also: ISO C 7.
20.

21.5 Start and termination [support.start.term]

[Note
:
The header <cstdlib> ([cstdlib.syn]) declares the functions described in this subclause.
end note
]
[[noreturn]] void _Exit(int status) noexcept;
Effects: This function has the semantics specified in the C standard library.
Remarks: The program is terminated without executing destructors for objects of automatic, thread, or static storage duration and without calling functions passed to atexit() ([basic.start.term]).
The function _­Exit is signal-safe ([csignal.syn]).
[[noreturn]] void abort() noexcept;
Effects: This function has the semantics specified in the C standard library.
Remarks: The program is terminated without executing destructors for objects of automatic, thread, or static storage duration and without calling functions passed to atexit() ([basic.start.term]).
The function abort is signal-safe ([csignal.syn]).
int atexit(c-atexit-handler* f) noexcept; int atexit(atexit-handler* f) noexcept;
Effects: The atexit() functions register the function pointed to by f to be called without arguments at normal program termination.
It is unspecified whether a call to atexit() that does not happen before ([intro.multithread]) a call to exit() will succeed.
[Note
:
The atexit() functions do not introduce a data race ([res.on.data.races]).
end note
]
Implementation limits: The implementation shall support the registration of at least 32 functions.
Returns: The atexit() function returns zero if the registration succeeds, nonzero if it fails.
[[noreturn]] void exit(int status);
Effects:
  • First, objects with thread storage duration and associated with the current thread are destroyed.
    Next, objects with static storage duration are destroyed and functions registered by calling atexit are called.215
    See [basic.start.term] for the order of destructions and calls.
    (Automatic objects are not destroyed as a result of calling exit().)216
    If control leaves a registered function called by exit because the function does not provide a handler for a thrown exception, std​::​terminate() shall be called ([except.terminate]).
  • Next, all open C streams (as mediated by the function signatures declared in <cstdio>) with unwritten buffered data are flushed, all open C streams are closed, and all files created by calling tmpfile() are removed.
  • Finally, control is returned to the host environment.
    If status is zero or EXIT_­SUCCESS, an implementation-defined form of the status successful termination is returned.
    If status is EXIT_­FAILURE, an implementation-defined form of the status unsuccessful termination is returned.
    Otherwise the status returned is implementation-defined.217
int at_quick_exit(c-atexit-handler* f) noexcept; int at_quick_exit(atexit-handler* f) noexcept;
Effects: The at_­quick_­exit() functions register the function pointed to by f to be called without arguments when quick_­exit is called.
It is unspecified whether a call to at_­quick_­exit() that does not happen before ([intro.multithread]) all calls to quick_­exit will succeed.
[Note
:
The at_­quick_­exit() functions do not introduce a data race ([res.on.data.races]).
end note
]
[Note
:
The order of registration may be indeterminate if at_­quick_­exit was called from more than one thread.
end note
]
[Note
:
The at_­quick_­exit registrations are distinct from the atexit registrations, and applications may need to call both registration functions with the same argument.
end note
]
Implementation limits: The implementation shall support the registration of at least 32 functions.
Returns: Zero if the registration succeeds, nonzero if it fails.
[[noreturn]] void quick_exit(int status) noexcept;
Effects: Functions registered by calls to at_­quick_­exit are called in the reverse order of their registration, except that a function shall be called after any previously registered functions that had already been called at the time it was registered.
Objects shall not be destroyed as a result of calling quick_­exit.
If control leaves a registered function called by quick_­exit because the function does not provide a handler for a thrown exception, std​::​terminate() shall be called.
[Note
:
A function registered via at_­quick_­exit is invoked by the thread that calls quick_­exit, which can be a different thread than the one that registered it, so registered functions should not rely on the identity of objects with thread storage duration.
end note
]
After calling registered functions, quick_­exit shall call _­Exit(status).
[Note
:
The standard file buffers are not flushed.
end note
]
Remarks: The function quick_­exit is signal-safe ([csignal.syn]) when the functions registered with at_­quick_­exit are.
22.
4.
A function is called for every time it is registered.
Objects with automatic storage duration are all destroyed in a program whose main function ([basic.start.main]) contains no automatic objects and executes the call to exit().
Control can be transferred directly to such a main function by throwing an exception that is caught in main.
The macros EXIT_­FAILURE and EXIT_­SUCCESS are defined in <cstdlib>.

21.6 Dynamic memory management [support.dynamic]

The header <new> defines several functions that manage the allocation of dynamic storage in a program.
It also defines components for reporting storage management errors.

21.6.1 Header <new> synopsis [new.syn]

namespace std {
  class bad_alloc;
  class bad_array_new_length;
  enum class align_val_t : size_t {};
  struct nothrow_t { explicit nothrow_t() = default; };
  extern const nothrow_t nothrow;
  using new_handler = void (*)();
  new_handler get_new_handler() noexcept;
  new_handler set_new_handler(new_handler new_p) noexcept;

  // [ptr.launder], pointer optimization barrier
  template <class T> constexpr T* launder(T* p) noexcept;

  // [hardware.interference], hardware interference size
  inline constexpr size_t hardware_destructive_interference_size = implementation-defined;
  inline constexpr size_t hardware_constructive_interference_size = implementation-defined;
}

void* operator new(std::size_t size);
void* operator new(std::size_t size, std::align_val_t alignment);
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void* operator new(std::size_t size, std::align_val_t alignment,
                   const std::nothrow_t&) noexcept;
void  operator delete(void* ptr) noexcept;
void  operator delete(void* ptr, std::size_t size) noexcept;
void  operator delete(void* ptr, std::align_val_t alignment) noexcept;
void  operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
void  operator delete(void* ptr, const std::nothrow_t&) noexcept;
void  operator delete(void* ptr, std::align_val_t alignment,
                      const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size);
void* operator new[](std::size_t size, std::align_val_t alignment);
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, std::align_val_t alignment,
                     const std::nothrow_t&) noexcept;
void  operator delete[](void* ptr) noexcept;
void  operator delete[](void* ptr, std::size_t size) noexcept;
void  operator delete[](void* ptr, std::align_val_t alignment) noexcept;
void  operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
void  operator delete[](void* ptr, const std::nothrow_t&) noexcept;
void  operator delete[](void* ptr, std::align_val_t alignment,
                        const std::nothrow_t&) noexcept;

void* operator new  (std::size_t size, void* ptr) noexcept;
void* operator new[](std::size_t size, void* ptr) noexcept;
void  operator delete  (void* ptr, void*) noexcept;
void  operator delete[](void* ptr, void*) noexcept;
See also: [intro.memory], [basic.stc.dynamic], [expr.new], [expr.delete], [class.free], [memory].

21.6.2 Storage allocation and deallocation [new.delete]

Except where otherwise specified, the provisions of [basic.stc.dynamic] apply to the library versions of operator new and operator delete.
If the value of an alignment argument passed to any of these functions is not a valid alignment value, the behavior is undefined.

21.6.2.1 Single-object forms [new.delete.single]

void* operator new(std::size_t size); void* operator new(std::size_t size, std::align_val_t alignment);
Effects: The allocation functions ([basic.stc.dynamic.allocation]) called by a new-expression to allocate size bytes of storage.
The second form is called for a type with new-extended alignment, and allocates storage with the specified alignment.
The first form is called otherwise, and allocates storage suitably aligned to represent any object of that size provided the object's type does not have new-extended alignment.
Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.
Required behavior: Return a non-null pointer to suitably aligned storage ([basic.stc.dynamic]), or else throw a bad_­alloc exception.
This requirement is binding on any replacement versions of these functions.
Default behavior:
  • Executes a loop: Within the loop, the function first attempts to allocate the requested storage.
    Whether the attempt involves a call to the C standard library functions malloc or aligned_­alloc is unspecified.
  • Returns a pointer to the allocated storage if the attempt is successful.
    Otherwise, if the current new_­handler ([get.new.handler]) is a null pointer value, throws bad_­alloc.
  • Otherwise, the function calls the current new_­handler function ([new.handler]).
    If the called function returns, the loop repeats.
  • The loop terminates when an attempt to allocate the requested storage is successful or when a called new_­handler function does not return.
void* operator new(std::size_t size, const std::nothrow_t&) noexcept; void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Effects: Same as above, except that these are called by a placement version of a new-expression when a C++ program prefers a null pointer result as an error indication, instead of a bad_­alloc exception.
Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.
Required behavior: Return a non-null pointer to suitably aligned storage ([basic.stc.dynamic]), or else return a null pointer.
Each of these nothrow versions of operator new returns a pointer obtained as if acquired from the (possibly replaced) corresponding non-placement function.
This requirement is binding on any replacement versions of these functions.
Default behavior: Calls operator new(size), or operator new(size, alignment), respectively.
If the call returns normally, returns the result of that call.
Otherwise, returns a null pointer.
[Example
:
T* p1 = new T;                  // throws bad_­alloc if it fails
T* p2 = new(nothrow) T;         // returns nullptr if it fails
end example
]
void operator delete(void* ptr) noexcept; void operator delete(void* ptr, std::size_t size) noexcept; void operator delete(void* ptr, std::align_val_t alignment) noexcept; void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
Effects: The deallocation functions ([basic.stc.dynamic.deallocation]) called by a delete-expression to render the value of ptr invalid.
Replaceable: A C++ program may define functions with any of these function signatures, and thereby displace the default versions defined by the C++ standard library.
If a function without a size parameter is defined, the program should also define the corresponding function with a size parameter.
If a function with a size parameter is defined, the program shall also define the corresponding version without the size parameter.
[Note
:
The default behavior below may change in the future, which will require replacing both deallocation functions when replacing the allocation function.
end note
]
Requires: ptr shall be a null pointer or its value shall represent the address of a block of memory allocated by an earlier call to a (possibly replaced) operator new(std​::​size_­t) or operator new(std​::​size_­t, std​::​align_­val_­t) which has not been invalidated by an intervening call to operator delete.
Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.
Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter.
If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr.
If present, the size argument shall equal the size argument passed to the allocation function that returned ptr.
Required behavior: A call to an operator delete with a size parameter may be changed to a call to the corresponding operator delete without a size parameter, without affecting memory allocation.
[Note
:
A conforming implementation is for operator delete(void* ptr, std​::​size_­t size) to simply call operator delete(ptr).
end note
]
Default behavior: The functions that have a size parameter forward their other parameters to the corresponding function without a size parameter.
[Note
:
See the note in the above Replaceable: paragraph.
end note
]
Default behavior: If ptr is null, does nothing.
Otherwise, reclaims the storage allocated by the earlier call to operator new.
Remarks: It is unspecified under what conditions part or all of such reclaimed storage will be allocated by subsequent calls to operator new or any of aligned_­alloc, calloc, malloc, or realloc, declared in <cstdlib>.
void operator delete(void* ptr, const std::nothrow_t&) noexcept; void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Effects: The deallocation functions ([basic.stc.dynamic.deallocation]) called by the implementation to render the value of ptr invalid when the constructor invoked from a nothrow placement version of the new-expression throws an exception.
Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.
Requires: ptr shall be a null pointer or its value shall represent the address of a block of memory allocated by an earlier call to a (possibly replaced) operator new(std​::​size_­t) or operator new(std​::​size_­t, std​::​align_­val_­t) which has not been invalidated by an intervening call to operator delete.
Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.
Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter.
If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr.
Default behavior: Calls operator delete(ptr), or operator delete(ptr, alignment), respectively.

21.6.2.2 Array forms [new.delete.array]

void* operator new[](std::size_t size); void* operator new[](std::size_t size, std::align_val_t alignment);
Effects: The allocation functions ([basic.stc.dynamic.allocation]) called by the array form of a new-expression to allocate size bytes of storage.
The second form is called for a type with new-extended alignment, and allocates storage with the specified alignment.
The first form is called otherwise, and allocates storage suitably aligned to represent any array object of that size or smaller, provided the object's type does not have new-extended alignment.218
Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.
Required behavior: Same as for the corresponding single-object forms.
This requirement is binding on any replacement versions of these functions.
Default behavior: Returns operator new(size), or operator new(size, alignment), respectively.
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Effects: Same as above, except that these are called by a placement version of a new-expression when a C++ program prefers a null pointer result as an error indication, instead of a bad_­alloc exception.
Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.
Required behavior: Return a non-null pointer to suitably aligned storage ([basic.stc.dynamic]), or else return a null pointer.
Each of these nothrow versions of operator new[] returns a pointer obtained as if acquired from the (possibly replaced) corresponding non-placement function.
This requirement is binding on any replacement versions of these functions.
Default behavior: Calls operator new[](size), or operator new[](size, alignment), respectively.
If the call returns normally, returns the result of that call.
Otherwise, returns a null pointer.
void operator delete[](void* ptr) noexcept; void operator delete[](void* ptr, std::size_t size) noexcept; void operator delete[](void* ptr, std::align_val_t alignment) noexcept; void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
Effects: The deallocation functions ([basic.stc.dynamic.deallocation]) called by the array form of a delete-expression to render the value of ptr invalid.
Replaceable: A C++ program may define functions with any of these function signatures, and thereby displace the default versions defined by the C++ standard library.
If a function without a size parameter is defined, the program should also define the corresponding function with a size parameter.
If a function with a size parameter is defined, the program shall also define the corresponding version without the size parameter.
[Note
:
The default behavior below may change in the future, which will require replacing both deallocation functions when replacing the allocation function.
end note
]
Requires: ptr shall be a null pointer or its value shall represent the address of a block of memory allocated by an earlier call to a (possibly replaced) operator new[](std​::​size_­t) or operator new[](std​::​size_­t, std​::​align_­val_­t) which has not been invalidated by an intervening call to operator delete[].
Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.
Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter.
If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr.
If present, the size argument shall equal the size argument passed to the allocation function that returned ptr.
Required behavior: A call to an operator delete[] with a size parameter may be changed to a call to the corresponding operator delete[] without a size parameter, without affecting memory allocation.
[Note
:
A conforming implementation is for operator delete[](void* ptr, std​::​size_­t size) to simply call operator delete[](ptr).
end note
]
Default behavior: The functions that have a size parameter forward their other parameters to the corresponding function without a size parameter.
The functions that do not have a size parameter forward their parameters to the corresponding operator delete (single-object) function.
void operator delete[](void* ptr, const std::nothrow_t&) noexcept; void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
Effects: The deallocation functions ([basic.stc.dynamic.deallocation]) called by the implementation to render the value of ptr invalid when the constructor invoked from a nothrow placement version of the array new-expression throws an exception.
Replaceable: A C++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C++ standard library.
Requires: ptr shall be a null pointer or its value shall represent the address of a block of memory allocated by an earlier call to a (possibly replaced) operator new[](std​::​size_­t) or operator new[](std​::​size_­t, std​::​align_­val_­t) which has not been invalidated by an intervening call to operator delete[].
Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.
Requires: If the alignment parameter is not present, ptr shall have been returned by an allocation function without an alignment parameter.
If present, the alignment argument shall equal the alignment argument passed to the allocation function that returned ptr.
Default behavior: Calls operator delete[](ptr), or operator delete[](ptr, alignment), respectively.
It is not the direct responsibility of operator new[] or operator delete[] to note the repetition count or element size of the array.
Those operations are performed elsewhere in the array new and delete expressions.
The array new expression, may, however, increase the size argument to operator new[] to obtain space to store supplemental information.

21.6.2.3 Non-allocating forms [new.delete.placement]

These functions are reserved; a C++ program may not define functions that displace the versions in the C++ standard library ([constraints]).
The provisions of [basic.stc.dynamic] do not apply to these reserved placement forms of operator new and operator delete.
void* operator new(std::size_t size, void* ptr) noexcept;
Returns: ptr.
Remarks: Intentionally performs no other action.
[Example
:
This can be useful for constructing an object at a known address:
void* place = operator new(sizeof(Something));
Something* p = new (place) Something();
end example
]
void* operator new[](std::size_t size, void* ptr) noexcept;
Returns: ptr.
Remarks: Intentionally performs no other action.
void operator delete(void* ptr, void*) noexcept;
Effects: Intentionally performs no action.
Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.
Remarks: Default function called when any part of the initialization in a placement new-expression that invokes the library's non-array placement operator new terminates by throwing an exception ([expr.new]).
void operator delete[](void* ptr, void*) noexcept;
Effects: Intentionally performs no action.
Requires: If an implementation has strict pointer safety ([basic.stc.dynamic.safety]) then ptr shall be a safely-derived pointer.
Remarks: Default function called when any part of the initialization in a placement new-expression that invokes the library's array placement operator new terminates by throwing an exception ([expr.new]).

21.6.2.4 Data races [new.delete.dataraces]

For purposes of determining the existence of data races, the library versions of operator new, user replacement versions of global operator new, the C standard library functions aligned_­alloc, calloc, and malloc, the library versions of operator delete, user replacement versions of operator delete, the C standard library function free, and the C standard library function realloc shall not introduce a data race ([res.on.data.races]).
Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before ([intro.multithread]) the next allocation (if any) in this order.

21.6.3 Storage allocation errors [alloc.errors]

21.6.3.1 Class bad_­alloc [bad.alloc]

namespace std {
  class bad_alloc : public exception {
  public:
    bad_alloc() noexcept;
    bad_alloc(const bad_alloc&) noexcept;
    bad_alloc& operator=(const bad_alloc&) noexcept;
    const char* what() const noexcept override;
  };
}
The class bad_­alloc defines the type of objects thrown as exceptions by the implementation to report a failure to allocate storage.
bad_alloc() noexcept;
Effects: Constructs an object of class bad_­alloc.
bad_alloc(const bad_alloc&) noexcept; bad_alloc& operator=(const bad_alloc&) noexcept;
Effects: Copies an object of class bad_­alloc.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).

21.6.3.2 Class bad_­array_­new_­length [new.badlength]

namespace std {
  class bad_array_new_length : public bad_alloc {
  public:
    bad_array_new_length() noexcept;
    const char* what() const noexcept override;
  };
}
The class bad_­array_­new_­length defines the type of objects thrown as exceptions by the implementation to report an attempt to allocate an array of size less than zero or greater than an implementation-defined limit ([expr.new]).
bad_array_new_length() noexcept;
Effects: constructs an object of class bad_­array_­new_­length.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).

21.6.3.3 Type new_­handler [new.handler]

using new_handler = void (*)();
The type of a handler function to be called by operator new() or operator new[]() ([new.delete]) when they cannot satisfy a request for additional storage.
Required behavior: A new_­handler shall perform one of the following:
  • make more storage available for allocation and then return;
  • throw an exception of type bad_­alloc or a class derived from bad_­alloc;
  • terminate execution of the program without returning to the caller.

21.6.3.4 set_­new_­handler [set.new.handler]

new_handler set_new_handler(new_handler new_p) noexcept;
Effects: Establishes the function designated by new_­p as the current new_­handler.
Returns: The previous new_­handler.
Remarks: The initial new_­handler is a null pointer.

21.6.3.5 get_­new_­handler [get.new.handler]

new_handler get_new_handler() noexcept;
Returns: The current new_­handler.
[Note
:
This may be a null pointer value.
end note
]

21.6.4 Pointer optimization barrier [ptr.launder]

template <class T> constexpr T* launder(T* p) noexcept;
Requires: p represents the address A of a byte in memory.
An object X that is within its lifetime ([basic.life]) and whose type is similar ([conv.qual]) to T is located at the address A.
All bytes of storage that would be reachable through the result are reachable through p (see below).
Returns: A value of type T * that points to X.
Remarks: An invocation of this function may be used in a core constant expression whenever the value of its argument may be used in a core constant expression.
A byte of storage is reachable through a pointer value that points to an object Y if it is within the storage occupied by Y, an object that is pointer-interconvertible with Y, or the immediately-enclosing array object if Y is an array element.
The program is ill-formed if T is a function type or cv void.
[Note
:
If a new object is created in storage occupied by an existing object of the same type, a pointer to the original object can be used to refer to the new object unless the type contains const or reference members; in the latter cases, this function can be used to obtain a usable pointer to the new object.
end note
]
[Example
:
struct X { const int n; };
X *p = new X{3};
const int a = p->n;
new (p) X{5};                       // p does not point to new object ([basic.life]) because X​::​n is const
const int b = p->n;                 // undefined behavior
const int c = std::launder(p)->n;   // OK
end example
]

21.6.5 Hardware interference size [hardware.interference]

inline constexpr size_t hardware_destructive_interference_size = implementation-defined;
This number is the minimum recommended offset between two concurrently-accessed objects to avoid additional performance degradation due to contention introduced by the implementation.
It shall be at least alignof(max_­align_­t).
[Example
:
struct keep_apart {
  alignas(hardware_destructive_interference_size) atomic<int> cat;
  alignas(hardware_destructive_interference_size) atomic<int> dog;
};
end example
]
inline constexpr size_t hardware_constructive_interference_size = implementation-defined;
This number is the maximum recommended size of contiguous memory occupied by two objects accessed with temporal locality by concurrent threads.
It shall be at least alignof(max_­align_­t).
[Example
:
struct together {
  atomic<int> dog;
  int puppy;
};
struct kennel {
  // Other data members...
  alignas(sizeof(together)) together pack;
  // Other data members...
};
static_assert(sizeof(together) <= hardware_constructive_interference_size);
end example
]

21.7 Type identification [support.rtti]

The header <typeinfo> defines a type associated with type information generated by the implementation.
It also defines two types for reporting dynamic type identification errors.

21.7.1 Header <typeinfo> synopsis [typeinfo.syn]

namespace std {
  class type_info;
  class bad_cast;
  class bad_typeid;
}
See also: [expr.dynamic.cast], [expr.typeid].

21.7.2 Class type_­info [type.info]

namespace std {
  class type_info {
  public:
    virtual ~type_info();
    bool operator==(const type_info& rhs) const noexcept;
    bool operator!=(const type_info& rhs) const noexcept;
    bool before(const type_info& rhs) const noexcept;
    size_t hash_code() const noexcept;
    const char* name() const noexcept;

    type_info(const type_info& rhs) = delete;                   // cannot be copied
    type_info& operator=(const type_info& rhs) = delete;        // cannot be copied
  };
}
The class type_­info describes type information generated by the implementation.
Objects of this class effectively store a pointer to a name for the type, and an encoded value suitable for comparing two types for equality or collating order.
The names, encoding rule, and collating sequence for types are all unspecified and may differ between programs.
bool operator==(const type_info& rhs) const noexcept;
Effects: Compares the current object with rhs.
Returns: true if the two values describe the same type.
bool operator!=(const type_info& rhs) const noexcept;
Returns: !(*this == rhs).
bool before(const type_info& rhs) const noexcept;
Effects: Compares the current object with rhs.
Returns: true if *this precedes rhs in the implementation's collation order.
size_t hash_code() const noexcept;
Returns: An unspecified value, except that within a single execution of the program, it shall return the same value for any two type_­info objects which compare equal.
Remarks: An implementation should return different values for two type_­info objects which do not compare equal.
const char* name() const noexcept;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt])

21.7.3 Class bad_­cast [bad.cast]

namespace std {
  class bad_cast : public exception {
  public:
    bad_cast() noexcept;
    bad_cast(const bad_cast&) noexcept;
    bad_cast& operator=(const bad_cast&) noexcept;
    const char* what() const noexcept override;
  };
}
The class bad_­cast defines the type of objects thrown as exceptions by the implementation to report the execution of an invalid dynamic_­cast expression ([expr.dynamic.cast]).
bad_cast() noexcept;
Effects: Constructs an object of class bad_­cast.
bad_cast(const bad_cast&) noexcept; bad_cast& operator=(const bad_cast&) noexcept;
Effects: Copies an object of class bad_­cast.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt])

21.7.4 Class bad_­typeid [bad.typeid]

namespace std {
  class bad_typeid : public exception {
  public:
    bad_typeid() noexcept;
    bad_typeid(const bad_typeid&) noexcept;
    bad_typeid& operator=(const bad_typeid&) noexcept;
    const char* what() const noexcept override;
  };
}
The class bad_­typeid defines the type of objects thrown as exceptions by the implementation to report a null pointer in a typeid expression ([expr.typeid]).
bad_typeid() noexcept;
Effects: Constructs an object of class bad_­typeid.
bad_typeid(const bad_typeid&) noexcept; bad_typeid& operator=(const bad_typeid&) noexcept;
Effects: Copies an object of class bad_­typeid.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt])

21.8 Exception handling [support.exception]

The header <exception> defines several types and functions related to the handling of exceptions in a C++ program.

21.8.1 Header <exception> synopsis [exception.syn]

namespace std {
  class exception;
  class bad_exception;
  class nested_exception;

  using terminate_handler = void (*)();
  terminate_handler get_terminate() noexcept;
  terminate_handler set_terminate(terminate_handler f) noexcept;
  [[noreturn]] void terminate() noexcept;

  int uncaught_exceptions() noexcept;

  using exception_ptr = unspecified;

  exception_ptr current_exception() noexcept;
  [[noreturn]] void rethrow_exception(exception_ptr p);
  template<class E> exception_ptr make_exception_ptr(E e) noexcept;

  template <class T> [[noreturn]] void throw_with_nested(T&& t);
  template <class E> void rethrow_if_nested(const E& e);
}
See also: [except.special].

21.8.2 Class exception [exception]

namespace std {
  class exception {
  public:
    exception() noexcept;
    exception(const exception&) noexcept;
    exception& operator=(const exception&) noexcept;
    virtual ~exception();
    virtual const char* what() const noexcept;
  };
}
The class exception defines the base class for the types of objects thrown as exceptions by C++ standard library components, and certain expressions, to report errors detected during program execution.
Each standard library class T that derives from class exception shall have a publicly accessible copy constructor and a publicly accessible copy assignment operator that do not exit with an exception.
These member functions shall meet the following postcondition: If two objects lhs and rhs both have dynamic type T and lhs is a copy of rhs, then strcmp(lhs.what(), rhs.what()) shall equal 0.
exception() noexcept;
Effects: Constructs an object of class exception.
exception(const exception& rhs) noexcept; exception& operator=(const exception& rhs) noexcept;
Effects: Copies an exception object.
Postconditions: If *this and rhs both have dynamic type exception then the value of the expression strcmp(what(), rhs.what()) shall equal 0.
virtual ~exception();
Effects: Destroys an object of class exception.
virtual const char* what() const noexcept;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).
The return value remains valid until the exception object from which it is obtained is destroyed or a non-const member function of the exception object is called.

21.8.3 Class bad_­exception [bad.exception]

namespace std {
  class bad_exception : public exception {
  public:
    bad_exception() noexcept;
    bad_exception(const bad_exception&) noexcept;
    bad_exception& operator=(const bad_exception&) noexcept;
    const char* what() const noexcept override;
  };
}
The class bad_­exception defines the type of the object referenced by the exception_­ptr returned from a call to current_­exception ([propagation]) when the currently active exception object fails to copy.
bad_exception() noexcept;
Effects: Constructs an object of class bad_­exception.
bad_exception(const bad_exception&) noexcept; bad_exception& operator=(const bad_exception&) noexcept;
Effects: Copies an object of class bad_­exception.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).

21.8.4 Abnormal termination [exception.terminate]

21.8.4.1 Type terminate_­handler [terminate.handler]

using terminate_handler = void (*)();
The type of a handler function to be called by std​::​terminate() when terminating exception processing.
Required behavior: A terminate_­handler shall terminate execution of the program without returning to the caller.
Default behavior: The implementation's default terminate_­handler calls abort().

21.8.4.2 set_­terminate [set.terminate]

terminate_handler set_terminate(terminate_handler f) noexcept;
Effects: Establishes the function designated by f as the current handler function for terminating exception processing.
Remarks: It is unspecified whether a null pointer value designates the default terminate_­handler.
Returns: The previous terminate_­handler.

21.8.4.3 get_­terminate [get.terminate]

terminate_handler get_terminate() noexcept;
Returns: The current terminate_­handler.
[Note
:
This may be a null pointer value.
end note
]

21.8.4.4 terminate [terminate]

[[noreturn]] void terminate() noexcept;
Remarks: Called by the implementation when exception handling must be abandoned for any of several reasons ([except.terminate]).
May also be called directly by the program.
Effects: Calls a terminate_­handler function.
It is unspecified which terminate_­handler function will be called if an exception is active during a call to set_­terminate.
Otherwise calls the current terminate_­handler function.
[Note
:
A default terminate_­handler is always considered a callable handler in this context.
end note
]

21.8.5 uncaught_­exceptions [uncaught.exceptions]

int uncaught_exceptions() noexcept;
Returns: The number of uncaught exceptions ([except.uncaught]).
Remarks: When uncaught_­exceptions() > 0, throwing an exception can result in a call of
std​::​terminate() ([except.terminate]).

21.8.6 Exception propagation [propagation]

using exception_ptr = unspecified;
The type exception_­ptr can be used to refer to an exception object.
exception_­ptr shall satisfy the requirements of NullablePointer ([nullablepointer.requirements]).
Two non-null values of type exception_­ptr are equivalent and compare equal if and only if they refer to the same exception.
The default constructor of exception_­ptr produces the null value of the type.
exception_­ptr shall not be implicitly convertible to any arithmetic, enumeration, or pointer type.
[Note
:
An implementation might use a reference-counted smart pointer as exception_­ptr.
end note
]
For purposes of determining the presence of a data race, operations on exception_­ptr objects shall access and modify only the exception_­ptr objects themselves and not the exceptions they refer to.
Use of rethrow_­exception on exception_­ptr objects that refer to the same exception object shall not introduce a data race.
[Note
:
If rethrow_­exception rethrows the same exception object (rather than a copy), concurrent access to that rethrown exception object may introduce a data race.
Changes in the number of exception_­ptr objects that refer to a particular exception do not introduce a data race.
end note
]
exception_ptr current_exception() noexcept;
Returns: An exception_­ptr object that refers to the currently handled exception ([except.handle]) or a copy of the currently handled exception, or a null exception_­ptr object if no exception is being handled.
The referenced object shall remain valid at least as long as there is an exception_­ptr object that refers to it.
If the function needs to allocate memory and the attempt fails, it returns an exception_­ptr object that refers to an instance of bad_­alloc.
It is unspecified whether the return values of two successive calls to current_­exception refer to the same exception object.
[Note
:
That is, it is unspecified whether current_­exception creates a new copy each time it is called.
end note
]
If the attempt to copy the current exception object throws an exception, the function returns an exception_­ptr object that refers to the thrown exception or, if this is not possible, to an instance of bad_­exception.
[Note
:
The copy constructor of the thrown exception may also fail, so the implementation is allowed to substitute a bad_­exception object to avoid infinite recursion.
end note
]
[[noreturn]] void rethrow_exception(exception_ptr p);
Requires: p shall not be a null pointer.
Throws: The exception object to which p refers.
template<class E> exception_ptr make_exception_ptr(E e) noexcept;
Effects: Creates an exception_­ptr object that refers to a copy of e, as if:
try {
  throw e;
} catch(...) {
  return current_exception();
}
[Note
:
This function is provided for convenience and efficiency reasons.
end note
]

21.8.7 nested_­exception [except.nested]

namespace std {
  class nested_exception {
  public:
    nested_exception() noexcept;
    nested_exception(const nested_exception&) noexcept = default;
    nested_exception& operator=(const nested_exception&) noexcept = default;
    virtual ~nested_exception() = default;

    // access functions
    [[noreturn]] void rethrow_nested() const;
    exception_ptr nested_ptr() const noexcept;
  };

  template<class T> [[noreturn]] void throw_with_nested(T&& t);
  template <class E> void rethrow_if_nested(const E& e);
}
The class nested_­exception is designed for use as a mixin through multiple inheritance.
It captures the currently handled exception and stores it for later use.
[Note
:
nested_­exception has a virtual destructor to make it a polymorphic class.
Its presence can be tested for with dynamic_­cast.
end note
]
nested_exception() noexcept;
Effects: The constructor calls current_­exception() and stores the returned value.
[[noreturn]] void rethrow_nested() const;
Effects: If nested_­ptr() returns a null pointer, the function calls std​::​terminate().
Otherwise, it throws the stored exception captured by *this.
exception_ptr nested_ptr() const noexcept;
Returns: The stored exception captured by this nested_­exception object.
template <class T> [[noreturn]] void throw_with_nested(T&& t);
Let U be decay_­t<T>.
Requires: U shall be CopyConstructible.
Throws: If is_­class_­v<U> && !is_­final_­v<U> && !is_­base_­of_­v<nested_­exception, U> is true, an exception of unspecified type that is publicly derived from both U and nested_­exception and constructed from std​::​forward<T>(t), otherwise std​::​forward<T>(t).
template <class E> void rethrow_if_nested(const E& e);
Effects: If E is not a polymorphic class type, or if nested_­exception is an inaccessible or ambiguous base class of E, there is no effect.
Otherwise, performs:
if (auto p = dynamic_cast<const nested_exception*>(addressof(e)))
  p->rethrow_nested();

21.9 Initializer lists [support.initlist]

The header <initializer_­list> defines a class template and several support functions related to list-initialization (see [dcl.init.list]).
All functions specified in this subclause are signal-safe ([csignal.syn]).

21.9.1 Header <initializer_­list> synopsis [initializer_list.syn]

namespace std {
  template<class E> class initializer_list {
  public:
    using value_type      = E;
    using reference       = const E&;
    using const_reference = const E&;
    using size_type       = size_t;

    using iterator        = const E*;
    using const_iterator  = const E*;

    constexpr initializer_list() noexcept;

    constexpr size_t size() const noexcept;     // number of elements
    constexpr const E* begin() const noexcept;  // first element
    constexpr const E* end() const noexcept;    // one past the last element
  };

  // [support.initlist.range], initializer list range access
  template<class E> constexpr const E* begin(initializer_list<E> il) noexcept;
  template<class E> constexpr const E* end(initializer_list<E> il) noexcept;
}
An object of type initializer_­list<E> provides access to an array of objects of type const E.
[Note
:
A pair of pointers or a pointer plus a length would be obvious representations for initializer_­list.
initializer_­list is used to implement initializer lists as specified in [dcl.init.list].
Copying an initializer list does not copy the underlying elements.
end note
]
If an explicit specialization or partial specialization of initializer_­list is declared, the program is ill-formed.

21.9.2 Initializer list constructors [support.initlist.cons]

constexpr initializer_list() noexcept;
Effects: Constructs an empty initializer_­list object.
Postconditions: size() == 0.

21.9.3 Initializer list access [support.initlist.access]

constexpr const E* begin() const noexcept;
Returns: A pointer to the beginning of the array.
If size() == 0 the values of begin() and end() are unspecified but they shall be identical.
constexpr const E* end() const noexcept;
Returns: begin() + size().
constexpr size_t size() const noexcept;
Returns: The number of elements in the array.
Complexity: Constant time.

21.9.4 Initializer list range access [support.initlist.range]

template<class E> constexpr const E* begin(initializer_list<E> il) noexcept;
Returns: il.begin().
template<class E> constexpr const E* end(initializer_list<E> il) noexcept;
Returns: il.end().

21.10 Other runtime support [support.runtime]

Headers <csetjmp> (nonlocal jumps), <csignal> (signal handling), <cstdarg> (variable arguments), and <cstdlib> (runtime environment getenv, system), provide further compatibility with C code.
Calls to the function getenv ([cstdlib.syn]) shall not introduce a data race ([res.on.data.races]) provided that nothing modifies the environment.
[Note
:
Calls to the POSIX functions setenv and putenv modify the environment.
end note
]
A call to the setlocale function ([c.locales]) may introduce a data race with other calls to the setlocale function or with calls to functions that are affected by the current C locale.
The implementation shall behave as if no library function other than locale​::​global calls the setlocale function.

21.10.1 Header <cstdarg> synopsis [cstdarg.syn]

namespace std {
  using va_list = see below;
}

#define va_arg(V, P) see below
#define va_copy(VDST, VSRC) see below
#define va_end(V) see below
#define va_start(V, P) see below
The contents of the header <cstdarg> are the same as the C standard library header <stdarg.h>, with the following changes: The restrictions that ISO C places on the second parameter to the va_­start macro in header <stdarg.h> are different in this International Standard.
The parameter parmN is the rightmost parameter in the variable parameter list of the function definition (the one just before the ...).219
If the parameter parmN is a pack expansion ([temp.variadic]) or an entity resulting from a lambda capture ([expr.prim.lambda]), the program is ill-formed, no diagnostic required.
If the parameter parmN is of a reference type, or of a type that is not compatible with the type that results when passing an argument for which there is no parameter, the behavior is undefined.
See also: ISO C 7.
16.
1.
1.
Note that va_­start is required to work as specified even if unary operator& is overloaded for the type of parmN.

21.10.2 Header <csetjmp> synopsis [csetjmp.syn]

namespace std {
  using jmp_buf = see below;
  [[noreturn]] void longjmp(jmp_buf env, int val);
}

#define setjmp(env) see below
The contents of the header <csetjmp> are the same as the C standard library header <setjmp.h>.
The function signature longjmp(jmp_­buf jbuf, int val) has more restricted behavior in this International Standard.
A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any automatic objects.
See also: ISO C 7.
13.

21.10.3 Header <csignal> synopsis [csignal.syn]

namespace std {
  using sig_atomic_t = see below;

  // [support.signal], signal handlers
  extern "C" using signal-handler = void(int);  // exposition only
  signal-handler* signal(int sig, signal-handler* func);

  int raise(int sig);
}

#define SIG_DFL see below
#define SIG_ERR see below
#define SIG_IGN see below
#define SIGABRT see below
#define SIGFPE see below
#define SIGILL see below
#define SIGINT see below
#define SIGSEGV see below
#define SIGTERM see below
The contents of the header <csignal> are the same as the C standard library header <signal.h>.

21.10.4 Signal handlers [support.signal]

A call to the function signal synchronizes with any resulting invocation of the signal handler so installed.
A plain lock-free atomic operation is an invocation of a function f from Clause [atomics], such that:
  • f is the function atomic_­is_­lock_­free(), or
  • f is the member function is_­lock_­free(), or
  • f is a non-static member function invoked on an object A, such that A.is_­lock_­free() yields true, or
  • f is a non-member function, and for every pointer-to-atomic argument A passed to f, atomic_­is_­lock_­free(A) yields true.
An evaluation is signal-safe unless it includes one of the following:
  • a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe.
    [Note
    :
    This implicitly excludes the use of new and delete expressions that rely on a library-provided memory allocator.
    end note
    ]
  • an access to an object with thread storage duration;
  • a dynamic_­cast expression;
  • throwing of an exception;
  • control entering a try-block or function-try-block;
  • initialization of a variable with static storage duration requiring dynamic initialization ([basic.start.dynamic], [stmt.dcl])220; or
  • waiting for the completion of the initialization of a variable with static storage duration ([stmt.dcl]).
A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.
The function signal is signal-safe if it is invoked with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler.
See also: ISO C 7.
14.
Such initialization might occur because it is the first odr-use ([basic.def.odr]) of that variable.

22 Diagnostics library [diagnostics]

22.1 General [diagnostics.general]

This Clause describes components that C++ programs may use to detect and report error conditions.
The following subclauses describe components for reporting several kinds of exceptional conditions, documenting program assertions, and a global variable for error number codes, as summarized in Table 33.
Table 33 — Diagnostics library summary
Subclause
Header(s)
Exception classes
<stdexcept>
Assertions
<cassert>
Error numbers
<cerrno>
System error support
<system_­error>

22.2 Exception classes [std.exceptions]

The C++ standard library provides classes to be used to report certain errors ([res.on.exception.handling]) in C++ programs.
In the error model reflected in these classes, errors are divided into two broad categories: logic errors and runtime errors.
The distinguishing characteristic of logic errors is that they are due to errors in the internal logic of the program.
In theory, they are preventable.
By contrast, runtime errors are due to events beyond the scope of the program.
They cannot be easily predicted in advance.
The header <stdexcept> defines several types of predefined exceptions for reporting errors in a C++ program.
These exceptions are related by inheritance.

22.2.1 Header <stdexcept> synopsis [stdexcept.syn]

namespace std {
  class logic_error;
    class domain_error;
    class invalid_argument;
    class length_error;
    class out_of_range;
  class runtime_error;
    class range_error;
    class overflow_error;
    class underflow_error;
}

22.2.2 Class logic_­error [logic.error]

namespace std {
  class logic_error : public exception {
  public:
    explicit logic_error(const string& what_arg);
    explicit logic_error(const char* what_arg);
  };
}
The class logic_­error defines the type of objects thrown as exceptions to report errors presumably detectable before the program executes, such as violations of logical preconditions or class invariants.
logic_error(const string& what_arg);
Effects: Constructs an object of class logic_­error.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
logic_error(const char* what_arg);
Effects: Constructs an object of class logic_­error.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.3 Class domain_­error [domain.error]

namespace std {
  class domain_error : public logic_error {
  public:
    explicit domain_error(const string& what_arg);
    explicit domain_error(const char* what_arg);
  };
}
The class domain_­error defines the type of objects thrown as exceptions by the implementation to report domain errors.
domain_error(const string& what_arg);
Effects: Constructs an object of class domain_­error.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
domain_error(const char* what_arg);
Effects: Constructs an object of class domain_­error.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.4 Class invalid_­argument [invalid.argument]

namespace std {
  class invalid_argument : public logic_error {
  public:
    explicit invalid_argument(const string& what_arg);
    explicit invalid_argument(const char* what_arg);
  };
}
The class invalid_­argument defines the type of objects thrown as exceptions to report an invalid argument.
invalid_argument(const string& what_arg);
Effects: Constructs an object of class invalid_­argument.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
invalid_argument(const char* what_arg);
Effects: Constructs an object of class invalid_­argument.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.5 Class length_­error [length.error]

namespace std {
  class length_error : public logic_error {
  public:
    explicit length_error(const string& what_arg);
    explicit length_error(const char* what_arg);
  };
}
The class length_­error defines the type of objects thrown as exceptions to report an attempt to produce an object whose length exceeds its maximum allowable size.
length_error(const string& what_arg);
Effects: Constructs an object of class length_­error.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
length_error(const char* what_arg);
Effects: Constructs an object of class length_­error.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.6 Class out_­of_­range [out.of.range]

namespace std {
  class out_of_range : public logic_error {
  public:
    explicit out_of_range(const string& what_arg);
    explicit out_of_range(const char* what_arg);
  };
}
The class out_­of_­range defines the type of objects thrown as exceptions to report an argument value not in its expected range.
out_of_range(const string& what_arg);
Effects: Constructs an object of class out_­of_­range.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
out_of_range(const char* what_arg);
Effects: Constructs an object of class out_­of_­range.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.7 Class runtime_­error [runtime.error]

namespace std {
  class runtime_error : public exception {
  public:
    explicit runtime_error(const string& what_arg);
    explicit runtime_error(const char* what_arg);
  };
}
The class runtime_­error defines the type of objects thrown as exceptions to report errors presumably detectable only when the program executes.
runtime_error(const string& what_arg);
Effects: Constructs an object of class runtime_­error.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
runtime_error(const char* what_arg);
Effects: Constructs an object of class runtime_­error.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.8 Class range_­error [range.error]

namespace std {
  class range_error : public runtime_error {
  public:
    explicit range_error(const string& what_arg);
    explicit range_error(const char* what_arg);
  };
}
The class range_­error defines the type of objects thrown as exceptions to report range errors in internal computations.
range_error(const string& what_arg);
Effects: Constructs an object of class range_­error.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
range_error(const char* what_arg);
Effects: Constructs an object of class range_­error.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.9 Class overflow_­error [overflow.error]

namespace std {
  class overflow_error : public runtime_error {
  public:
    explicit overflow_error(const string& what_arg);
    explicit overflow_error(const char* what_arg);
  };
}
The class overflow_­error defines the type of objects thrown as exceptions to report an arithmetic overflow error.
overflow_error(const string& what_arg);
Effects: Constructs an object of class overflow_­error.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
overflow_error(const char* what_arg);
Effects: Constructs an object of class overflow_­error.
Postconditions: strcmp(what(), what_­arg) == 0.

22.2.10 Class underflow_­error [underflow.error]

namespace std {
  class underflow_error : public runtime_error {
  public:
    explicit underflow_error(const string& what_arg);
    explicit underflow_error(const char* what_arg);
  };
}
The class underflow_­error defines the type of objects thrown as exceptions to report an arithmetic underflow error.
underflow_error(const string& what_arg);
Effects: Constructs an object of class underflow_­error.
Postconditions: strcmp(what(), what_­arg.c_­str()) == 0.
underflow_error(const char* what_arg);
Effects: Constructs an object of class underflow_­error.
Postconditions: strcmp(what(), what_­arg) == 0.

22.3 Assertions [assertions]

The header <cassert> provides a macro for documenting C++ program assertions and a mechanism for disabling the assertion checks.

22.3.1 Header <cassert> synopsis [cassert.syn]

#define assert(E) see below
The contents are the same as the C standard library header <assert.h>, except that a macro named static_­assert is not defined.
See also: ISO C 7.
2.

22.3.2 The assert macro [assertions.assert]

An expression assert(E) is a constant subexpression ([defns.const.subexpr]), if
  • NDEBUG is defined at the point where assert is last defined or redefined, or
  • E contextually converted to bool (Clause [conv]) is a constant subexpression that evaluates to the value true.

22.4 Error numbers [errno]

The contents of the header <cerrno> are the same as the POSIX header <errno.h>, except that errno shall be defined as a macro.
[Note
:
The intent is to remain in close alignment with the POSIX standard.
end note
]
A separate errno value shall be provided for each thread.

22.4.1 Header <cerrno> synopsis [cerrno.syn]

#define errno see below

#define E2BIG see below
#define EACCES see below
#define EADDRINUSE see below
#define EADDRNOTAVAIL see below
#define EAFNOSUPPORT see below
#define EAGAIN see below
#define EALREADY see below
#define EBADF see below
#define EBADMSG see below
#define EBUSY see below
#define ECANCELED see below
#define ECHILD see below
#define ECONNABORTED see below
#define ECONNREFUSED see below
#define ECONNRESET see below
#define EDEADLK see below
#define EDESTADDRREQ see below
#define EDOM see below
#define EEXIST see below
#define EFAULT see below
#define EFBIG see below
#define EHOSTUNREACH see below
#define EIDRM see below
#define EILSEQ see below
#define EINPROGRESS see below
#define EINTR see below
#define EINVAL see below
#define EIO see below
#define EISCONN see below
#define EISDIR see below
#define ELOOP see below
#define EMFILE see below
#define EMLINK see below
#define EMSGSIZE see below
#define ENAMETOOLONG see below
#define ENETDOWN see below
#define ENETRESET see below
#define ENETUNREACH see below
#define ENFILE see below
#define ENOBUFS see below
#define ENODATA see below
#define ENODEV see below
#define ENOENT see below
#define ENOEXEC see below
#define ENOLCK see below
#define ENOLINK see below
#define ENOMEM see below
#define ENOMSG see below
#define ENOPROTOOPT see below
#define ENOSPC see below
#define ENOSR see below
#define ENOSTR see below
#define ENOSYS see below
#define ENOTCONN see below
#define ENOTDIR see below
#define ENOTEMPTY see below
#define ENOTRECOVERABLE see below
#define ENOTSOCK see below
#define ENOTSUP see below
#define ENOTTY see below
#define ENXIO see below
#define EOPNOTSUPP see below
#define EOVERFLOW see below
#define EOWNERDEAD see below
#define EPERM see below
#define EPIPE see below
#define EPROTO see below
#define EPROTONOSUPPORT see below
#define EPROTOTYPE see below
#define ERANGE see below
#define EROFS see below
#define ESPIPE see below
#define ESRCH see below
#define ETIME see below
#define ETIMEDOUT see below
#define ETXTBSY see below
#define EWOULDBLOCK see below
#define EXDEV see below
The meaning of the macros in this header is defined by the POSIX standard.
See also: ISO C 7.
5.

22.5 System error support [syserr]

This subclause describes components that the standard library and C++ programs may use to report error conditions originating from the operating system or other low-level application program interfaces.
Components described in this subclause shall not change the value of errno ([errno]).
Implementations should leave the error states provided by other libraries unchanged.

22.5.1 Header <system_­error> synopsis [system_error.syn]

namespace std {
  class error_category;
  const error_category& generic_category() noexcept;
  const error_category& system_category() noexcept;

  class error_code;
  class error_condition;
  class system_error;

  template <class T>
  struct is_error_code_enum : public false_type {};

  template <class T>
  struct is_error_condition_enum : public false_type {};

  enum class errc {
    address_family_not_supported,       // EAFNOSUPPORT
    address_in_use,                     // EADDRINUSE
    address_not_available,              // EADDRNOTAVAIL
    already_connected,                  // EISCONN
    argument_list_too_long,             // E2BIG
    argument_out_of_domain,             // EDOM
    bad_address,                        // EFAULT
    bad_file_descriptor,                // EBADF
    bad_message,                        // EBADMSG
    broken_pipe,                        // EPIPE
    connection_aborted,                 // ECONNABORTED
    connection_already_in_progress,     // EALREADY
    connection_refused,                 // ECONNREFUSED
    connection_reset,                   // ECONNRESET
    cross_device_link,                  // EXDEV
    destination_address_required,       // EDESTADDRREQ
    device_or_resource_busy,            // EBUSY
    directory_not_empty,                // ENOTEMPTY
    executable_format_error,            // ENOEXEC
    file_exists,                        // EEXIST
    file_too_large,                     // EFBIG
    filename_too_long,                  // ENAMETOOLONG
    function_not_supported,             // ENOSYS
    host_unreachable,                   // EHOSTUNREACH
    identifier_removed,                 // EIDRM
    illegal_byte_sequence,              // EILSEQ
    inappropriate_io_control_operation, // ENOTTY
    interrupted,                        // EINTR
    invalid_argument,                   // EINVAL
    invalid_seek,                       // ESPIPE
    io_error,                           // EIO
    is_a_directory,                     // EISDIR
    message_size,                       // EMSGSIZE
    network_down,                       // ENETDOWN
    network_reset,                      // ENETRESET
    network_unreachable,                // ENETUNREACH
    no_buffer_space,                    // ENOBUFS
    no_child_process,                   // ECHILD
    no_link,                            // ENOLINK
    no_lock_available,                  // ENOLCK
    no_message_available,               // ENODATA
    no_message,                         // ENOMSG
    no_protocol_option,                 // ENOPROTOOPT
    no_space_on_device,                 // ENOSPC
    no_stream_resources,                // ENOSR
    no_such_device_or_address,          // ENXIO
    no_such_device,                     // ENODEV
    no_such_file_or_directory,          // ENOENT
    no_such_process,                    // ESRCH
    not_a_directory,                    // ENOTDIR
    not_a_socket,                       // ENOTSOCK
    not_a_stream,                       // ENOSTR
    not_connected,                      // ENOTCONN
    not_enough_memory,                  // ENOMEM
    not_supported,                      // ENOTSUP
    operation_canceled,                 // ECANCELED
    operation_in_progress,              // EINPROGRESS
    operation_not_permitted,            // EPERM
    operation_not_supported,            // EOPNOTSUPP
    operation_would_block,              // EWOULDBLOCK
    owner_dead,                         // EOWNERDEAD
    permission_denied,                  // EACCES
    protocol_error,                     // EPROTO
    protocol_not_supported,             // EPROTONOSUPPORT
    read_only_file_system,              // EROFS
    resource_deadlock_would_occur,      // EDEADLK
    resource_unavailable_try_again,     // EAGAIN
    result_out_of_range,                // ERANGE
    state_not_recoverable,              // ENOTRECOVERABLE
    stream_timeout,                     // ETIME
    text_file_busy,                     // ETXTBSY
    timed_out,                          // ETIMEDOUT
    too_many_files_open_in_system,      // ENFILE
    too_many_files_open,                // EMFILE
    too_many_links,                     // EMLINK
    too_many_symbolic_link_levels,      // ELOOP
    value_too_large,                    // EOVERFLOW
    wrong_protocol_type,                // EPROTOTYPE
  };

  template <> struct is_error_condition_enum<errc> : true_type {};

  // [syserr.errcode.nonmembers], non-member functions
  error_code make_error_code(errc e) noexcept;

  template <class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const error_code& ec);

  // [syserr.errcondition.nonmembers], non-member functions
  error_condition make_error_condition(errc e) noexcept;

  // [syserr.compare], comparison functions
  bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
  bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
  bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
  bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
  bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
  bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
  bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;

  // [syserr.hash], hash support
  template <class T> struct hash;
  template <> struct hash<error_code>;
  template <> struct hash<error_condition>;

  // [syserr], system error support
  template <class T> inline constexpr bool is_error_code_enum_v
    = is_error_code_enum<T>::value;
  template <class T> inline constexpr bool is_error_condition_enum_v
    = is_error_condition_enum<T>::value;
}
The value of each enum errc constant shall be the same as the value of the <cerrno> macro shown in the above synopsis.
Whether or not the <system_­error> implementation exposes the <cerrno> macros is unspecified.
The is_­error_­code_­enum and is_­error_­condition_­enum may be specialized for user-defined types to indicate that such types are eligible for class error_­code and class error_­condition automatic conversions, respectively.

22.5.2 Class error_­category [syserr.errcat]

22.5.2.1 Class error_­category overview [syserr.errcat.overview]

The class error_­category serves as a base class for types used to identify the source and encoding of a particular category of error code.
Classes may be derived from error_­category to support categories of errors in addition to those defined in this International Standard.
Such classes shall behave as specified in this subclause.
[Note
:
error_­category objects are passed by reference, and two such objects are equal if they have the same address.
This means that applications using custom error_­category types should create a single object of each such type.
end note
]
namespace std {
  class error_category {
  public:
    constexpr error_category() noexcept;
    virtual ~error_category();
    error_category(const error_category&) = delete;
    error_category& operator=(const error_category&) = delete;
    virtual const char* name() const noexcept = 0;
    virtual error_condition default_error_condition(int ev) const noexcept;
    virtual bool equivalent(int code, const error_condition& condition) const noexcept;
    virtual bool equivalent(const error_code& code, int condition) const noexcept;
    virtual string message(int ev) const = 0;

    bool operator==(const error_category& rhs) const noexcept;
    bool operator!=(const error_category& rhs) const noexcept;
    bool operator<(const error_category& rhs) const noexcept;
  };

  const error_category& generic_category() noexcept;
  const error_category& system_category() noexcept;
}

22.5.2.2 Class error_­category virtual members [syserr.errcat.virtuals]

virtual ~error_category();
Effects: Destroys an object of class error_­category.
virtual const char* name() const noexcept = 0;
Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
Returns: error_­condition(ev, *this).
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
Returns: default_­error_­condition(code) == condition.
virtual bool equivalent(const error_code& code, int condition) const noexcept;
Returns: *this == code.category() && code.value() == condition.
virtual string message(int ev) const = 0;
Returns: A string that describes the error condition denoted by ev.

22.5.2.3 Class error_­category non-virtual members [syserr.errcat.nonvirtuals]

constexpr error_category() noexcept;
Effects: Constructs an object of class error_­category.
bool operator==(const error_category& rhs) const noexcept;
Returns: this == &rhs.
bool operator!=(const error_category& rhs) const noexcept;
Returns: !(*this == rhs).
bool operator<(const error_category& rhs) const noexcept;
Returns: less<const error_­category*>()(this, &rhs).
[Note
:
less ([comparisons]) provides a total ordering for pointers.
end note
]

22.5.2.4 Program defined classes derived from error_­category [syserr.errcat.derived]

virtual const char* name() const noexcept = 0;
Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
Returns: An object of type error_­condition that corresponds to ev.
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
Returns: true if, for the category of error represented by *this, code is considered equivalent to condition; otherwise, false.
virtual bool equivalent(const error_code& code, int condition) const noexcept;
Returns: true if, for the category of error represented by *this, code is considered equivalent to condition; otherwise, false.

22.5.2.5 Error category objects [syserr.errcat.objects]

const error_category& generic_category() noexcept;
Returns: A reference to an object of a type derived from class error_­category.
All calls to this function shall return references to the same object.
Remarks: The object's default_­error_­condition and equivalent virtual functions shall behave as specified for the class error_­category.
The object's name virtual function shall return a pointer to the string "generic".
const error_category& system_category() noexcept;
Returns: A reference to an object of a type derived from class error_­category.
All calls to this function shall return references to the same object.
Remarks: The object's equivalent virtual functions shall behave as specified for class error_­category.
The object's name virtual function shall return a pointer to the string "system".
The object's default_­error_­condition virtual function shall behave as follows:
If the argument ev corresponds to a POSIX errno value posv, the function shall return error_­condition(posv, generic_­category()).
Otherwise, the function shall return error_­condition(ev, system_­category()).
What constitutes correspondence for any given operating system is unspecified.
[Note
:
The number of potential system error codes is large and unbounded, and some may not correspond to any POSIX errno value.
Thus implementations are given latitude in determining correspondence.
end note
]

22.5.3 Class error_­code [syserr.errcode]

22.5.3.1 Class error_­code overview [syserr.errcode.overview]

The class error_­code describes an object used to hold error code values, such as those originating from the operating system or other low-level application program interfaces.
[Note
:
Class error_­code is an adjunct to error reporting by exception.
end note
]
namespace std {
  class error_code {
  public:
    // [syserr.errcode.constructors], constructors
    error_code() noexcept;
    error_code(int val, const error_category& cat) noexcept;
    template <class ErrorCodeEnum>
      error_code(ErrorCodeEnum e) noexcept;

    // [syserr.errcode.modifiers], modifiers
    void assign(int val, const error_category& cat) noexcept;
    template <class ErrorCodeEnum>
      error_code& operator=(ErrorCodeEnum e) noexcept;
    void clear() noexcept;

    // [syserr.errcode.observers], observers
    int value() const noexcept;
    const error_category& category() const noexcept;
    error_condition default_error_condition() const noexcept;
    string message() const;
    explicit operator bool() const noexcept;

  private:
    int val_;                   // exposition only
    const error_category* cat_; // exposition only
  };

  // [syserr.errcode.nonmembers], non-member functions
  error_code make_error_code(errc e) noexcept;

  template <class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const error_code& ec);
}

22.5.3.2 Class error_­code constructors [syserr.errcode.constructors]

error_code() noexcept;
Effects: Constructs an object of type error_­code.
Postconditions: val_­ == 0 and cat_­ == &system_­category().
error_code(int val, const error_category& cat) noexcept;
Effects: Constructs an object of type error_­code.
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorCodeEnum> error_code(ErrorCodeEnum e) noexcept;
Effects: Constructs an object of type error_­code.
Postconditions: *this == make_­error_­code(e).
Remarks: This constructor shall not participate in overload resolution unless
is_­error_­code_­enum_­v<ErrorCodeEnum> is true.

22.5.3.3 Class error_­code modifiers [syserr.errcode.modifiers]

void assign(int val, const error_category& cat) noexcept;
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorCodeEnum> error_code& operator=(ErrorCodeEnum e) noexcept;
Postconditions: *this == make_­error_­code(e).
Returns: *this.
Remarks: This operator shall not participate in overload resolution unless
is_­error_­code_­enum_­v<ErrorCodeEnum> is true.
void clear() noexcept;
Postconditions: value() == 0 and category() == system_­category().

22.5.3.4 Class error_­code observers [syserr.errcode.observers]

int value() const noexcept;
Returns: val_­.
const error_category& category() const noexcept;
Returns: *cat_­.
error_condition default_error_condition() const noexcept;
Returns: category().default_­error_­condition(value()).
string message() const;
Returns: category().message(value()).
explicit operator bool() const noexcept;
Returns: value() != 0.

22.5.3.5 Class error_­code non-member functions [syserr.errcode.nonmembers]

error_code make_error_code(errc e) noexcept;
Returns: error_­code(static_­cast<int>(e), generic_­category()).
template <class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const error_code& ec);
Effects: As if by: os << ec.category().name() << ':' << ec.value();

22.5.4 Class error_­condition [syserr.errcondition]

22.5.4.1 Class error_­condition overview [syserr.errcondition.overview]

The class error_­condition describes an object used to hold values identifying error conditions.
[Note
:
error_­condition values are portable abstractions, while error_­code values ([syserr.errcode]) are implementation specific.
end note
]
namespace std {
  class error_condition {
  public:
    // [syserr.errcondition.constructors], constructors
    error_condition() noexcept;
    error_condition(int val, const error_category& cat) noexcept;
    template <class ErrorConditionEnum>
      error_condition(ErrorConditionEnum e) noexcept;

    // [syserr.errcondition.modifiers], modifiers
    void assign(int val, const error_category& cat) noexcept;
    template <class ErrorConditionEnum>
      error_condition& operator=(ErrorConditionEnum e) noexcept;
    void clear() noexcept;

    // [syserr.errcondition.observers], observers
    int value() const noexcept;
    const error_category& category() const noexcept;
    string message() const;
    explicit operator bool() const noexcept;

  private:
    int val_;                   // exposition only
    const error_category* cat_; // exposition only
  };
}

22.5.4.2 Class error_­condition constructors [syserr.errcondition.constructors]

error_condition() noexcept;
Effects: Constructs an object of type error_­condition.
Postconditions: val_­ == 0 and cat_­ == &generic_­category().
error_condition(int val, const error_category& cat) noexcept;
Effects: Constructs an object of type error_­condition.
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorConditionEnum> error_condition(ErrorConditionEnum e) noexcept;
Effects: Constructs an object of type error_­condition.
Postconditions: *this == make_­error_­condition(e).
Remarks: This constructor shall not participate in overload resolution unless
is_­error_­condition_­enum_­v<ErrorConditionEnum> is true.

22.5.4.3 Class error_­condition modifiers [syserr.errcondition.modifiers]

void assign(int val, const error_category& cat) noexcept;
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorConditionEnum> error_condition& operator=(ErrorConditionEnum e) noexcept;
Postconditions: *this == make_­error_­condition(e).
Returns: *this.
Remarks: This operator shall not participate in overload resolution unless
is_­error_­condition_­enum_­v<ErrorConditionEnum> is true.
void clear() noexcept;
Postconditions: value() == 0 and category() == generic_­category().

22.5.4.4 Class error_­condition observers [syserr.errcondition.observers]

int value() const noexcept;
Returns: val_­.
const error_category& category() const noexcept;
Returns: *cat_­.
string message() const;
Returns: category().message(value()).
explicit operator bool() const noexcept;
Returns: value() != 0.

22.5.4.5 Class error_­condition non-member functions [syserr.errcondition.nonmembers]

error_condition make_error_condition(errc e) noexcept;
Returns: error_­condition(static_­cast<int>(e), generic_­category()).

22.5.5 Comparison functions [syserr.compare]

bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
Returns:
lhs.category() < rhs.category() ||
(lhs.category() == rhs.category() && lhs.value() < rhs.value());
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
Returns: lhs.category() < rhs.category() || lhs.category() == rhs.category() &&
lhs.value() < rhs.value()
.
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
Returns: lhs.category() == rhs.category() && lhs.value() == rhs.value().
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
Returns: lhs.category().equivalent(lhs.value(), rhs) || rhs.category().equivalent(lhs, rhs.value()).
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
Returns: rhs.category().equivalent(rhs.value(), lhs) || lhs.category().equivalent(rhs, lhs.value()).
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
Returns: lhs.category() == rhs.category() && lhs.value() == rhs.value().
bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
Returns: !(lhs == rhs).

22.5.6 System error hash support [syserr.hash]

template <> struct hash<error_code>; template <> struct hash<error_condition>;
The specializations are enabled ([unord.hash]).

22.5.7 Class system_­error [syserr.syserr]

22.5.7.1 Class system_­error overview [syserr.syserr.overview]

The class system_­error describes an exception object used to report error conditions that have an associated error code.
Such error conditions typically originate from the operating system or other low-level application program interfaces.
[Note
:
If an error represents an out-of-memory condition, implementations are encouraged to throw an exception object of type bad_­alloc ([bad.alloc]) rather than system_­error.
end note
]
namespace std {
  class system_error : public runtime_error {
  public:
    system_error(error_code ec, const string& what_arg);
    system_error(error_code ec, const char* what_arg);
    system_error(error_code ec);
    system_error(int ev, const error_category& ecat, const string& what_arg);
    system_error(int ev, const error_category& ecat, const char* what_arg);
    system_error(int ev, const error_category& ecat);
    const error_code& code() const noexcept;
    const char* what() const noexcept override;
  };
}

22.5.7.2 Class system_­error members [syserr.syserr.members]

system_error(error_code ec, const string& what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == ec.
string(what()).find(what_­arg) != string​::​npos.
system_error(error_code ec, const char* what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == ec.
string(what()).find(what_­arg) != string​::​npos.
system_error(error_code ec);
Effects: Constructs an object of class system_­error.
Postconditions: code() == ec.
system_error(int ev, const error_category& ecat, const string& what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == error_­code(ev, ecat).
string(what()).find(what_­arg) != string​::​npos.
system_error(int ev, const error_category& ecat, const char* what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == error_­code(ev, ecat).
string(what()).find(what_­arg) != string​::​npos.
system_error(int ev, const error_category& ecat);
Effects: Constructs an object of class system_­error.
Postconditions: code() == error_­code(ev, ecat).
const error_code& code() const noexcept;
Returns: ec or error_­code(ev, ecat), from the constructor, as appropriate.
const char* what() const noexcept override;
Returns: An ntbs incorporating the arguments supplied in the constructor.
[Note
:
The returned ntbs might be the contents of what_­arg + ": " + code.message().
end note
]

23 General utilities library [utilities]

23.1 General [utilities.general]

This Clause describes utilities that are generally useful in C++ programs; some of these utilities are used by other elements of the C++ standard library.
These utilities are summarized in Table 34.
Table 34 — General utilities library summary
Subclause
Header(s)
Utility components
<utility>
Compile-time integer sequences
<utility>
Pairs
<utility>
Tuples
<tuple>
Optional objects
<optional>
Variants
<variant>
Storage for any type
<any>
Fixed-size sequences of bits
<bitset>
Memory
<memory>
<cstdlib>
Smart pointers
<memory>
Memory resources
<memory_­resource>
Scoped allocators
<scoped_­allocator>
Function objects
<functional>
Type traits
<type_­traits>
Compile-time rational arithmetic
<ratio>
Time utilities
<chrono>
<ctime>
Type indexes
<typeindex>
Execution policies
<execution>

23.2 Utility components [utility]

This subclause contains some basic function and class templates that are used throughout the rest of the library.

23.2.1 Header <utility> synopsis [utility.syn]

#include <initializer_list>     // see [initializer_list.syn]

namespace std {
  // [operators], operators
  namespace rel_ops {
    template<class T> bool operator!=(const T&, const T&);
    template<class T> bool operator> (const T&, const T&);
    template<class T> bool operator<=(const T&, const T&);
    template<class T> bool operator>=(const T&, const T&);
  }

  // [utility.swap], swap
  template <class T>
    void swap(T& a, T& b) noexcept(see below);
  template <class T, size_t N>
    void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);

  // [utility.exchange], exchange
  template <class T, class U = T>
    T exchange(T& obj, U&& new_val);

  // [forward], forward/move
  template <class T>
    constexpr T&& forward(remove_reference_t<T>& t) noexcept;
  template <class T>
    constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
  template <class T>
    constexpr remove_reference_t<T>&& move(T&&) noexcept;
  template <class T>
    constexpr conditional_t<
        !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&>
      move_if_noexcept(T& x) noexcept;

  // [utility.as_const], as_­const
  template <class T>
    constexpr add_const_t<T>& as_const(T& t) noexcept;
  template <class T>
    void as_const(const T&&) = delete;

  // [declval], declval
  template <class T>
    add_rvalue_reference_t<T> declval() noexcept;  // as unevaluated operand

  // [intseq], Compile-time integer sequences
  template<class T, T...>
    struct integer_sequence;
  template<size_t... I>
    using index_sequence = integer_sequence<size_t, I...>;

  template<class T, T N>
    using make_integer_sequence = integer_sequence<T, see below>;
  template<size_t N>
    using make_index_sequence = make_integer_sequence<size_t, N>;

  template<class... T>
    using index_sequence_for = make_index_sequence<sizeof...(T)>;

  // [pairs], class template pair
  template <class T1, class T2>
    struct pair;

  // [pairs.spec], pair specialized algorithms
  template <class T1, class T2>
    constexpr bool operator==(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator< (const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator!=(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator> (const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator>=(const pair<T1, T2>&, const pair<T1, T2>&);
  template <class T1, class T2>
    constexpr bool operator<=(const pair<T1, T2>&, const pair<T1, T2>&);

  template <class T1, class T2>
    void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));

  template <class T1, class T2>
    constexpr see below make_pair(T1&&, T2&&);

  // [pair.astuple], tuple-like access to pair
  template <class T> class tuple_size;
  template <size_t I, class T> class tuple_element;

  template <class T1, class T2> struct tuple_size<pair<T1, T2>>;
  template <class T1, class T2> struct tuple_element<0, pair<T1, T2>>;
  template <class T1, class T2> struct tuple_element<1, pair<T1, T2>>;

  template<size_t I, class T1, class T2>
    constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>&) noexcept;
  template<size_t I, class T1, class T2>
    constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&&) noexcept;
  template <class T1, class T2>
    constexpr T1& get(pair<T1, T2>& p) noexcept;
  template <class T1, class T2>
    constexpr const T1& get(const pair<T1, T2>& p) noexcept;
  template <class T1, class T2>
    constexpr T1&& get(pair<T1, T2>&& p) noexcept;
  template <class T1, class T2>
    constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
  template <class T2, class T1>
    constexpr T2& get(pair<T1, T2>& p) noexcept;
  template <class T2, class T1>
    constexpr const T2& get(const pair<T1, T2>& p) noexcept;
  template <class T2, class T1>
    constexpr T2&& get(pair<T1, T2>&& p) noexcept;
  template <class T2, class T1>
    constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;

  // [pair.piecewise], pair piecewise construction
  struct piecewise_construct_t {
    explicit piecewise_construct_t() = default;
  };
  inline constexpr piecewise_construct_t piecewise_construct{};
  template <class... Types> class tuple;        // defined in <tuple> ([tuple.syn])

  // in-place construction
  struct in_place_t {
    explicit in_place_t() = default;
  };
  inline constexpr in_place_t in_place{};
  template <class T>
    struct in_place_type_t {
      explicit in_place_type_t() = default;
    };
  template <class T> inline constexpr in_place_type_t<T> in_place_type{};
  template <size_t I>
    struct in_place_index_t {
      explicit in_place_index_t() = default;
    };
  template <size_t I> inline constexpr in_place_index_t<I> in_place_index{};


  // floating-point format for primitive numerical conversion
  enum class chars_format {
    scientific = unspecified,
    fixed = unspecified,
    hex = unspecified,
    general = fixed | scientific
  };



  // [utility.to.chars], primitive numerical output conversion
  struct to_chars_result {
    char* ptr;
    error_code ec;
  };

  to_chars_result to_chars(char* first, char* last, see below value, int base = 10);

  to_chars_result to_chars(char* first, char* last, float value);
  to_chars_result to_chars(char* first, char* last, double value);
  to_chars_result to_chars(char* first, char* last, long double value);

  to_chars_result to_chars(char* first, char* last, float value,
                           chars_format fmt);
  to_chars_result to_chars(char* first, char* last, double value,
                           chars_format fmt);
  to_chars_result to_chars(char* first, char* last, long double value,
                           chars_format fmt);

  to_chars_result to_chars(char* first, char* last, float value,
                           chars_format fmt, int precision);
  to_chars_result to_chars(char* first, char* last, double value,
                           chars_format fmt, int precision);
  to_chars_result to_chars(char* first, char* last, long double value,
                           chars_format fmt, int precision);



  // [utility.from.chars], primitive numerical input conversion
  struct from_chars_result {
    const char* ptr;
    error_code ec;
  };

  from_chars_result from_chars(const char* first, const char* last,
                               see below& value, int base = 10);

  from_chars_result from_chars(const char* first, const char* last, float& value,
                               chars_format fmt = chars_format::general);
  from_chars_result from_chars(const char* first, const char* last, double& value,
                               chars_format fmt = chars_format::general);
  from_chars_result from_chars(const char* first, const char* last, long double& value,
                               chars_format fmt = chars_format::general);
}
The header <utility> defines several types and function templates that are described in this Clause.
It also defines the template pair and various function templates that operate on pair objects.
The type chars_­format is a bitmask type ([bitmask.types]) with elements scientific, fixed, and hex.

23.2.2 Operators [operators]

To avoid redundant definitions of operator!= out of operator== and operators >, <=, and >= out of operator<, the library provides the following:
template <class T> bool operator!=(const T& x, const T& y);
Requires: Type T is EqualityComparable (Table 20).
Returns: !(x == y).
template <class T> bool operator>(const T& x, const T& y);
Requires: Type T is LessThanComparable (Table 21).
Returns: y < x.
template <class T> bool operator<=(const T& x, const T& y);
Requires: Type T is LessThanComparable (Table 21).
Returns: !(y < x).
template <class T> bool operator>=(const T& x, const T& y);
Requires: Type T is LessThanComparable (Table 21).
Returns: !(x < y).
In this library, whenever a declaration is provided for an operator!=, operator>, operator>=, or operator<=, and requirements and semantics are not explicitly provided, the requirements and semantics are as specified in this Clause.

23.2.3 swap [utility.swap]

template <class T> void swap(T& a, T& b) noexcept(see below);
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true and is_­move_­assignable_­v<T> is true.
The expression inside noexcept is equivalent to:
is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
Requires: Type T shall be MoveConstructible (Table 23) and MoveAssignable (Table 25).
Effects: Exchanges values stored in two locations.
template <class T, size_t N> void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<T> is true.
Requires: a[i] shall be swappable with ([swappable.requirements]) b[i] for all i in the range [0, N).
Effects: As if by swap_­ranges(a, a + N, b).

23.2.4 exchange [utility.exchange]

template <class T, class U = T> T exchange(T& obj, U&& new_val);
Effects: Equivalent to:
T old_val = std::move(obj);
obj = std::forward<U>(new_val);
return old_val;

23.2.5 Forward/move helpers [forward]

The library provides templated helper functions to simplify applying move semantics to an lvalue and to simplify the implementation of forwarding functions.
All functions specified in this subclause are signal-safe ([csignal.syn]).
template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept; template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
Returns: static_­cast<T&&>(t).
Remarks: If the second form is instantiated with an lvalue reference type, the program is ill-formed.
[Example
:
template <class T, class A1, class A2>
shared_ptr<T> factory(A1&& a1, A2&& a2) {
  return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2)));
}

struct A {
  A(int&, const double&);
};

void g() {
  shared_ptr<A> sp1 = factory<A>(2, 1.414); // error: 2 will not bind to int&
  int i = 2;
  shared_ptr<A> sp2 = factory<A>(i, 1.414); // OK
}
In the first call to factory, A1 is deduced as int, so 2 is forwarded to A's constructor as an rvalue.
In the second call to factory, A1 is deduced as int&, so i is forwarded to A's constructor as an lvalue.
In both cases, A2 is deduced as double, so 1.
414 is forwarded to A's constructor as an rvalue.
end example
]
template <class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
Returns: static_­cast<remove_­reference_­t<T>&&>(t).
[Example
:
template <class T, class A1>
shared_ptr<T> factory(A1&& a1) {
  return shared_ptr<T>(new T(std::forward<A1>(a1)));
}

struct A {
  A();
  A(const A&);      // copies from lvalues
  A(A&&);           // moves from rvalues
};

void g() {
  A a;
  shared_ptr<A> sp1 = factory<A>(a);                // “a” binds to A(const A&)
  shared_ptr<A> sp1 = factory<A>(std::move(a));     // “a” binds to A(A&&)
}
In the first call to factory, A1 is deduced as A&, so a is forwarded as a non-const lvalue.
This binds to the constructor A(const A&), which copies the value from a.
In the second call to factory, because of the call std​::​move(a), A1 is deduced as A, so a is forwarded as an rvalue.
This binds to the constructor A(A&&), which moves the value from a.
end example
]
template <class T> constexpr conditional_t< !is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&> move_if_noexcept(T& x) noexcept;
Returns: std​::​move(x).

23.2.6 Function template as_­const [utility.as_const]

template <class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
Returns: t.

23.2.7 Function template declval [declval]

The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands (Clause [expr]).
template <class T> add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand
Remarks: If this function is odr-used ([basic.def.odr]), the program is ill-formed.
Remarks: The template parameter T of declval may be an incomplete type.
[Example
:
template <class To, class From> decltype(static_cast<To>(declval<From>())) convert(From&&);
declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To.
For another example see class template common_­type ([meta.trans.other]).
end example
]

23.2.8 Primitive numeric output conversion [utility.to.chars]

All functions named to_­chars convert value into a character string by successively filling the range [first, last), where [first, last) is required to be a valid range.
If the member ec of the return value is such that the value, when converted to bool, is false, the conversion was successful and the member ptr is the one-past-the-end pointer of the characters written.
Otherwise, the member ec has the value errc​::​value_­too_­large, the member ptr has the value last, and the contents of the range [first, last) are unspecified.
The functions that take a floating-point value but not a precision parameter ensure that the string representation consists of the smallest number of characters such that there is at least one digit before the radix point (if present) and parsing the representation using the corresponding from_­chars function recovers value exactly.
[Note
:
This guarantee applies only if to_­chars and from_­chars are executed on the same implementation.
end note
]
The functions taking a chars_­format parameter determine the conversion specifier for printf as follows: The conversion specifier is f if fmt is chars_­format​::​fixed, e if fmt is chars_­format​::​scientific, a (without leading "0x" in the result) if fmt is chars_­format​::​hex, and g if fmt is chars_­format​::​general.
to_chars_result to_chars(char* first, char* last, see below value, int base = 10);
Requires: base has a value between 2 and 36 (inclusive).
Effects: The value of value is converted to a string of digits in the given base (with no redundant leading zeroes).
Digits in the range 10.
35 (inclusive) are represented as lowercase characters a.
z.
If value is less than zero, the representation starts with a minus sign.
Throws: Nothing.
Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the type of the parameter value.
to_chars_result to_chars(char* first, char* last, float value); to_chars_result to_chars(char* first, char* last, double value); to_chars_result to_chars(char* first, char* last, long double value);
Effects: value is converted to a string in the style of printf in the "C" locale.
The conversion specifier is f or e, chosen according to the requirement for a shortest representation (see above); a tie is resolved in favor of f.
Throws: Nothing.
to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt);
Requires: fmt has the value of one of the enumerators of chars_­format.
Effects: value is converted to a string in the style of printf in the "C" locale.
Throws: Nothing.
to_chars_result to_chars(char* first, char* last, float value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, double value, chars_format fmt, int precision); to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt, int precision);
Requires: fmt has the value of one of the enumerators of chars_­format.
Effects: value is converted to a string in the style of printf in the "C" locale with the given precision.
Throws: Nothing.
See also: ISO C 7.
21.
6.
1.

23.2.9 Primitive numeric input conversion [utility.from.chars]

All functions named from_­chars analyze the string [first, last) for a pattern, where [first, last) is required to be a valid range.
If no characters match the pattern, value is unmodified, the member ptr of the return value is first and the member ec is equal to errc​::​invalid_­argument.
Otherwise, the characters matching the pattern are interpreted as a representation of a value of the type of value.
The member ptr of the return value points to the first character not matching the pattern, or has the value last if all characters match.
If the parsed value is not in the range representable by the type of value, value is unmodified and the member ec of the return value is equal to errc​::​result_­out_­of_­range.
Otherwise, value is set to the parsed value and the member ec is set such that the conversion to bool yields false.
from_chars_result from_chars(const char* first, const char* last, see below& value, int base = 10);
Requires: base has a value between 2 and 36 (inclusive).
Effects: The pattern is the expected form of the subject sequence in the "C" locale for the given nonzero base, as described for strtol, except that no "0x" or "0X" prefix shall appear if the value of base is 16, and except that a minus sign is the only sign that may appear, and only if value has a signed type.
Throws: Nothing.
Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the referenced type of the parameter value.
from_chars_result from_chars(const char* first, const char* last, float& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, double& value, chars_format fmt = chars_format::general); from_chars_result from_chars(const char* first, const char* last, long double& value, chars_format fmt = chars_format::general);
Requires: fmt has the value of one of the enumerators of chars_­format.
Effects: The pattern is the expected form of the subject sequence in the "C" locale, as described for strtod, except that
  • the only sign that may appear is a minus sign;
  • if fmt has chars_­format​::​scientific set but not chars_­format​::​fixed, the otherwise optional exponent part shall appear;
  • if fmt has chars_­format​::​fixed set but not chars_­format​::​scientific, the optional exponent part shall not appear; and
  • if fmt is chars_­format​::​hex, the prefix "0x" or "0X" is assumed.
    [Example
    :
    The string 0x123 is parsed to have the value 0 with remaining characters x123.
    end example
    ]
In any case, the resulting value is one of at most two floating-point values closest to the value of the string matching the pattern.
Throws: Nothing.
See also: ISO C 7.
22.
1.
3, ISO C 7.
22.
1.
4.

23.3 Compile-time integer sequences [intseq]

23.3.1 In general [intseq.general]

The library provides a class template that can represent an integer sequence.
When used as an argument to a function template the parameter pack defining the sequence can be deduced and used in a pack expansion.
[Note
:
The index_­sequence alias template is provided for the common case of an integer sequence of type size_­t; see also [tuple.apply].
end note
]

23.3.2 Class template integer_­sequence [intseq.intseq]

namespace std {
  template<class T, T... I>
    struct integer_sequence {
      using value_type = T;
      static constexpr size_t size() noexcept { return sizeof...(I); }
    };
}
T shall be an integer type.

23.3.3 Alias template make_­integer_­sequence [intseq.make]

template<class T, T N> using make_integer_sequence = integer_sequence<T, see below>;
If N is negative the program is ill-formed.
The alias template make_­integer_­sequence denotes a specialization of integer_­sequence with N template non-type arguments.
The type make_­integer_­sequence<T, N> denotes the type integer_­sequence<T, 0, 1, ..., N-1>.
[Note
:
make_­integer_­sequence<int, 0> denotes the type integer_­sequence<int>
end note
]

23.4 Pairs [pairs]

23.4.1 In general [pairs.general]

The library provides a template for heterogeneous pairs of values.
The library also provides a matching function template to simplify their construction and several templates that provide access to pair objects as if they were tuple objects (see [tuple.helper] and [tuple.elem]).

23.4.2 Class template pair [pairs.pair]

namespace std {
  template <class T1, class T2>
    struct pair {
      using first_type  = T1;
      using second_type = T2;

      T1 first;
      T2 second;

      pair(const pair&) = default;
      pair(pair&&) = default;
      EXPLICIT constexpr pair();
      EXPLICIT constexpr pair(const T1& x, const T2& y);
      template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
      template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
      template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
      template <class... Args1, class... Args2>
        pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);

      pair& operator=(const pair& p);
      template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
      pair& operator=(pair&& p) noexcept(see below);
      template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);

      void swap(pair& p) noexcept(see below);
    };

  template<class T1, class T2>
    pair(T1, T2) -> pair<T1, T2>;
}
Constructors and member functions of pair shall not throw exceptions unless one of the element-wise operations specified to be called for that operation throws an exception.
The defaulted move and copy constructor, respectively, of pair shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function.
The destructor of pair shall be a trivial destructor if (is_­trivially_­destructible_­v<T1> && is_­trivially_­destructible_­v<T2>) is true.
EXPLICIT constexpr pair();
Effects: Value-initializes first and second.
Remarks: This constructor shall not participate in overload resolution unless is_­default_­constructible_­v<first_­type> is true and is_­default_­constructible_­v<second_­type> is true.
[Note
:
This behavior can be implemented by a constructor template with default template arguments.
end note
]
The constructor is explicit if and only if either first_­type or second_­type is not implicitly default-constructible.
[Note
:
This behavior can be implemented with a trait that checks whether a const first_­type& or a const second_­type& can be initialized with {}.
end note
]
EXPLICIT constexpr pair(const T1& x, const T2& y);
Effects: Initializes first with x and second with y.
Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<first_­type> is true and is_­copy_­constructible_­v<second_­type> is true.
The constructor is explicit if and only if is_­convertible_­v<const first_­type&, first_­type> is false or is_­convertible_­v<const second_­type&, second_­type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
Effects: Initializes first with std​::​forward<U1>(x) and second with std​::​forward<U2>(y).
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<first_­type, U1&&> is true and is_­constructible_­v<second_­type, U2&&> is true.
The constructor is explicit if and only if is_­convertible_­v<U1&&, first_­type> is false or is_­convertible_­v<U2&&, second_­type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
Effects: Initializes members from the corresponding members of the argument.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<first_­type, const U1&> is true and is_­constructible_­v<second_­type, const U2&> is true.
The constructor is explicit if and only if is_­convertible_­v<const U1&, first_­type> is false or is_­convertible_­v<const U2&, second_­type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
Effects: Initializes first with std​::​forward<U1>(p.first) and second with std​::​forward<U2>(​p.second).
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<first_­type, U1&&> is true and is_­constructible_­v<second_­type, U2&&> is true.
The constructor is explicit if and only if is_­convertible_­v<U1&&, first_­type> is false or is_­convertible_­v<U2&&, second_­type> is false.
template<class... Args1, class... Args2> pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
Requires: is_­constructible_­v<first_­type, Args1&&...> is true and is_­constructible_­v<second_­type, Args2&&...> is true.
Effects: Initializes first with arguments of types Args1... obtained by forwarding the elements of first_­args and initializes second with arguments of types Args2... obtained by forwarding the elements of second_­args.
(Here, forwarding an element x of type U within a tuple object means calling std​::​forward<U>(x).)
This form of construction, whereby constructor arguments for first and second are each provided in a separate tuple object, is called piecewise construction.
pair& operator=(const pair& p);
Effects: Assigns p.first to first and p.second to second.
Remarks: This operator shall be defined as deleted unless is_­copy_­assignable_­v<first_­type> is true and is_­copy_­assignable_­v<second_­type> is true.
Returns: *this.
template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
Effects: Assigns p.first to first and p.second to second.
Remarks: This operator shall not participate in overload resolution unless is_­assignable_­v<first_­type&, const U1&> is true and is_­assignable_­v<second_­type&, const U2&> is true.
Returns: *this.
pair& operator=(pair&& p) noexcept(see below);
Effects: Assigns to first with std​::​forward<first_­type>(p.first) and to second with
std​::​forward<second_­type>(p.second).
Remarks: This operator shall be defined as deleted unless is_­move_­assignable_­v<first_­type> is true and is_­move_­assignable_­v<second_­type> is true.
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
Returns: *this.
template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
Effects: Assigns to first with std​::​forward<U>(p.first) and to second with
std​::​forward<V>(p.second).
Remarks: This operator shall not participate in overload resolution unless is_­assignable_­v<first_­type&, U1&&> is true and is_­assignable_­v<second_­type&, U2&&> is true.
Returns: *this.
void swap(pair& p) noexcept(see below);
Requires: first shall be swappable with ([swappable.requirements]) p.first and second shall be swappable with p.second.
Effects: Swaps first with p.first and second with p.second.
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_swappable_v<first_type> && is_nothrow_swappable_v<second_type>

23.4.3 Specialized algorithms [pairs.spec]

template <class T1, class T2> constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: x.first == y.first && x.second == y.second.
template <class T1, class T2> constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: x.first < y.first || (!(y.first < x.first) && x.second < y.second).
template <class T1, class T2> constexpr bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: !(x == y).
template <class T1, class T2> constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: y < x.
template <class T1, class T2> constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: !(x < y).
template <class T1, class T2> constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns: !(y < x).
template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<T1> is true and is_­swappable_­v<T2> is true.
template <class T1, class T2> constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
Returns: pair<V1, V2>(std​::​forward<T1>(x), std​::​forward<T2>(y)), where V1 and V2 are determined as follows: Let Ui be decay_­t<Ti> for each Ti.
If Ui is a specialization of reference_­wrapper, then Vi is Ui​::​type&, otherwise Vi is Ui.
[Example
:
In place of:
  return pair<int, double>(5, 3.1415926);   // explicit types
a C++ program may contain:
  return make_pair(5, 3.1415926);           // types are deduced
end example
]

23.4.4 Tuple-like access to pair [pair.astuple]

template <class T1, class T2> struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
tuple_element<0, pair<T1, T2>>::type
Value: The type T1.
tuple_element<1, pair<T1, T2>>::type
Value: The type T2.
template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>& p) noexcept; template<size_t I, class T1, class T2> constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept; template<size_t I, class T1, class T2> constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
Returns: If I == 0 returns a reference to p.first; if I == 1 returns a reference to p.second; otherwise the program is ill-formed.
template <class T1, class T2> constexpr T1& get(pair<T1, T2>& p) noexcept; template <class T1, class T2> constexpr const T1& get(const pair<T1, T2>& p) noexcept; template <class T1, class T2> constexpr T1&& get(pair<T1, T2>&& p) noexcept; template <class T1, class T2> constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
Requires: T1 and T2 are distinct types.
Otherwise, the program is ill-formed.
Returns: A reference to p.first.
template <class T2, class T1> constexpr T2& get(pair<T1, T2>& p) noexcept; template <class T2, class T1> constexpr const T2& get(const pair<T1, T2>& p) noexcept; template <class T2, class T1> constexpr T2&& get(pair<T1, T2>&& p) noexcept; template <class T2, class T1> constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
Requires: T1 and T2 are distinct types.
Otherwise, the program is ill-formed.
Returns: A reference to p.second.

23.4.5 Piecewise construction [pair.piecewise]

struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{};
The struct piecewise_­construct_­t is an empty structure type used as a unique type to disambiguate constructor and function overloading.
Specifically, pair has a constructor with piecewise_­construct_­t as the first argument, immediately followed by two tuple ([tuple]) arguments used for piecewise construction of the elements of the pair object.

23.5 Tuples [tuple]

23.5.1 In general [tuple.general]

This subclause describes the tuple library that provides a tuple type as the class template tuple that can be instantiated with any number of arguments.
Each template argument specifies the type of an element in the tuple.
Consequently, tuples are heterogeneous, fixed-size collections of values.
An instantiation of tuple with two arguments is similar to an instantiation of pair with the same two arguments.

23.5.2 Header <tuple> synopsis [tuple.syn]

namespace std {
  // [tuple.tuple], class template tuple
  template <class... Types>
    class tuple;

  // [tuple.creation], tuple creation functions
  inline constexpr unspecified ignore;

  template <class... TTypes>
    constexpr tuple<VTypes...> make_tuple(TTypes&&...);

  template <class... TTypes>
    constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept;

  template<class... TTypes>
    constexpr tuple<TTypes&...> tie(TTypes&...) noexcept;

  template <class... Tuples>
    constexpr tuple<CTypes...> tuple_cat(Tuples&&...);

  // [tuple.apply], calling a function with a tuple of arguments
  template <class F, class Tuple>
    constexpr decltype(auto) apply(F&& f, Tuple&& t);

  template <class T, class Tuple>
    constexpr T make_from_tuple(Tuple&& t);

  // [tuple.helper], tuple helper classes
  template <class T> class tuple_size;                  // not defined
  template <class T> class tuple_size<const T>;
  template <class T> class tuple_size<volatile T>;
  template <class T> class tuple_size<const volatile T>;

  template <class... Types> class tuple_size<tuple<Types...>>;

  template <size_t I, class T> class tuple_element;     // not defined
  template <size_t I, class T> class tuple_element<I, const T>;
  template <size_t I, class T> class tuple_element<I, volatile T>;
  template <size_t I, class T> class tuple_element<I, const volatile T>;

  template <size_t I, class... Types>
    class tuple_element<I, tuple<Types...>>;

  template <size_t I, class T>
    using tuple_element_t = typename tuple_element<I, T>::type;

  // [tuple.elem], element access
  template <size_t I, class... Types>
    constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept;
  template <size_t I, class... Types>
    constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&&) noexcept;
  template <size_t I, class... Types>
    constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>&) noexcept;
  template <size_t I, class... Types>
    constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&&) noexcept;
  template <class T, class... Types>
    constexpr T& get(tuple<Types...>& t) noexcept;
  template <class T, class... Types>
    constexpr T&& get(tuple<Types...>&& t) noexcept;
  template <class T, class... Types>
    constexpr const T& get(const tuple<Types...>& t) noexcept;
  template <class T, class... Types>
    constexpr const T&& get(const tuple<Types...>&& t) noexcept;

  // [tuple.rel], relational operators
  template<class... TTypes, class... UTypes>
    constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&);
  template<class... TTypes, class... UTypes>
    constexpr bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&);

  // [tuple.traits], allocator-related traits
  template <class... Types, class Alloc>
    struct uses_allocator<tuple<Types...>, Alloc>;

  // [tuple.special], specialized algorithms
  template <class... Types>
    void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);

  // [tuple.helper], tuple helper classes
  template <class T>
    inline constexpr size_t tuple_size_v = tuple_size<T>::value;
}

23.5.3 Class template tuple [tuple.tuple]

namespace std {
  template <class... Types>
    class tuple  {
    public:
      // [tuple.cnstr], tuple construction
      EXPLICIT constexpr tuple();
      EXPLICIT constexpr tuple(const Types&...);         // only if sizeof...(Types) >= 1
      template <class... UTypes>
        EXPLICIT constexpr tuple(UTypes&&...);           // only if sizeof...(Types) >= 1

      tuple(const tuple&) = default;
      tuple(tuple&&) = default;

      template <class... UTypes>
        EXPLICIT constexpr tuple(const tuple<UTypes...>&);
      template <class... UTypes>
        EXPLICIT constexpr tuple(tuple<UTypes...>&&);

      template <class U1, class U2>
        EXPLICIT constexpr tuple(const pair<U1, U2>&);   // only if sizeof...(Types) == 2
      template <class U1, class U2>
        EXPLICIT constexpr tuple(pair<U1, U2>&&);        // only if sizeof...(Types) == 2

      // allocator-extended constructors
      template <class Alloc>
        tuple(allocator_arg_t, const Alloc& a);
      template <class Alloc>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
      template <class Alloc, class... UTypes>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
      template <class Alloc>
        tuple(allocator_arg_t, const Alloc& a, const tuple&);
      template <class Alloc>
        tuple(allocator_arg_t, const Alloc& a, tuple&&);
      template <class Alloc, class... UTypes>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
      template <class Alloc, class... UTypes>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
      template <class Alloc, class U1, class U2>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
      template <class Alloc, class U1, class U2>
        EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);

      // [tuple.assign], tuple assignment
      tuple& operator=(const tuple&);
      tuple& operator=(tuple&&) noexcept(see below);

      template <class... UTypes>
        tuple& operator=(const tuple<UTypes...>&);
      template <class... UTypes>
        tuple& operator=(tuple<UTypes...>&&);

      template <class U1, class U2>
        tuple& operator=(const pair<U1, U2>&);              // only if sizeof...(Types) == 2
      template <class U1, class U2>
        tuple& operator=(pair<U1, U2>&&);                   // only if sizeof...(Types) == 2

      // [tuple.swap], tuple swap
      void swap(tuple&) noexcept(see below);
    };

  template<class... UTypes>
    tuple(UTypes...) -> tuple<UTypes...>;
  template<class T1, class T2>
    tuple(pair<T1, T2>) -> tuple<T1, T2>;
  template<class Alloc, class... UTypes>
    tuple(allocator_arg_t, Alloc, UTypes...) -> tuple<UTypes...>;
  template<class Alloc, class T1, class T2>
    tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;
  template<class Alloc, class... UTypes>
    tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
}

23.5.3.1 Construction [tuple.cnstr]

For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception.
The defaulted move and copy constructor, respectively, of tuple shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function.
The defaulted move and copy constructor of tuple<> shall be constexpr functions.
The destructor of tuple shall be a trivial destructor if (is_­trivially_­destructible_­v<Types> && ...) is true.
In the constructor descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, be the type in Types, and be the type in a template parameter pack named UTypes, where indexing is zero-based.
EXPLICIT constexpr tuple();
Effects: Value-initializes each element.
Remarks: This constructor shall not participate in overload resolution unless is_­default_­constructible_­v<> is true for all i.
[Note
:
This behavior can be implemented by a constructor template with default template arguments.
end note
]
The constructor is explicit if and only if is not implicitly default-constructible for at least one i.
[Note
:
This behavior can be implemented with a trait that checks whether a const & can be initialized with {}.
end note
]
EXPLICIT constexpr tuple(const Types&...);
Effects: Initializes each element with the value of the corresponding parameter.
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) >= 1 and is_­copy_­constructible_­v<> is true for all i.
The constructor is explicit if and only if is_­convertible_­v<const &, > is false for at least one i.
template <class... UTypes> EXPLICIT constexpr tuple(UTypes&&... u);
Effects: Initializes the elements in the tuple with the corresponding value in std​::​forward<UTypes>(u).
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == sizeof...(UTypes) and sizeof...(Types) >= 1 and is_­constructible_­v<, &&> is true for all i.
The constructor is explicit if and only if is_­convertible_­v<&&, > is false for at least one i.
tuple(const tuple& u) = default;
Requires: is_­copy_­constructible_­v<> is true for all i.
Effects: Initializes each element of *this with the corresponding element of u.
tuple(tuple&& u) = default;
Requires: is_­move_­constructible_­v<> is true for all i.
Effects: For all i, initializes the element of *this with std​::​forward<>(get<i>(u)).
template <class... UTypes> EXPLICIT constexpr tuple(const tuple<UTypes...>& u);
Effects: Initializes each element of *this with the corresponding element of u.
Remarks: This constructor shall not participate in overload resolution unless
  • sizeof...(Types) == sizeof...(UTypes) and
  • is_­constructible_­v<, const &> is true for all i, and
  • sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands to U)
    !is_­convertible_­v<const tuple<U>&, T> && !is_­constructible_­v<T, const tuple<U>&>
    && !is_­same_­v<T, U>
    is true.
The constructor is explicit if and only if is_­convertible_­v<const &, > is false for at least one i.
template <class... UTypes> EXPLICIT constexpr tuple(tuple<UTypes...>&& u);
Effects: For all i, initializes the element of *this with std​::​forward<>(get<i>(u)).
Remarks: This constructor shall not participate in overload resolution unless
  • sizeof...(Types) == sizeof...(UTypes), and
  • is_­constructible_­v<, &&> is true for all i, and
  • sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands to U)
    !is_­convertible_­v<tuple<U>, T> && !is_­constructible_­v<T, tuple<U>> &&
    !is_­same_­v<T, U>
    is true.
The constructor is explicit if and only if is_­convertible_­v<&&, > is false for at least one i.
template <class U1, class U2> EXPLICIT constexpr tuple(const pair<U1, U2>& u);
Effects: Initializes the first element with u.first and the second element with u.second.
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2, is_­constructible_­v<, const U1&> is true and is_­constructible_­v<, const U2&> is true.
The constructor is explicit if and only if is_­convertible_­v<const U1&, > is false or is_­convertible_­v<const U2&, > is false.
template <class U1, class U2> EXPLICIT constexpr tuple(pair<U1, U2>&& u);
Effects: Initializes the first element with std​::​forward<U1>(u.first) and the second element with std​::​forward<U2>(u.second).
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2, is_­constructible_­v<, U1&&> is true and is_­constructible_­v<, U2&&> is true.
The constructor is explicit if and only if is_­convertible_­v<U1&&, > is false or is_­convertible_­v<U2&&, > is false.
template <class Alloc> tuple(allocator_arg_t, const Alloc& a); template <class Alloc> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, const tuple&); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, tuple&&); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&); template <class Alloc, class... UTypes> EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&); template <class Alloc, class U1, class U2> EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template <class Alloc, class U1, class U2> EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
Requires: Alloc shall meet the requirements for an Allocator ([allocator.requirements]).
Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction ([allocator.uses.construction]).

23.5.3.2 Assignment [tuple.assign]

For each tuple assignment operator, an exception is thrown only if the assignment of one of the types in Types throws an exception.
In the function descriptions that follow, let i be in the range [0, sizeof...​(Types)) in order, be the type in Types, and be the type in a template parameter pack named UTypes, where indexing is zero-based.
tuple& operator=(const tuple& u);
Effects: Assigns each element of u to the corresponding element of *this.
Remarks: This operator shall be defined as deleted unless is_­copy_­assignable_­v<> is true for all i.
Returns: *this.
tuple& operator=(tuple&& u) noexcept(see below);
Effects: For all i, assigns std​::​forward<>(get<i>(u)) to get<i>(*this).
Remarks: This operator shall be defined as deleted unless is_­move_­assignable_­v<> is true for all i.
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_move_assignable_v<>
where is the type in Types.
Returns: *this.
template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);
Effects: Assigns each element of u to the corresponding element of *this.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == sizeof...(UTypes) and is_­assignable_­v<&, const &> is true for all i.
Returns: *this.
template <class... UTypes> tuple& operator=(tuple<UTypes...>&& u);
Effects: For all i, assigns std​::​forward<>(get<i>(u)) to get<i>(*this).
Remarks: This operator shall not participate in overload resolution unless is_­assignable_­v<&, &&> == true for all i and sizeof...(Types) == sizeof...(UTypes).
Returns: *this.
template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u);
Effects: Assigns u.first to the first element of *this and u.second to the second element of *this.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2 and is_­assignable_­v<&, const U1&> is true for the first type in Types and is_­assignable_­v<&, const U2&> is true for the second type in Types.
Returns: *this.
template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u);
Effects: Assigns std​::​forward<U1>(u.first) to the first element of *this and
std​::​forward<U2>(u.second) to the second element of *this.
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2 and is_­assignable_­v<&, U1&&> is true for the first type in Types and is_­assignable_­v<&, U2&&> is true for the second type in Types.
Returns: *this.

23.5.3.3 swap [tuple.swap]

void swap(tuple& rhs) noexcept(see below);
Requires: Each element in *this shall be swappable with ([swappable.requirements]) the corresponding element in rhs.
Effects: Calls swap for each element in *this and its corresponding element in rhs.
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_swappable_v<>
where is the type in Types.
Throws: Nothing unless one of the element-wise swap calls throws an exception.

23.5.3.4 Tuple creation functions [tuple.creation]

In the function descriptions that follow, the members of a parameter pack XTypes are denoted by X for i in [0, sizeof...(XTypes)) in order, where indexing is zero-based.
template<class... TTypes> constexpr tuple<VTypes...> make_tuple(TTypes&&... t);
The pack VTypes is defined as follows.
Let U be decay_­t<T> for each T in TTypes.
If U is a specialization of reference_­wrapper, then V in VTypes is U​::​type&, otherwise V is U.
Returns: tuple<VTypes...>(std​::​forward<TTypes>(t)...).
[Example
:
int i; float j;
make_tuple(1, ref(i), cref(j))
creates a tuple of type tuple<int, int&, const float&>.
end example
]
template<class... TTypes> constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&... t) noexcept;
Effects: Constructs a tuple of references to the arguments in t suitable for forwarding as arguments to a function.
Because the result may contain references to temporary variables, a program shall ensure that the return value of this function does not outlive any of its arguments (e.g., the program should typically not store the result in a named variable).
Returns: tuple<TTypes&&...>(std​::​forward<TTypes>(t)...).
template<class... TTypes> constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
Returns: tuple<TTypes&...>(t...).
When an argument in t is ignore, assigning any value to the corresponding tuple element has no effect.
[Example
:
tie functions allow one to create tuples that unpack tuples into variables.
ignore can be used for elements that are not needed:
int i; std::string s;
tie(i, ignore, s) = make_tuple(42, 3.14, "C++");
// i == 42, s == "C++"
end example
]
template <class... Tuples> constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
In the following paragraphs, let be the type in Tuples, be remove_­reference_­t<T>, and be the parameter in the function parameter pack tpls, where all indexing is zero-based.
Requires: For all i, shall be the type tuple<...>, where is the (possibly empty) cv-qualifier-seq and is the parameter pack representing the element types in .
Let be the type in .
For all the following requirements shall be satisfied:
  • If is deduced as an lvalue reference type, then is_­constructible_­v<, &> == true, otherwise
  • is_­constructible_­v<, &&> == true.
Remarks: The types in CTypes shall be equal to the ordered sequence of the extended types ..., ..., , ..., where n is equal to sizeof...(Tuples).
Let ... be the ordered sequence of tuple elements of the resulting tuple object corresponding to the type sequence .
Returns: A tuple object constructed by initializing the type element in ... with
get<>(std::forward<>())
for each valid and each group in order.
[Note
:
An implementation may support additional types in the parameter pack Tuples that support the tuple-like protocol, such as pair and array.
end note
]

23.5.3.5 Calling a function with a tuple of arguments [tuple.apply]

template <class F, class Tuple> constexpr decltype(auto) apply(F&& f, Tuple&& t);
Effects: Given the exposition-only function:
template <class F, class Tuple, size_t... I>
constexpr decltype(auto)
    apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {                // exposition only
  return INVOKE(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
Equivalent to:
return apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
                  make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
template <class T, class Tuple> constexpr T make_from_tuple(Tuple&& t);
Effects: Given the exposition-only function:
template <class T, class Tuple, size_t... I>
constexpr T make_from_tuple_impl(Tuple&& t, index_sequence<I...>) {     // exposition only
  return T(get<I>(std::forward<Tuple>(t))...);
}
Equivalent to:
return make_from_tuple_impl<T>(forward<Tuple>(t),
                               make_index_sequence<tuple_size_v<decay_t<Tuple>>>{});
[Note
:
The type of T must be supplied as an explicit template parameter, as it cannot be deduced from the argument list.
end note
]

23.5.3.6 Tuple helper classes [tuple.helper]

template <class T> struct tuple_size;
Remarks: All specializations of tuple_­size shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, N> for some N.
template <class... Types> class tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
template <size_t I, class... Types> class tuple_element<I, tuple<Types...>> { public: using type = TI; };
Requires: I < sizeof...(Types).
The program is ill-formed if I is out of bounds.
Type: TI is the type of the Ith element of Types, where indexing is zero-based.
template <class T> class tuple_size<const T>; template <class T> class tuple_size<volatile T>; template <class T> class tuple_size<const volatile T>;
Let TS denote tuple_­size<T> of the cv-unqualified type T.
If the expression TS​::​value is well-formed when treated as an unevaluated operand, then each of the three templates shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of
integral_constant<size_t, TS::value>
Otherwise, they shall have no member value.
Access checking is performed as if in a context unrelated to TS and T.
Only the validity of the immediate context of the expression is considered.
[Note
:
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
In addition to being available via inclusion of the <tuple> header, the three templates are available when either of the headers <array> or <utility> are included.
template <size_t I, class T> class tuple_element<I, const T>; template <size_t I, class T> class tuple_element<I, volatile T>; template <size_t I, class T> class tuple_element<I, const volatile T>;
Let TE denote tuple_­element_­t<I, T> of the cv-unqualified type T.
Then each of the three templates shall meet the TransformationTrait requirements ([meta.rqmts]) with a member typedef type that names the following type:
  • for the first specialization, add_­const_­t<TE>,
  • for the second specialization, add_­volatile_­t<TE>, and
  • for the third specialization, add_­cv_­t<TE>.
In addition to being available via inclusion of the <tuple> header, the three templates are available when either of the headers <array> or <utility> are included.

23.5.3.7 Element access [tuple.elem]

template <size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>& t) noexcept; template <size_t I, class... Types> constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&& t) noexcept; // Note A template <size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>& t) noexcept; // Note B template <size_t I, class... Types> constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
Requires: I < sizeof...(Types).
The program is ill-formed if I is out of bounds.
Returns: A reference to the Ith element of t, where indexing is zero-based.
[Note
:
[Note A] If a T in Types is some reference type X&, the return type is X&, not X&&.
However, if the element type is a non-reference type T, the return type is T&&.
end note
]
[Note
:
[Note B] Constness is shallow.
If a T in Types is some reference type X&, the return type is X&, not const X&.
However, if the element type is a non-reference type T, the return type is const T&.
This is consistent with how constness is defined to work for member variables of reference type.
end note
]
template <class T, class... Types> constexpr T& get(tuple<Types...>& t) noexcept; template <class T, class... Types> constexpr T&& get(tuple<Types...>&& t) noexcept; template <class T, class... Types> constexpr const T& get(const tuple<Types...>& t) noexcept; template <class T, class... Types> constexpr const T&& get(const tuple<Types...>&& t) noexcept;
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Returns: A reference to the element of t corresponding to the type T in Types....
[Example
:
  const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6);
  const int& i1 = get<int>(t);        // OK. Not ambiguous. i1 == 1
  const int& i2 = get<const int>(t);  // OK. Not ambiguous. i2 == 2
  const double& d = get<double>(t);   // ERROR. ill-formed
end example
]
[Note
:
The reason get is a non-member function is that if this functionality had been provided as a member function, code where the type depended on a template parameter would have required using the template keyword.
end note
]

23.5.3.8 Relational operators [tuple.rel]

template<class... TTypes, class... UTypes> constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Requires: For all i, where 0 <= i and i < sizeof...(TTypes), get<i>(t) == get<i>(u) is a valid expression returning a type that is convertible to bool.
sizeof...(TTypes) == sizeof...(UTypes).
Returns: true if get<i>(t) == get<i>(u) for all i, otherwise false.
For any two zero-length tuples e and f, e == f returns true.
Effects: The elementary comparisons are performed in order from the zeroth index upwards.
No comparisons or element accesses are performed after the first equality comparison that evaluates to false.
template<class... TTypes, class... UTypes> constexpr bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Requires: For all i, where 0 <= i and i < sizeof...(TTypes), both get<i>(t) < get<i>(u) and get<i>(u) < get<i>(t) are valid expressions returning types that are convertible to bool.
sizeof...(TTypes) == sizeof...(UTypes).
Returns: The result of a lexicographical comparison between t and u.
The result is defined as: (bool)(get<0>(t) < get<0>(u)) || (!(bool)(get<0>(u) < get<0>(t)) && t < u), where r for some tuple r is a tuple containing all but the first element of r.
For any two zero-length tuples e and f, e < f returns false.
template<class... TTypes, class... UTypes> constexpr bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: !(t == u).
template<class... TTypes, class... UTypes> constexpr bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: u < t.
template<class... TTypes, class... UTypes> constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: !(u < t).
template<class... TTypes, class... UTypes> constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
Returns: !(t < u).
[Note
:
The above definitions for comparison functions do not require t (or u) to be constructed.
It may not even be possible, as t and u are not required to be copy constructible.
Also, all comparison functions are short circuited; they do not perform element accesses beyond what is required to determine the result of the comparison.
end note
]

23.5.3.9 Tuple traits [tuple.traits]

template <class... Types, class Alloc> struct uses_allocator<tuple<Types...>, Alloc> : true_type { };
Requires: Alloc shall be an Allocator ([allocator.requirements]).
[Note
:
Specialization of this trait informs other library components that tuple can be constructed with an allocator, even though it does not have a nested allocator_­type.
end note
]

23.5.3.10 Tuple specialized algorithms [tuple.special]

template <class... Types> void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<> is true for all i, where .
The expression inside noexcept is equivalent to:
noexcept(x.swap(y))
Effects: As if by x.swap(y).

23.6 Optional objects [optional]

23.6.1 In general [optional.general]

This subclause describes class template optional that represents optional objects.
An optional object is an object that contains the storage for another object and manages the lifetime of this contained object, if any.
The contained object may be initialized after the optional object has been initialized, and may be destroyed before the optional object has been destroyed.
The initialization state of the contained object is tracked by the optional object.

23.6.2 Header <optional> synopsis [optional.syn]

namespace std {
  // [optional.optional], class template optional
  template <class T>
    class optional;

  // [optional.nullopt], no-value state indicator
  struct nullopt_t{see below};
  inline constexpr nullopt_t nullopt(unspecified);

  // [optional.bad.access], class bad_­optional_­access
  class bad_optional_access;

  // [optional.relops], relational operators
  template <class T, class U>
  constexpr bool operator==(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator!=(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator<(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator>(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator<=(const optional<T>&, const optional<U>&);
  template <class T, class U>
  constexpr bool operator>=(const optional<T>&, const optional<U>&);

  // [optional.nullops], comparison with nullopt
  template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
  template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
  template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;

  // [optional.comp_with_t], comparison with T
  template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator==(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator!=(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator<(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator<=(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator>(const U&, const optional<T>&);
  template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
  template <class T, class U> constexpr bool operator>=(const U&, const optional<T>&);

  // [optional.specalg], specialized algorithms
  template <class T>
    void swap(optional<T>&, optional<T>&) noexcept(see below);

  template <class T>
    constexpr optional<see below> make_optional(T&&);
  template <class T, class... Args>
    constexpr optional<T> make_optional(Args&&... args);
  template <class T, class U, class... Args>
    constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);

  // [optional.hash], hash support
  template <class T> struct hash;
  template <class T> struct hash<optional<T>>;
}
A program that necessitates the instantiation of template optional for a reference type, or for possibly cv-qualified types in_­place_­t or nullopt_­t is ill-formed.

23.6.3 Class template optional [optional.optional]

template <class T>
  class optional {
  public:
    using value_type = T;

    // [optional.ctor], constructors
    constexpr optional() noexcept;
    constexpr optional(nullopt_t) noexcept;
    constexpr optional(const optional&);
    constexpr optional(optional&&) noexcept(see below);
    template <class... Args>
      constexpr explicit optional(in_place_t, Args&&...);
    template <class U, class... Args>
      constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
    template <class U = T>
      EXPLICIT constexpr optional(U&&);
    template <class U>
      EXPLICIT optional(const optional<U>&);
    template <class U>
      EXPLICIT optional(optional<U>&&);

    // [optional.dtor], destructor
    ~optional();

    // [optional.assign], assignment
    optional& operator=(nullopt_t) noexcept;
    optional& operator=(const optional&);
    optional& operator=(optional&&) noexcept(see below);
    template <class U = T> optional& operator=(U&&);
    template <class U> optional& operator=(const optional<U>&);
    template <class U> optional& operator=(optional<U>&&);
    template <class... Args> T& emplace(Args&&...);
    template <class U, class... Args> T& emplace(initializer_list<U>, Args&&...);

    // [optional.swap], swap
    void swap(optional&) noexcept(see below);

    // [optional.observe], observers
    constexpr const T* operator->() const;
    constexpr T* operator->();
    constexpr const T& operator*() const&;
    constexpr T& operator*() &;
    constexpr T&& operator*() &&;
    constexpr const T&& operator*() const&&;
    constexpr explicit operator bool() const noexcept;
    constexpr bool has_value() const noexcept;
    constexpr const T& value() const&;
    constexpr T& value() &;
    constexpr T&& value() &&;
    constexpr const T&& value() const&&;
    template <class U> constexpr T value_or(U&&) const&;
    template <class U> constexpr T value_or(U&&) &&;

    // [optional.mod], modifiers
    void reset() noexcept;

  private:
    T *val; // exposition only
  };

template<class T> optional(T) -> optional<T>;
Any instance of optional<T> at any given time either contains a value or does not contain a value.
When an instance of optional<T> contains a value, it means that an object of type T, referred to as the optional object's contained value, is allocated within the storage of the optional object.
Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value.
The contained value shall be allocated in a region of the optional<T> storage suitably aligned for the type T.
When an object of type optional<T> is contextually converted to bool, the conversion returns true if the object contains a value; otherwise the conversion returns false.
Member val is provided for exposition only.
When an optional<T> object contains a value, val points to the contained value.
T shall be an object type and shall satisfy the requirements of Destructible (Table 27).

23.6.3.1 Constructors [optional.ctor]

constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept;
Postconditions: *this does not contain a value.
Remarks: No contained value is initialized.
For every object type T these constructors shall be constexpr constructors ([dcl.constexpr]).
constexpr optional(const optional& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression *rhs.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall be defined as deleted unless is_­copy_­constructible_­v<T> is true.
If is_­trivially_­copy_­constructible_­v<T> is true, this constructor shall be a constexpr constructor.
constexpr optional(optional&& rhs) noexcept(see below);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression std​::​move(*rhs).
bool(rhs) is unchanged.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: The expression inside noexcept is equivalent to is_­nothrow_­move_­constructible_­v<T>.
This constructor shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true.
If is_­trivially_­move_­constructible_­v<T> is true, this constructor shall be a constexpr constructor.
template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If T's constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor.
This constructor shall not participate in overload resolution unless is_­constructible_­v<T, Args...> is true.
template <class U, class... Args> constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<T, initializer_­list<U>&, Args&&...> is true.
If T's constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor.
[Note
:
The following constructors are conditionally specified as explicit.
This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution.
end note
]
template <class U = T> EXPLICIT constexpr optional(U&& v);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the expression std​::​forward<U>(v).
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
This constructor shall not participate in overload resolution unless is_­constructible_­v<T, U&&> is true, is_­same_­v<decay_­t<U>, in_­place_­t> is false, and is_­same_­v<optional<T>, decay_­t<U>> is false.
The constructor is explicit if and only if is_­convertible_­v<U&&, T> is false.
template <class U> EXPLICIT optional(const optional<U>& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression *rhs.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall not participate in overload resolution unless
  • is_­constructible_­v<T, const U&> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false, and
  • is_­convertible_­v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_­convertible_­v<const U&, T> is false.
template <class U> EXPLICIT optional(optional<U>&& rhs);
Effects: If rhs contains a value, initializes the contained value as if direct-non-list-initializing an object of type T with the expression std​::​move(*rhs).
bool(rhs) is unchanged.
Postconditions: bool(rhs) == bool(*this).
Throws: Any exception thrown by the selected constructor of T.
Remarks: This constructor shall not participate in overload resolution unless
  • is_­constructible_­v<T, U&&> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false, and
  • is_­convertible_­v<const optional<U>&&, T> is false.
The constructor is explicit if and only if is_­convertible_­v<U&&, T> is false.

23.6.3.2 Destructor [optional.dtor]

~optional();
Effects: If is_­trivially_­destructible_­v<T> != true and *this contains a value, calls
val->T::~T()
Remarks: If is_­trivially_­destructible_­v<T> == true then this destructor shall be a trivial destructor.

23.6.3.3 Assignment [optional.assign]

optional<T>& operator=(nullopt_t) noexcept;
Effects: If *this contains a value, calls val->T​::​~T() to destroy the contained value; otherwise no effect.
Returns: *this.
Postconditions: *this does not contain a value.
optional<T>& operator=(const optional& rhs);
Effects: See Table [tab:optional.assign.copy].
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns *rhs to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with *rhs
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's copy constructor, no effect.
If an exception is thrown during the call to T's copy assignment, the state of its contained value is as defined by the exception safety guarantee of T's copy assignment.
This operator shall be defined as deleted unless is_­copy_­constructible_­v<T> is true and is_­copy_­assignable_­v<T> is true.
optional<T>& operator=(optional&& rhs) noexcept(see below);
Effects: See Table [tab:optional.assign.move].
The result of the expression bool(rhs) remains unchanged.
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns std​::​move(*rhs) to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with std​::​move(*rhs)
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's move constructor, the state of *rhs.val is determined by the exception safety guarantee of T's move constructor.
If an exception is thrown during the call to T's move assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's move assignment.
This operator shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true and is_­move_­assignable_­v<T> is true.
template <class U = T> optional<T>& operator=(U&& v);
Effects: If *this contains a value, assigns std​::​forward<U>(v) to the contained value; otherwise initializes the contained value as if direct-non-list-initializing object of type T with std​::​forward<U>(v).
Returns: *this.
Postconditions: *this contains a value.
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's constructor, the state of v is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the state of *val and v is determined by the exception safety guarantee of T's assignment.
This function shall not participate in overload resolution unless is_­same_­v<optional<T>, decay_­t<U>> is false, conjunction_­v<is_­scalar<T>, is_­same<T, decay_­t<U>>> is false, is_­constructible_­v<T, U> is true, and is_­assignable_­v<T&, U> is true.
template <class U> optional<T>& operator=(const optional<U>& rhs);
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns *rhs to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with *rhs
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's constructor, the state of *rhs.val is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment.
This function shall not participate in overload resolution unless
  • is_­constructible_­v<T, const U&> is true,
  • is_­assignable_­v<T&, const U&> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false,
  • is_­convertible_­v<const optional<U>&&, T> is false,
  • is_­assignable_­v<T&, optional<U>&> is false,
  • is_­assignable_­v<T&, optional<U>&&> is false,
  • is_­assignable_­v<T&, const optional<U>&> is false, and
  • is_­assignable_­v<T&, const optional<U>&&> is false.
template <class U> optional<T>& operator=(optional<U>&& rhs);
The result of the expression bool(rhs) remains unchanged.
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & assigns std​::​move(*rhs) to the contained value & initializes the contained value as if direct-non-list-initializing an object of type T with std​::​move(*rhs)
rhs does not contain a value& & destroys the contained value by calling val->T​::​~T() & no effect
Returns: *this.
Postconditions: bool(rhs) == bool(*this).
Remarks: If any exception is thrown, the result of the expression bool(*this) remains unchanged.
If an exception is thrown during the call to T's constructor, the state of *rhs.val is determined by the exception safety guarantee of T's constructor.
If an exception is thrown during the call to T's assignment, the state of *val and *rhs.val is determined by the exception safety guarantee of T's assignment.
This function shall not participate in overload resolution unless
  • is_­constructible_­v<T, U> is true,
  • is_­assignable_­v<T&, U> is true,
  • is_­constructible_­v<T, optional<U>&> is false,
  • is_­constructible_­v<T, optional<U>&&> is false,
  • is_­constructible_­v<T, const optional<U>&> is false,
  • is_­constructible_­v<T, const optional<U>&&> is false,
  • is_­convertible_­v<optional<U>&, T> is false,
  • is_­convertible_­v<optional<U>&&, T> is false,
  • is_­convertible_­v<const optional<U>&, T> is false,
  • is_­convertible_­v<const optional<U>&&, T> is false,
  • is_­assignable_­v<T&, optional<U>&> is false,
  • is_­assignable_­v<T&, optional<U>&&> is false,
  • is_­assignable_­v<T&, const optional<U>&> is false, and
  • is_­assignable_­v<T&, const optional<U>&&> is false.
template <class... Args> T& emplace(Args&&... args);
Requires: is_­constructible_­v<T, Args&&...> is true.
Effects: Calls *this = nullopt.
Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed.
template <class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Effects: Calls *this = nullopt.
Then initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of T.
Remarks: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed.
This function shall not participate in overload resolution unless is_­constructible_­v<T, initializer_­list<U>&, Args&&...> is true.

23.6.3.4 Swap [optional.swap]

void swap(optional& rhs) noexcept(see below);
Requires: Lvalues of type T shall be swappable and is_­move_­constructible_­v<T> is true.
Effects: See Table [tab:optional.swap].
[htbp]
&&*this contains a value&*this does not contain a value
rhs contains a value& & calls swap(*(*this), *rhs) & initializes the contained value of *this as if direct-non-list-initializing an object of type T with the expression std​::​move(*rhs), followed by rhs.val->T​::​~T(); postcondition is that *this contains a value and rhs does not contain a value
rhs does not contain a value& & initializes the contained value of rhs as if direct-non-list-initializing an object of type T with the expression std​::​move(*(*this)), followed by val->T​::​~T(); postcondition is that *this does not contain a value and rhs contains a value & no effect
Throws: Any exceptions thrown by the operations in the relevant part of Table [tab:optional.swap].
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
If any exception is thrown, the results of the expressions bool(*this) and bool(rhs) remain unchanged.
If an exception is thrown during the call to function swap, the state of *val and *rhs.val is determined by the exception safety guarantee of swap for lvalues of T.
If an exception is thrown during the call to T's move constructor, the state of *val and *rhs.val is determined by the exception safety guarantee of T's move constructor.

23.6.3.5 Observers [optional.observe]

constexpr const T* operator->() const; constexpr T* operator->();
Requires: *this contains a value.
Returns: val.
Throws: Nothing.
Remarks: These functions shall be constexpr functions.
constexpr const T& operator*() const&; constexpr T& operator*() &;
Requires: *this contains a value.
Returns: *val.
Throws: Nothing.
Remarks: These functions shall be constexpr functions.
constexpr T&& operator*() &&; constexpr const T&& operator*() const&&;
Requires: *this contains a value.
Effects: Equivalent to: return std​::​move(*val);
constexpr explicit operator bool() const noexcept;
Returns: true if and only if *this contains a value.
Remarks: This function shall be a constexpr function.
constexpr bool has_value() const noexcept;
Returns: true if and only if *this contains a value.
Remarks: This function shall be a constexpr function.
constexpr const T& value() const&; constexpr T& value() &;
Effects: Equivalent to:
return bool(*this) ? *val : throw bad_optional_access();
constexpr T&& value() &&; constexpr const T&& value() const&&;
Effects: Equivalent to:
return bool(*this) ? std::move(*val) : throw bad_optional_access();
template <class U> constexpr T value_or(U&& v) const&;
Effects: Equivalent to:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
Remarks: If is_­copy_­constructible_­v<T> && is_­convertible_­v<U&&, T> is false, the program is ill-formed.
template <class U> constexpr T value_or(U&& v) &&;
Effects: Equivalent to:
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
Remarks: If is_­move_­constructible_­v<T> && is_­convertible_­v<U&&, T> is false, the program is ill-formed.

23.6.3.6 Modifiers [optional.mod]

void reset() noexcept;
Effects: If *this contains a value, calls val->T​::​~T() to destroy the contained value; otherwise no effect.
Postconditions: *this does not contain a value.

23.6.4 No-value state indicator [optional.nullopt]

struct nullopt_t{see below}; inline constexpr nullopt_t nullopt(unspecified);
The struct nullopt_­t is an empty structure type used as a unique type to indicate the state of not containing a value for optional objects.
In particular, optional<T> has a constructor with nullopt_­t as a single argument; this indicates that an optional object not containing a value shall be constructed.
Type nullopt_­t shall not have a default constructor or an initializer-list constructor, and shall not be an aggregate.

23.6.5 Class bad_­optional_­access [optional.bad.access]

class bad_optional_access : public exception {
public:
  bad_optional_access();
};
The class bad_­optional_­access defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an optional object that does not contain a value.
bad_optional_access();
Effects: Constructs an object of class bad_­optional_­access.
Postconditions: what() returns an implementation-defined ntbs.

23.6.6 Relational operators [optional.relops]

template <class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
Requires: The expression *x == *y shall be well-formed and its result shall be convertible to bool.
[Note
:
T need not be EqualityComparable.
end note
]
Returns: If bool(x) != bool(y), false; otherwise if bool(x) == false, true; otherwise *x == *y.
Remarks: Specializations of this function template for which *x == *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x != *y shall be well-formed and its result shall be convertible to bool.
Returns: If bool(x) != bool(y), true; otherwise, if bool(x) == false, false; otherwise *x != *y.
Remarks: Specializations of this function template for which *x != *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
Requires: *x < *y shall be well-formed and its result shall be convertible to bool.
Returns: If !y, false; otherwise, if !x, true; otherwise *x < *y.
Remarks: Specializations of this function template for which *x < *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
Requires: The expression *x > *y shall be well-formed and its result shall be convertible to bool.
Returns: If !x, false; otherwise, if !y, true; otherwise *x > *y.
Remarks: Specializations of this function template for which *x > *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x <= *y shall be well-formed and its result shall be convertible to bool.
Returns: If !x, true; otherwise, if !y, false; otherwise *x <= *y.
Remarks: Specializations of this function template for which *x <= *y is a core constant expression shall be constexpr functions.
template <class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
Requires: The expression *x >= *y shall be well-formed and its result shall be convertible to bool.
Returns: If !y, true; otherwise, if !x, false; otherwise *x >= *y.
Remarks: Specializations of this function template for which *x >= *y is a core constant expression shall be constexpr functions.

23.6.7 Comparison with nullopt [optional.nullops]

template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept; template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept;
Returns: !x.
template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept; template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept;
Returns: bool(x).
template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
Returns: false.
template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
Returns: bool(x).
template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept;
Returns: !x.
template <class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept;
Returns: true.
template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept;
Returns: bool(x).
template <class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept;
Returns: false.
template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept;
Returns: true.
template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept;
Returns: !x.

23.6.8 Comparison with T [optional.comp_with_t]

template <class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
Requires: The expression *x == v shall be well-formed and its result shall be convertible to bool.
[Note
:
T need not be EqualityComparable.
end note
]
Effects: Equivalent to: return bool(x) ? *x == v : false;
template <class T, class U> constexpr bool operator==(const U& v, const optional<T>& x);
Requires: The expression v == *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v == *x : false;
template <class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
Requires: The expression *x != v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x != v : true;
template <class T, class U> constexpr bool operator!=(const U& v, const optional<T>& x);
Requires: The expression v != *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v != *x : true;
template <class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
Requires: The expression *x < v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x < v : true;
template <class T, class U> constexpr bool operator<(const U& v, const optional<T>& x);
Requires: The expression v < *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v < *x : false;
template <class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
Requires: The expression *x <= v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x <= v : true;
template <class T, class U> constexpr bool operator<=(const U& v, const optional<T>& x);
Requires: The expression v <= *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v <= *x : false;
template <class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
Requires: The expression *x > v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x > v : false;
template <class T, class U> constexpr bool operator>(const U& v, const optional<T>& x);
Requires: The expression v > *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v > *x : true;
template <class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
Requires: The expression *x >= v shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? *x >= v : false;
template <class T, class U> constexpr bool operator>=(const U& v, const optional<T>& x);
Requires: The expression v >= *x shall be well-formed and its result shall be convertible to bool.
Effects: Equivalent to: return bool(x) ? v >= *x : true;

23.6.9 Specialized algorithms [optional.specalg]

template <class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
Effects: Calls x.swap(y).
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<T> is true and is_­swappable_­v<T> is true.
template <class T> constexpr optional<decay_t<T>> make_optional(T&& v);
Returns: optional<decay_­t<T>>(std​::​forward<T>(v)).
template <class T, class...Args> constexpr optional<T> make_optional(Args&&... args);
Effects: Equivalent to: return optional<T>(in_­place, std​::​forward<Args>(args)...);
template <class T, class U, class... Args> constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
Effects: Equivalent to: return optional<T>(in_­place, il, std​::​forward<Args>(args)...);

23.6.10 Hash support [optional.hash]

template <class T> struct hash<optional<T>>;
The specialization hash<optional<T>> is enabled ([unord.hash]) if and only if hash<remove_­const_­t<T>> is enabled.
When enabled, for an object o of type optional<T>, if bool(o) == true, then hash<optional<T>>()(o) shall evaluate to the same value as hash<remove_­const_­t<T>>()(*o); otherwise it evaluates to an unspecified value.
The member functions are not guaranteed to be noexcept.

23.7 Variants [variant]

23.7.1 In general [variant.general]

A variant object holds and manages the lifetime of a value.
If the variant holds a value, that value's type has to be one of the template argument types given to variant.
These template arguments are called alternatives.

23.7.2 Header <variant> synopsis [variant.syn]

namespace std {
  // [variant.variant], class template variant
  template <class... Types>
    class variant;

  // [variant.helper], variant helper classes
  template <class T> struct variant_size;                   // not defined
  template <class T> struct variant_size<const T>;
  template <class T> struct variant_size<volatile T>;
  template <class T> struct variant_size<const volatile T>;
  template <class T>
    inline constexpr size_t variant_size_v = variant_size<T>::value;

  template <class... Types>
    struct variant_size<variant<Types...>>;

  template <size_t I, class T> struct variant_alternative;  // not defined
  template <size_t I, class T> struct variant_alternative<I, const T>;
  template <size_t I, class T> struct variant_alternative<I, volatile T>;
  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
  template <size_t I, class T>
    using variant_alternative_t = typename variant_alternative<I, T>::type;

  template <size_t I, class... Types>
    struct variant_alternative<I, variant<Types...>>;

  inline constexpr size_t variant_npos = -1;

  // [variant.get], value access
  template <class T, class... Types>
    constexpr bool holds_alternative(const variant<Types...>&) noexcept;

  template <size_t I, class... Types>
    constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&);
  template <size_t I, class... Types>
    constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&);
  template <size_t I, class... Types>
    constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&);
  template <size_t I, class... Types>
    constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&);

  template <class T, class... Types>
    constexpr T& get(variant<Types...>&);
  template <class T, class... Types>
    constexpr T&& get(variant<Types...>&&);
  template <class T, class... Types>
    constexpr const T& get(const variant<Types...>&);
  template <class T, class... Types>
    constexpr const T&& get(const variant<Types...>&&);

  template <size_t I, class... Types>
    constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
      get_if(variant<Types...>*) noexcept;
  template <size_t I, class... Types>
    constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
      get_if(const variant<Types...>*) noexcept;

  template <class T, class... Types>
    constexpr add_pointer_t<T>
      get_if(variant<Types...>*) noexcept;
  template <class T, class... Types>
    constexpr add_pointer_t<const T>
      get_if(const variant<Types...>*) noexcept;

  // [variant.relops], relational operators
  template <class... Types>
    constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
  template <class... Types>
    constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);

  // [variant.visit], visitation
  template <class Visitor, class... Variants>
    constexpr see below visit(Visitor&&, Variants&&...);

  // [variant.monostate], class monostate
  struct monostate;

  // [variant.monostate.relops], monostate relational operators
  constexpr bool operator<(monostate, monostate) noexcept;
  constexpr bool operator>(monostate, monostate) noexcept;
  constexpr bool operator<=(monostate, monostate) noexcept;
  constexpr bool operator>=(monostate, monostate) noexcept;
  constexpr bool operator==(monostate, monostate) noexcept;
  constexpr bool operator!=(monostate, monostate) noexcept;

  // [variant.specalg], specialized algorithms
  template <class... Types>
    void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);

  // [variant.bad.access], class bad_­variant_­access
  class bad_variant_access;

  // [variant.hash], hash support
  template <class T> struct hash;
  template <class... Types> struct hash<variant<Types...>>;
  template <> struct hash<monostate>;

  // [variant.traits], allocator-related traits
  template <class T, class Alloc> struct uses_allocator;
  template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc>;
}

23.7.3 Class template variant [variant.variant]

namespace std {
  template <class... Types>
    class variant {
    public:
      // [variant.ctor], constructors
      constexpr variant() noexcept(see below);
      variant(const variant&);
      variant(variant&&) noexcept(see below);

      template <class T>
        constexpr variant(T&&) noexcept(see below);

      template <class T, class... Args>
        constexpr explicit variant(in_place_type_t<T>, Args&&...);
      template <class T, class U, class... Args>
        constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...);

      template <size_t I, class... Args>
        constexpr explicit variant(in_place_index_t<I>, Args&&...);
      template <size_t I, class U, class... Args>
        constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);

      // allocator-extended constructors
      template <class Alloc>
        variant(allocator_arg_t, const Alloc&);
      template <class Alloc>
        variant(allocator_arg_t, const Alloc&, const variant&);
      template <class Alloc>
        variant(allocator_arg_t, const Alloc&, variant&&);
      template <class Alloc, class T>
        variant(allocator_arg_t, const Alloc&, T&&);
      template <class Alloc, class T, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_type_t<T>, Args&&...);
      template <class Alloc, class T, class U, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_type_t<T>,
                initializer_list<U>, Args&&...);
      template <class Alloc, size_t I, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_index_t<I>, Args&&...);
      template <class Alloc, size_t I, class U, class... Args>
        variant(allocator_arg_t, const Alloc&, in_place_index_t<I>,
                initializer_list<U>, Args&&...);

      // [variant.dtor], destructor
      ~variant();

      // [variant.assign], assignment
      variant& operator=(const variant&);
      variant& operator=(variant&&) noexcept(see below);

      template <class T> variant& operator=(T&&) noexcept(see below);

      // [variant.mod], modifiers
      template <class T, class... Args>
        T& emplace(Args&&...);
      template <class T, class U, class... Args>
        T& emplace(initializer_list<U>, Args&&...);
      template <size_t I, class... Args>
        variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
      template <size_t I, class U, class... Args>
        variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...);

      // [variant.status], value status
      constexpr bool valueless_by_exception() const noexcept;
      constexpr size_t index() const noexcept;

      // [variant.swap], swap
      void swap(variant&) noexcept(see below);
    };
}
Any instance of variant at any given time either holds a value of one of its alternative types, or it holds no value.
When an instance of variant holds a value of alternative type T, it means that a value of type T, referred to as the variant object's contained value, is allocated within the storage of the variant object.
Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value.
The contained value shall be allocated in a region of the variant storage suitably aligned for all types in Types....
It is implementation-defined whether over-aligned types are supported.
All types in Types... shall be (possibly cv-qualified) object types that are not arrays.
A program that instantiates the definition of variant with no template arguments is ill-formed.

23.7.3.1 Constructors [variant.ctor]

In the descriptions that follow, let i be in the range [0, sizeof...(Types)), and be the type in Types....
constexpr variant() noexcept(see below);
Effects: Constructs a variant holding a value-initialized value of type .
Postconditions: valueless_­by_­exception() is false and index() is 0.
Throws: Any exception thrown by the value-initialization of .
Remarks: This function shall be constexpr if and only if the value-initialization of the alternative type would satisfy the requirements for a constexpr function.
The expression inside noexcept is equivalent to is_­nothrow_­default_­constructible_­v<>.
This function shall not participate in overload resolution unless is_­default_­constructible_­v<> is true.
[Note
:
See also class monostate.
end note
]
variant(const variant& w);
Effects: If w holds a value, initializes the variant to hold the same alternative as w and direct-initializes the contained value with get<j>(w), where j is w.index().
Otherwise, initializes the variant to not hold a value.
Throws: Any exception thrown by direct-initializing any for all i.
Remarks: This function shall not participate in overload resolution unless is_­copy_­constructible_­v<> is true for all i.
variant(variant&& w) noexcept(see below);
Effects: If w holds a value, initializes the variant to hold the same alternative as w and direct-initializes the contained value with get<j>(std​::​move(w)), where j is w.index().
Otherwise, initializes the variant to not hold a value.
Throws: Any exception thrown by move-constructing any for all i.
Remarks: The expression inside noexcept is equivalent to the logical AND of is_­nothrow_­move_­constructible_­v<> for all i.
This function shall not participate in overload resolution unless is_­move_­constructible_­v<> is true for all i.
template <class T> constexpr variant(T&& t) noexcept(see below);
Let be a type that is determined as follows: build an imaginary function FUN() for each alternative type .
The overload FUN() selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative which is the type of the contained value after construction.
Effects: Initializes *this to hold the alternative type and direct-initializes the contained value as if direct-non-list-initializing it with std​::​forward<T>(t).
Postconditions: holds_­alternative<>(*this) is true.
Throws: Any exception thrown by the initialization of the selected alternative .
Remarks: This function shall not participate in overload resolution unless is_­same_­v<decay_­t<T>, variant> is false, unless decay_­t<T> is neither a specialization of in_­place_­type_­t nor a specialization of in_­place_­index_­t, unless is_­constructible_­v<, T> is true, and unless the expression FUN(std​::​forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well formed.
[Note
:
variant<string, string> v("abc");
is ill-formed, as both alternative types have an equally viable constructor for the argument.
end note
]
The expression inside noexcept is equivalent to is_­nothrow_­constructible_­v<, T>.
If 's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments std​::​forward<Args>(args)....
Postconditions: holds_­alternative<T>(*this) is true.
Throws: Any exception thrown by calling the selected constructor of T.
Remarks: This function shall not participate in overload resolution unless there is exactly one occurrence of T in Types... and is_­constructible_­v<T, Args...> is true.
If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <class T, class U, class... Args> constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type T with the arguments il, std​::​forward<Args>(args)....
Postconditions: holds_­alternative<T>(*this) is true.
Throws: Any exception thrown by calling the selected constructor of T.
Remarks: This function shall not participate in overload resolution unless there is exactly one occurrence of T in Types... and is_­constructible_­v<T, initializer_­list<U>&, Args...> is true.
If T's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type with the arguments std​::​forward<Args>(args)....
Postconditions: index() is I.
Throws: Any exception thrown by calling the selected constructor of .
Remarks: This function shall not participate in overload resolution unless
  • I is less than sizeof...(Types) and
  • is_­constructible_­v<, Args...> is true.
If 's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
template <size_t I, class U, class... Args> constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
Effects: Initializes the contained value as if direct-non-list-initializing an object of type with the arguments il, std​::​forward<Args>(args)....
Postconditions: index() is I.
Remarks: This function shall not participate in overload resolution unless
  • I is less than sizeof...(Types) and
  • is_­constructible_­v<, initializer_­list<U>&, Args...> is true.
If 's selected constructor is a constexpr constructor, this constructor shall be a constexpr constructor.
// allocator-extended constructors template <class Alloc> variant(allocator_arg_t, const Alloc& a); template <class Alloc> variant(allocator_arg_t, const Alloc& a, const variant& v); template <class Alloc> variant(allocator_arg_t, const Alloc& a, variant&& v); template <class Alloc, class T> variant(allocator_arg_t, const Alloc& a, T&& t); template <class Alloc, class T, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, Args&&... args); template <class Alloc, class T, class U, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, initializer_list<U> il, Args&&... args); template <class Alloc, size_t I, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, Args&&... args); template <class Alloc, size_t I, class U, class... Args> variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, initializer_list<U> il, Args&&... args);
Requires: Alloc shall meet the requirements for an Allocator ([allocator.requirements]).
Effects: Equivalent to the preceding constructors except that the contained value is constructed with uses-allocator construction ([allocator.uses.construction]).

23.7.3.2 Destructor [variant.dtor]

~variant();
Effects: If valueless_­by_­exception() is false, destroys the currently contained value.
Remarks: If is_­trivially_­destructible_­v<> == true for all then this destructor shall be a trivial destructor.

23.7.3.3 Assignment [variant.assign]

variant& operator=(const variant& rhs);
Let j be rhs.index().
Effects:
  • If neither *this nor rhs holds a value, there is no effect.
    Otherwise,
  • if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
    Otherwise,
  • if index() == j, assigns the value contained in rhs to the value contained in *this.
    Otherwise,
  • if either is_­nothrow_­copy_­constructible_­v<> or !is_­nothrow_­move_­constructible_­v<> is true, equivalent to emplace<j>(get<j>(rhs)).
    Otherwise,
  • equivalent to operator=(variant(rhs)).
Returns: *this.
Postconditions: index() == rhs.index().
Remarks: This function shall not participate in overload resolution unless is_­copy_­constructible_­v<> && is_­copy_­assignable_­v<> is true for all i.
variant& operator=(variant&& rhs) noexcept(see below);
Let j be rhs.index().
Effects:
  • If neither *this nor rhs holds a value, there is no effect.
    Otherwise,
  • if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
    Otherwise,
  • if index() == j, assigns get<j>(std​::​move(rhs)) to the value contained in *this.
    Otherwise,
  • equivalent to emplace<j>(get<j>(std​::​move(rhs))).
Returns: *this.
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<> && is_­move_­assignable_­v<> is true for all i.
The expression inside noexcept is equivalent to: is_­nothrow_­move_­constructible_­v<> && is_­nothrow_­move_­assignable_­v<> for all i.
  • If an exception is thrown during the call to 's move construction (with j being rhs.index()), the variant will hold no value.
  • If an exception is thrown during the call to 's move assignment, the state of the contained value is as defined by the exception safety guarantee of 's move assignment; index() will be j.
template <class T> variant& operator=(T&& t) noexcept(see below);
Let be a type that is determined as follows: build an imaginary function FUN() for each alternative type .
The overload FUN() selected by overload resolution for the expression FUN(std​::​forward<T>(​t)) defines the alternative which is the type of the contained value after assignment.
Effects:
  • If *this holds a , assigns std​::​forward<T>(t) to the value contained in *this.
    Otherwise,
  • if is_­nothrow_­constructible_­v<, T> || !is_­nothrow_­move_­constructible_­v<> is true, equivalent to emplace<j>(std​::​forward<T>(t)).
    Otherwise,
  • equivalent to operator=(variant(std​::​forward<T>(t))).
Postconditions: holds_­alternative<>(*this) is true, with selected by the imaginary function overload resolution described above.
Returns: *this.
Remarks: This function shall not participate in overload resolution unless is_­same_­v<decay_­t<T>, variant> is false, unless is_­assignable_­v<&, T> && is_­constructible_­v<, T> is true, and unless the expression FUN(std​::​forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well formed.
[Note
:
variant<string, string> v;
v = "abc";
is ill-formed, as both alternative types have an equally viable constructor for the argument.
end note
]
The expression inside noexcept is equivalent to:
is_nothrow_assignable_v<T&, T> && is_nothrow_constructible_v<T, T>
  • If an exception is thrown during the assignment of std​::​forward<T>(t) to the value contained in *this, the state of the contained value and t are as defined by the exception safety guarantee of the assignment expression; valueless_­by_­exception() will be false.
  • If an exception is thrown during the initialization of the contained value, the variant object might not hold a value.

23.7.3.4 Modifiers [variant.mod]

template <class T, class... Args> T& emplace(Args&&... args);
Let I be the zero-based index of T in Types....
Effects: Equivalent to: return emplace<I>(std​::​forward<Args>(args)...);
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<T, Args...> is true, and T occurs exactly once in Types....
template <class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Let I be the zero-based index of T in Types....
Effects: Equivalent to: return emplace<I>(il, std​::​forward<Args>(args)...);
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<T, initializer_­list<U>&, Args...> is true, and T occurs exactly once in Types....
template <size_t I, class... Args> variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
Requires: I < sizeof...(Types).
Effects: Destroys the currently contained value if valueless_­by_­exception() is false.
Then initializes the contained value as if direct-non-list-initializing a value of type with the arguments std​::​forward<Args>(args)....
Postconditions: index() is I.
Returns: A reference to the new contained value.
Throws: Any exception thrown during the initialization of the contained value.
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<, Args...> is true.
If an exception is thrown during the initialization of the contained value, the variant might not hold a value.
template <size_t I, class U, class... Args> variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
Requires: I < sizeof...(Types).
Effects: Destroys the currently contained value if valueless_­by_­exception() is false.
Then initializes the contained value as if direct-non-list-initializing a value of type with the arguments il, std​::​forward<Args>(args)....
Postconditions: index() is I.
Returns: A reference to the new contained value.
Throws: Any exception thrown during the initialization of the contained value.
Remarks: This function shall not participate in overload resolution unless is_­constructible_­v<, initializer_­list<U>&, Args...> is true.
If an exception is thrown during the initialization of the contained value, the variant might not hold a value.

23.7.3.5 Value status [variant.status]

constexpr bool valueless_by_exception() const noexcept;
Effects: Returns false if and only if the variant holds a value.
[Note
:
A variant might not hold a value if an exception is thrown during a type-changing assignment or emplacement.
The latter means that even a variant<float, int> can become valueless_­by_­exception(), for instance by
struct S { operator int() { throw 42; }};
variant<float, int> v{12.f};
v.emplace<1>(S());
end note
]
constexpr size_t index() const noexcept;
Effects: If valueless_­by_­exception() is true, returns variant_­npos.
Otherwise, returns the zero-based index of the alternative of the contained value.

23.7.3.6 Swap [variant.swap]

void swap(variant& rhs) noexcept(see below);
Requires: Lvalues of type shall be swappable ([swappable.requirements]) and is_­move_­constructible_­v<> shall be true for all i.
Effects:
  • if valueless_­by_­exception() && rhs.valueless_­by_­exception() no effect.
    Otherwise,
  • if index() == rhs.index(), calls swap(get<i>(*this), get<i>(rhs)) where i is index().
    Otherwise,
  • exchanges values of rhs and *this.
Throws: If index() == rhs.index(), any exception thrown by swap(get<i>(*this), get<i>(rhs)) with i being index().
Otherwise, any exception thrown by the move constructor of or with i being index() and j being rhs.index().
Remarks: If an exception is thrown during the call to function swap(get<i>(*this), get<i>(rhs)), the states of the contained values of *this and of rhs are determined by the exception safety guarantee of swap for lvalues of with i being index().
If an exception is thrown during the exchange of the values of *this and rhs, the states of the values of *this and of rhs are determined by the exception safety guarantee of variant's move constructor.
The expression inside noexcept is equivalent to the logical AND of is_­nothrow_­move_­constructible_­v<> && is_­nothrow_­swappable_­v<> for all i.

23.7.4 variant helper classes [variant.helper]

template <class T> struct variant_size;
Remarks: All specializations of variant_­size shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, N> for some N.
template <class T> class variant_size<const T>; template <class T> class variant_size<volatile T>; template <class T> class variant_size<const volatile T>;
Let VS denote variant_­size<T> of the cv-unqualified type T.
Then each of the three templates shall meet the UnaryTypeTrait requirements ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, VS​::​value>.
template <class... Types> struct variant_size<variant<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
template <size_t I, class T> class variant_alternative<I, const T>; template <size_t I, class T> class variant_alternative<I, volatile T>; template <size_t I, class T> class variant_alternative<I, const volatile T>;
Let VA denote variant_­alternative<I, T> of the cv-unqualified type T.
Then each of the three templates shall meet the TransformationTrait requirements ([meta.rqmts]) with a member typedef type that names the following type:
  • for the first specialization, add_­const_­t<VA​::​type>,
  • for the second specialization, add_­volatile_­t<VA​::​type>, and
  • for the third specialization, add_­cv_­t<VA​::​type>.
variant_alternative<I, variant<Types...>>::type
Requires: I < sizeof...(Types).
Value: The type .

23.7.5 Value access [variant.get]

template <class T, class... Types> constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Returns: true if index() is equal to the zero-based index of T in Types....
template <size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>& v); template <size_t I, class... Types> constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&& v); template <size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>& v); template <size_t I, class... Types> constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&& v);
Requires: I < sizeof...(Types).
Otherwise the program is ill-formed.
Effects: If v.index() is I, returns a reference to the object stored in the variant.
Otherwise, throws an exception of type bad_­variant_­access.
template <class T, class... Types> constexpr T& get(variant<Types...>& v); template <class T, class... Types> constexpr T&& get(variant<Types...>&& v); template <class T, class... Types> constexpr const T& get(const variant<Types...>& v); template <class T, class... Types> constexpr const T&& get(const variant<Types...>&& v);
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Effects: If v holds a value of type T, returns a reference to that value.
Otherwise, throws an exception of type bad_­variant_­access.
template <size_t I, class... Types> constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> get_if(variant<Types...>* v) noexcept; template <size_t I, class... Types> constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> get_if(const variant<Types...>* v) noexcept;
Requires: I < sizeof...(Types).
Otherwise the program is ill-formed.
Returns: A pointer to the value stored in the variant, if v != nullptr and v->index() == I.
Otherwise, returns nullptr.
template <class T, class... Types> constexpr add_pointer_t<T> get_if(variant<Types...>* v) noexcept; template <class T, class... Types> constexpr add_pointer_t<const T> get_if(const variant<Types...>* v) noexcept;
Requires: The type T occurs exactly once in Types....
Otherwise, the program is ill-formed.
Effects: Equivalent to: return get_­if<i>(v); with i being the zero-based index of T in Types....

23.7.6 Relational operators [variant.relops]

template <class... Types> constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) == get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.index() != w.index(), false; otherwise if v.valueless_­by_­exception(), true; otherwise get<i>(v) == get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) != get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.index() != w.index(), true; otherwise if v.valueless_­by_­exception(), false; otherwise get<i>(v) != get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) < get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If w.valueless_­by_­exception(), false; otherwise if v.valueless_­by_­exception(), true; otherwise, if v.index() < w.index(), true; otherwise if v.index() > w.index(), false; otherwise get<i>(v) < get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) > get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.valueless_­by_­exception(), false; otherwise if w.valueless_­by_­exception(), true; otherwise, if v.index() > w.index(), true; otherwise if v.index() < w.index(), false; otherwise get<i>(v) > get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) <= get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If v.valueless_­by_­exception(), true; otherwise if w.valueless_­by_­exception(), false; otherwise, if v.index() < w.index(), true; otherwise if v.index() > w.index(), false; otherwise get<i>(v) <= get<i>(w) with i being v.index().
template <class... Types> constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
Requires: get<i>(v) >= get<i>(w) is a valid expression returning a type that is convertible to bool, for all i.
Returns: If w.valueless_­by_­exception(), true; otherwise if v.valueless_­by_­exception(), false; otherwise, if v.index() > w.index(), true; otherwise if v.index() < w.index(), false; otherwise get<i>(v) >= get<i>(w) with i being v.index().

23.7.7 Visitation [variant.visit]

template <class Visitor, class... Variants> constexpr see below visit(Visitor&& vis, Variants&&... vars);
Requires: The expression in the Effects: element shall be a valid expression of the same type and value category, for all combinations of alternative types of all variants.
Otherwise, the program is ill-formed.
Effects: Let is... be vars.index()....
Returns INVOKE(forward<Visitor>(vis), get<is>(forward<Variants>(vars))...);.
Remarks: The return type is the common type of all possible INVOKE expressions of the Effects: element.
Throws: bad_­variant_­access if any variant in vars is valueless_­by_­exception().
Complexity: For sizeof...(Variants) <= 1, the invocation of the callable object is implemented in constant time, i.e. it does not depend on sizeof...(Types). For sizeof...(Variants) > 1, the invocation of the callable object has no complexity requirements.

23.7.8 Class monostate [variant.monostate]

struct monostate{};
The class monostate can serve as a first alternative type for a variant to make the variant type default constructible.

23.7.9 monostate relational operators [variant.monostate.relops]

constexpr bool operator<(monostate, monostate) noexcept { return false; } constexpr bool operator>(monostate, monostate) noexcept { return false; } constexpr bool operator<=(monostate, monostate) noexcept { return true; } constexpr bool operator>=(monostate, monostate) noexcept { return true; } constexpr bool operator==(monostate, monostate) noexcept { return true; } constexpr bool operator!=(monostate, monostate) noexcept { return false; }
[Note
:
monostate objects have only a single state; they thus always compare equal.
end note
]

23.7.10 Specialized algorithms [variant.specalg]

template <class... Types> void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
Effects: Equivalent to v.swap(w).
Remarks: This function shall not participate in overload resolution unless is_­move_­constructible_­v<> && is_­swappable_­v<> is true for all i.
The expression inside noexcept is equivalent to noexcept(v.swap(w)).

23.7.11 Class bad_­variant_­access [variant.bad.access]

class bad_variant_access : public exception {
public:
  bad_variant_access() noexcept;
  const char* what() const noexcept override;
};
Objects of type bad_­variant_­access are thrown to report invalid accesses to the value of a variant object.
bad_variant_access() noexcept;
Constructs a bad_­variant_­access object.
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.

23.7.12 Hash support [variant.hash]

template <class... Types> struct hash<variant<Types...>>;
The specialization hash<variant<Types...>> is enabled ([unord.hash]) if and only if every specialization in hash<remove_­const_­t<Types>>... is enabled.
The member functions are not guaranteed to be noexcept.
template <> struct hash<monostate>;
The specialization is enabled ([unord.hash]).

23.7.13 Allocator-related traits [variant.traits]

template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc> : true_type { };
Requires: Alloc shall be an Allocator ([allocator.requirements]).
[Note
:
Specialization of this trait informs other library components that variant can be constructed with an allocator, even though it does not have a nested allocator_­type.
end note
]

23.8 Storage for any type [any]

This section describes components that C++ programs may use to perform operations on objects of a discriminated type.
[Note
:
The discriminated type may contain values of different types but does not attempt conversion between them, i.e. 5 is held strictly as an int and is not implicitly convertible either to "5" or to 5.0.
This indifference to interpretation but awareness of type effectively allows safe, generic containers of single values, with no scope for surprises from ambiguous conversions.
end note
]

23.8.1 Header <any> synopsis [any.synop]

namespace std {
  // [any.bad_any_cast], class bad_­any_­cast
  class bad_any_cast;

  // [any.class], class any
  class any;

  // [any.nonmembers], non-member functions
  void swap(any& x, any& y) noexcept;

  template <class T, class... Args>
    any make_any(Args&& ...args);
  template <class T, class U, class... Args>
    any make_any(initializer_list<U> il, Args&& ...args);

  template<class T>
    T any_cast(const any& operand);
  template<class T>
    T any_cast(any& operand);
  template<class T>
    T any_cast(any&& operand);

  template<class T>
    const T* any_cast(const any* operand) noexcept;
  template<class T>
    T* any_cast(any* operand) noexcept;
}

23.8.2 Class bad_­any_­cast [any.bad_any_cast]

class bad_any_cast : public bad_cast {
public:
  const char* what() const noexcept override;
};
Objects of type bad_­any_­cast are thrown by a failed any_­cast ([any.nonmembers]).
const char* what() const noexcept override;
Returns: An implementation-defined ntbs.
Remarks: The message may be a null-terminated multibyte string ([multibyte.strings]), suitable for conversion and display as a wstring ([string.classes], [locale.codecvt]).

23.8.3 Class any [any.class]

class any {
public:
  // [any.cons], construction and destruction
  constexpr any() noexcept;

  any(const any& other);
  any(any&& other) noexcept;

  template <class T> any(T&& value);

  template <class T, class... Args>
    explicit any(in_place_type_t<T>, Args&&...);
  template <class T, class U, class... Args>
    explicit any(in_place_type_t<T>, initializer_list<U>, Args&&...);

  ~any();

  // [any.assign], assignments
  any& operator=(const any& rhs);
  any& operator=(any&& rhs) noexcept;

  template <class T> any& operator=(T&& rhs);

  // [any.modifiers], modifiers
  template <class T, class... Args>
    decay_t<T>& emplace(Args&& ...);
  template <class T, class U, class... Args>
    decay_t<T>& emplace(initializer_list<U>, Args&&...);
  void reset() noexcept;
  void swap(any& rhs) noexcept;

  // [any.observers], observers
  bool has_value() const noexcept;
  const type_info& type() const noexcept;
};
An object of class any stores an instance of any type that satisfies the constructor requirements or it has no value, and this is referred to as the state of the class any object.
The stored instance is called the contained value, Two states are equivalent if either they both have no value, or both have a value and the contained values are equivalent.
The non-member any_­cast functions provide type-safe access to the contained value.
Implementations should avoid the use of dynamically allocated memory for a small contained value.
[Example
:
where the object constructed is holding only an int.
end example
]
Such small-object optimization shall only be applied to types T for which is_­nothrow_­move_­constructible_­v<T> is true.

23.8.3.1 Construction and destruction [any.cons]

constexpr any() noexcept;
Postconditions: has_­value() is false.
any(const any& other);
Effects: If other.has_­value() is false, constructs an object that has no value.
Otherwise, equivalent to any(in_­place<T>, any_­cast<const T&>(other)) where T is the type of the contained object.
Throws: Any exceptions arising from calling the selected constructor for the contained value.
any(any&& other) noexcept;
Effects: If other.has_­value() is false, constructs an object that has no value.
Otherwise, constructs an object of type any that contains either the contained object of other, or contains an object of the same type constructed from the contained object of other considering that contained object as an rvalue.
Postconditions: other is left in a valid but otherwise unspecified state.
template<class T> any(T&& value);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Constructs an object of type any that contains an object of type VT direct-initialized with std​::​forward<T>(value).
Remarks: This constructor shall not participate in overload resolution unless VT is not the same type as any, VT is not a specialization of in_­place_­type_­t, and is_­copy_­constructible_­v<VT> is true.
Throws: Any exception thrown by the selected constructor of VT.
template <class T, class... Args> explicit any(in_place_type_t<T>, Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value of type VT.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, Args...> is true.
template <class T, class U, class... Args> explicit any(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: This constructor shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, initializer_­list<U>&, Args...> is true.
~any();
Effects: As if by reset().

23.8.3.2 Assignment [any.assign]

any& operator=(const any& rhs);
Effects: As if by any(rhs).swap(*this).
No effects if an exception is thrown.
Returns: *this.
Throws: Any exceptions arising from the copy constructor for the contained value.
any& operator=(any&& rhs) noexcept;
Effects: As if by any(std​::​move(rhs)).swap(*this).
Returns: *this.
Postconditions: The state of *this is equivalent to the original state of rhs and rhs is left in a valid but otherwise unspecified state.
template<class T> any& operator=(T&& rhs);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Constructs an object tmp of type any that contains an object of type VT direct-initialized with std​::​forward<T>(rhs), and tmp.swap(*this).
No effects if an exception is thrown.
Returns: *this.
Remarks: This operator shall not participate in overload resolution unless VT is not the same type as any and is_­copy_­constructible_­v<VT> is true.
Throws: Any exception thrown by the selected constructor of VT.

23.8.3.3 Modifiers [any.modifiers]

template <class T, class... Args> decay_t<T>& emplace(Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Calls reset().
Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed.
This function shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, Args...> is true.
template <class T, class U, class... Args> decay_t<T>& emplace(initializer_list<U> il, Args&&... args);
Let VT be decay_­t<T>.
Requires: VT shall satisfy the CopyConstructible requirements.
Effects: Calls reset().
Then initializes the contained value as if direct-non-list-initializing an object of type VT with the arguments il, std​::​forward<Args>(args)....
Postconditions: *this contains a value.
Returns: A reference to the new contained value.
Throws: Any exception thrown by the selected constructor of VT.
Remarks: If an exception is thrown during the call to VT's constructor, *this does not contain a value, and any previously contained value has been destroyed.
The function shall not participate in overload resolution unless is_­copy_­constructible_­v<VT> is true and is_­constructible_­v<VT, initializer_­list<U>&, Args...> is true.
void reset() noexcept;
Effects: If has_­value() is true, destroys the contained value.
Postconditions: has_­value() is false.
void swap(any& rhs) noexcept;
Effects: Exchanges the states of *this and rhs.

23.8.3.4 Observers [any.observers]

bool has_value() const noexcept;
Returns: true if *this contains an object, otherwise false.
const type_info& type() const noexcept;
Returns: typeid(T) if *this has a contained value of type T, otherwise typeid(void).
[Note
:
Useful for querying against types known either at compile time or only at runtime.
end note
]

23.8.4 Non-member functions [any.nonmembers]

void swap(any& x, any& y) noexcept;
Effects: As if by x.swap(y).
template <class T, class... Args> any make_any(Args&& ...args);
Effects: Equivalent to: return any(in_­place_­type<T>, std​::​forward<Args>(args)...);
template <class T, class U, class... Args> any make_any(initializer_list<U> il, Args&& ...args);
Effects: Equivalent to: return any(in_­place_­type<T>, il, std​::​forward<Args>(args)...);
template<class T> T any_cast(const any& operand); template<class T> T any_cast(any& operand); template<class T> T any_cast(any&& operand);
Let U be the type remove_­cv_­t<remove_­reference_­t<ValueType>>.
Requires: For the first overload, is_­constructible_­v<ValueType, const U&> is true.
For the second overload, is_­constructible_­v<ValueType, U&> is true.
For the third overload, is_­constructible_­v<ValueType, U> is true.
Otherwise the program is ill-formed.
Returns: For the first and second overload, static_­cast<ValueType>(*any_­cast<U>(&operand)).
For the third overload, static_­cast<ValueType>(std​::​move(*any_­cast<U>(&operand))).
Throws: bad_­any_­cast if operand.type() != typeid(remove_­reference_­t<T>).
[Example
:
any x(5);                                   // x holds int
assert(any_cast<int>(x) == 5);              // cast to value
any_cast<int&>(x) = 10;                     // cast to reference
assert(any_cast<int>(x) == 10);

x = "Meow";                                 // x holds const char*
assert(strcmp(any_cast<const char*>(x), "Meow") == 0);
any_cast<const char*&>(x) = "Harry";
assert(strcmp(any_cast<const char*>(x), "Harry") == 0);

x = string("Meow");                         // x holds string
string s, s2("Jane");
s = move(any_cast<string&>(x));             // move from any
assert(s == "Meow");
any_cast<string&>(x) = move(s2);            // move to any
assert(any_cast<const string&>(x) == "Jane");

string cat("Meow");
const any y(cat);                           // const y holds string
assert(any_cast<const string&>(y) == cat);

any_cast<string&>(y);                       // error; cannot
                                            // any_­cast away const
end example
]
template<class T> const T* any_cast(const any* operand) noexcept; template<class T> T* any_cast(any* operand) noexcept;
Returns: If operand != nullptr && operand->type() == typeid(T), a pointer to the object contained by operand; otherwise, nullptr.
[Example
:
bool is_string(const any& operand) {
  return any_cast<string>(&operand) != nullptr;
}
end example
]

23.9 Bitsets [bitset]

23.9.1 Header <bitset> synopsis [bitset.syn]

#include <string>
#include <iosfwd>   // for istream ([istream.syn]), ostream ([ostream.syn]), see [iosfwd.syn]

namespace std {
  template <size_t N> class bitset;

  // [bitset.operators], bitset operators
  template <size_t N>
    bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept;
  template <size_t N>
    bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept;
  template <size_t N>
    bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept;
  template <class charT, class traits, size_t N>
    basic_istream<charT, traits>&
      operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
  template <class charT, class traits, size_t N>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
}
The header <bitset> defines a class template and several related functions for representing and manipulating fixed-size sequences of bits.

23.9.2 Class template bitset [template.bitset]

namespace std {
  template<size_t N> class bitset {
  public:
    // bit reference:
    class reference {
      friend class bitset;
      reference() noexcept;
    public:
      ~reference() noexcept;
      reference& operator=(bool x) noexcept;             // for b[i] = x;
      reference& operator=(const reference&) noexcept;   // for b[i] = b[j];
      bool operator~() const noexcept;                   // flips the bit
      operator bool() const noexcept;                    // for x = b[i];
      reference& flip() noexcept;                        // for b[i].flip();
    };

    // [bitset.cons], constructors
    constexpr bitset() noexcept;
    constexpr bitset(unsigned long long val) noexcept;
    template<class charT, class traits, class Allocator>
      explicit bitset(
        const basic_string<charT, traits, Allocator>& str,
        typename basic_string<charT, traits, Allocator>::size_type pos = 0,
        typename basic_string<charT, traits, Allocator>::size_type n =
          basic_string<charT, traits, Allocator>::npos,
        charT zero = charT('0'),
        charT one = charT('1'));
    template <class charT>
      explicit bitset(
        const charT* str,
        typename basic_string<charT>::size_type n = basic_string<charT>::npos,
        charT zero = charT('0'),
        charT one = charT('1'));

    // [bitset.members], bitset operations
    bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator<<=(size_t pos) noexcept;
    bitset<N>& operator>>=(size_t pos) noexcept;
    bitset<N>& set() noexcept;
    bitset<N>& set(size_t pos, bool val = true);
    bitset<N>& reset() noexcept;
    bitset<N>& reset(size_t pos);
    bitset<N>  operator~() const noexcept;
    bitset<N>& flip() noexcept;
    bitset<N>& flip(size_t pos);

    // element access:
    constexpr bool operator[](size_t pos) const;       // for b[i];
    reference operator[](size_t pos);                  // for b[i];

    unsigned long to_ulong() const;
    unsigned long long to_ullong() const;
    template <class charT = char,
              class traits = char_traits<charT>,
              class Allocator = allocator<charT>>
      basic_string<charT, traits, Allocator>
        to_string(charT zero = charT('0'), charT one = charT('1')) const;

    size_t count() const noexcept;
    constexpr size_t size() const noexcept;
    bool operator==(const bitset<N>& rhs) const noexcept;
    bool operator!=(const bitset<N>& rhs) const noexcept;
    bool test(size_t pos) const;
    bool all() const noexcept;
    bool any() const noexcept;
    bool none() const noexcept;
    bitset<N> operator<<(size_t pos) const noexcept;
    bitset<N> operator>>(size_t pos) const noexcept;
  };

  // [bitset.hash], hash support
  template <class T> struct hash;
  template <size_t N> struct hash<bitset<N>>;
}
The class template bitset<N>describes an object that can store a sequence consisting of a fixed number of bits, N.
Each bit represents either the value zero (reset) or one (set).
To toggle a bit is to change the value zero to one, or the value one to zero.
Each bit has a non-negative position pos.
When converting between an object of class bitset<N> and a value of some integral type, bit position pos corresponds to the bit value 1 << pos.
The integral value corresponding to two or more bits is the sum of their bit values.
The functions described in this subclause can report three kinds of errors, each associated with a distinct exception:

23.9.2.1 bitset constructors [bitset.cons]

constexpr bitset() noexcept;
Effects: Constructs an object of class bitset<N>, initializing all bits to zero.
constexpr bitset(unsigned long long val) noexcept;
Effects: Constructs an object of class bitset<N>, initializing the first M bit positions to the corresponding bit values in val.
M is the smaller of N and the number of bits in the value representation ([basic.types]) of unsigned long long.
If M < N, the remaining bit positions are initialized to zero.
template <class charT, class traits, class Allocator> explicit bitset(const basic_string<charT, traits, Allocator>& str, typename basic_string<charT, traits, Allocator>::size_type pos = 0, typename basic_string<charT, traits, Allocator>::size_type n = basic_string<charT, traits, Allocator>::npos, charT zero = charT('0'), charT one = charT('1'));
Throws: out_­of_­range if pos > str.size() or invalid_­argument if an invalid character is found (see below).
Effects: Determines the effective length rlen of the initializing string as the smaller of n and str.size() - pos.
The function then throws invalid_­argument if any of the rlen characters in str beginning at position pos is other than zero or one.
The function uses traits​::​eq() to compare the character values.
Otherwise, the function constructs an object of class bitset<N>, initializing the first M bit positions to values determined from the corresponding characters in the string str.
M is the smaller of N and rlen.
An element of the constructed object has value zero if the corresponding character in str, beginning at position pos, is zero.
Otherwise, the element has the value one.
Character position pos + M - 1 corresponds to bit position zero.
Subsequent decreasing character positions correspond to increasing bit positions.
If M < N, remaining bit positions are initialized to zero.
template <class charT> explicit bitset( const charT* str, typename basic_string<charT>::size_type n = basic_string<charT>::npos, charT zero = charT('0'), charT one = charT('1'));
Effects: Constructs an object of class bitset<N> as if by:
bitset(
  n == basic_string<charT>::npos
    ? basic_string<charT>(str)
    : basic_string<charT>(str, n),
  0, n, zero, one)

23.9.2.2 bitset members [bitset.members]

bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
Effects: Clears each bit in *this for which the corresponding bit in rhs is clear, and leaves all other bits unchanged.
Returns: *this.
bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
Effects: Sets each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
Returns: *this.
bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
Effects: Toggles each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits unchanged.
Returns: *this.
bitset<N>& operator<<=(size_t pos) noexcept;
Effects: Replaces each bit at position I in *this with a value determined as follows:
  • If I < pos, the new value is zero;
  • If I >= pos, the new value is the previous value of the bit at position I - pos.
Returns: *this.
bitset<N>& operator>>=(size_t pos) noexcept;
Effects: Replaces each bit at position I in *this with a value determined as follows:
  • If pos >= N - I, the new value is zero;
  • If pos < N - I, the new value is the previous value of the bit at position I + pos.
Returns: *this.
bitset<N>& set() noexcept;
Effects: Sets all bits in *this.
Returns: *this.
bitset<N>& set(size_t pos, bool val = true);
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Effects: Stores a new value in the bit at position pos in *this.
If val is nonzero, the stored value is one, otherwise it is zero.
Returns: *this.
bitset<N>& reset() noexcept;
Effects: Resets all bits in *this.
Returns: *this.
bitset<N>& reset(size_t pos);
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Effects: Resets the bit at position pos in *this.
Returns: *this.
bitset<N> operator~() const noexcept;
Effects: Constructs an object x of class bitset<N> and initializes it with *this.
Returns: x.flip().
bitset<N>& flip() noexcept;
Effects: Toggles all bits in *this.
Returns: *this.
bitset<N>& flip(size_t pos);
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Effects: Toggles the bit at position pos in *this.
Returns: *this.
unsigned long to_ulong() const;
Throws: overflow_­error if the integral value x corresponding to the bits in *this cannot be represented as type unsigned long.
Returns: x.
unsigned long long to_ullong() const;
Throws: overflow_­error if the integral value x corresponding to the bits in *this cannot be represented as type unsigned long long.
Returns: x.
template <class charT = char, class traits = char_traits<charT>, class Allocator = allocator<charT>> basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;
Effects: Constructs a string object of the appropriate type and initializes it to a string of length N characters.
Each character is determined by the value of its corresponding bit position in *this.
Character position N - 1 corresponds to bit position zero.
Subsequent decreasing character positions correspond to increasing bit positions.
Bit value zero becomes the character zero, bit value one becomes the character one.
Returns: The created object.
size_t count() const noexcept;
Returns: A count of the number of bits set in *this.
constexpr size_t size() const noexcept;
Returns: N.
bool operator==(const bitset<N>& rhs) const noexcept;
Returns: true if the value of each bit in *this equals the value of the corresponding bit in rhs.
bool operator!=(const bitset<N>& rhs) const noexcept;
Returns: true if !(*this == rhs).
bool test(size_t pos) const;
Throws: out_­of_­range if pos does not correspond to a valid bit position.
Returns: true if the bit at position pos in *this has the value one.
bool all() const noexcept;
Returns: count() == size().
bool any() const noexcept;
Returns: count() != 0.
bool none() const noexcept;
Returns: count() == 0.
bitset<N> operator<<(size_t pos) const noexcept;
Returns: bitset<N>(*this) <<= pos.
bitset<N> operator>>(size_t pos) const noexcept;
Returns: bitset<N>(*this) >>= pos.
constexpr bool operator[](size_t pos) const;
Requires: pos shall be valid.
Returns: true if the bit at position pos in *this has the value one, otherwise false.
Throws: Nothing.
bitset<N>::reference operator[](size_t pos);
Requires: pos shall be valid.
Returns: An object of type bitset<N>​::​reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val).
Throws: Nothing.
Remarks: For the purpose of determining the presence of a data race ([intro.multithread]), any access or update through the resulting reference potentially accesses or modifies, respectively, the entire underlying bitset.

23.9.3 bitset hash support [bitset.hash]

template <size_t N> struct hash<bitset<N>>;
The specialization is enabled ([unord.hash]).

23.9.4 bitset operators [bitset.operators]

bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) &= rhs.
bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) |= rhs.
bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
Returns: bitset<N>(lhs) ^= rhs.
template <class charT, class traits, size_t N> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
A formatted input function ([istream.formatted]).
Effects: Extracts up to N characters from is.
Stores these characters in a temporary object str of type basic_­string<charT, traits>, then evaluates the expression x = bitset<N>(str).
Characters are extracted and stored until any of the following occurs:
  • N characters have been extracted and stored;
  • end-of-file occurs on the input sequence;
  • the next input character is neither is.widen('0') nor is.widen('1') (in which case the input character is not extracted).
If no characters are stored in str, calls is.setstate(ios_­base​::​failbit) (which may throw ios_­base​::​failure ([iostate.flags])).
Returns: is.
template <class charT, class traits, size_t N> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
Returns:
os << x.template to_string<charT, traits, allocator<charT>>(
  use_facet<ctype<charT>>(os.getloc()).widen('0'),
  use_facet<ctype<charT>>(os.getloc()).widen('1'))
(see [ostream.formatted]).

23.10 Memory [memory]

23.10.1 In general [memory.general]

This subclause describes the contents of the header <memory> ([memory.syn]) and some of the contents of the header <cstdlib> ([cstdlib.syn]).

23.10.2 Header <memory> synopsis [memory.syn]

The header <memory> defines several types and function templates that describe properties of pointers and pointer-like types, manage memory for containers and other template types, destroy objects, and construct multiple objects in uninitialized memory buffers ([pointer.traits][specialized.algorithms]).
The header also defines the templates unique_­ptr, shared_­ptr, weak_­ptr, and various function templates that operate on objects of these types ([smartptr]).
namespace std {
  // [pointer.traits], pointer traits
  template <class Ptr> struct pointer_traits;
  template <class T> struct pointer_traits<T*>;

  // [util.dynamic.safety], pointer safety
  enum class pointer_safety { relaxed, preferred, strict };
  void declare_reachable(void* p);
  template <class T> T* undeclare_reachable(T* p);
  void declare_no_pointers(char* p, size_t n);
  void undeclare_no_pointers(char* p, size_t n);
  pointer_safety get_pointer_safety() noexcept;

  // [ptr.align], pointer alignment function
  void* align(size_t alignment, size_t size, void*& ptr, size_t& space);

  // [allocator.tag], allocator argument tag
  struct allocator_arg_t { explicit allocator_arg_t() = default; };
  inline constexpr allocator_arg_t allocator_arg{};

  // [allocator.uses], uses_­allocator
  template <class T, class Alloc> struct uses_allocator;

  // [allocator.traits], allocator traits
  template <class Alloc> struct allocator_traits;

  // [default.allocator], the default allocator
  template <class T> class allocator;
  template <class T, class U>
    bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
  template <class T, class U>
    bool operator!=(const allocator<T>&, const allocator<U>&) noexcept;

  // [specialized.algorithms], specialized algorithms
  template <class T> constexpr T* addressof(T& r) noexcept;
  template <class T> const T* addressof(const T&&) = delete;
  template <class ForwardIterator>
    void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
  template <class ExecutionPolicy, class ForwardIterator>
    void uninitialized_default_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         ForwardIterator first, ForwardIterator last);
  template <class ForwardIterator, class Size>
    ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
  template <class ExecutionPolicy, class ForwardIterator, class Size>
    ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                                      ForwardIterator first, Size n);
  template <class ForwardIterator>
    void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
  template <class ExecutionPolicy, class ForwardIterator>
    void uninitialized_value_construct(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       ForwardIterator first, ForwardIterator last);
  template <class ForwardIterator, class Size>
    ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
  template <class ExecutionPolicy, class ForwardIterator, class Size>
    ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                                    ForwardIterator first, Size n);
  template <class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class InputIterator, class Size, class ForwardIterator>
    ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
                                         ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
    ForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         InputIterator first, Size n,
                                         ForwardIterator result);
  template <class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_move(InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       InputIterator first, InputIterator last,
                                       ForwardIterator result);
  template <class InputIterator, class Size, class ForwardIterator>
    pair<InputIterator, ForwardIterator>
      uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
  template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
    pair<InputIterator, ForwardIterator>
      uninitialized_move_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                           InputIterator first, Size n, ForwardIterator result);
  template <class ForwardIterator, class T>
    void uninitialized_fill(ForwardIterator first, ForwardIterator last,
                            const T& x);
  template <class ExecutionPolicy, class ForwardIterator, class T>
    void uninitialized_fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                            ForwardIterator first, ForwardIterator last,
                            const T& x);
  template <class ForwardIterator, class Size, class T>
    ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
  template <class ExecutionPolicy, class ForwardIterator, class Size, class T>
    ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         ForwardIterator first, Size n, const T& x);
  template <class T>
    void destroy_at(T* location);
  template <class ForwardIterator>
    void destroy(ForwardIterator first, ForwardIterator last);
  template <class ExecutionPolicy, class ForwardIterator>
    void destroy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                 ForwardIterator first, ForwardIterator last);
  template <class ForwardIterator, class Size>
    ForwardIterator destroy_n(ForwardIterator first, Size n);
  template <class ExecutionPolicy, class ForwardIterator, class Size>
    ForwardIterator destroy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                              ForwardIterator first, Size n);

  // [unique.ptr], class template unique_­ptr
  template <class T> struct default_delete;
  template <class T> struct default_delete<T[]>;
  template <class T, class D = default_delete<T>> class unique_ptr;
  template <class T, class D> class unique_ptr<T[], D>;

  template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
  template <class T> unique_ptr<T> make_unique(size_t n);
  template <class T, class... Args> unspecified make_unique(Args&&...) = delete;

  template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

  template <class T1, class D1, class T2, class D2>
    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template <class T1, class D1, class T2, class D2>
    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

  template <class T, class D>
    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);

  // [util.smartptr.weak.bad], class bad_­weak_­ptr
  class bad_weak_ptr;

  // [util.smartptr.shared], class template shared_­ptr
  template<class T> class shared_ptr;

  // [util.smartptr.shared.create], shared_­ptr creation
  template<class T, class... Args>
    shared_ptr<T> make_shared(Args&&... args);
  template<class T, class A, class... Args>
    shared_ptr<T> allocate_shared(const A& a, Args&&... args);

  // [util.smartptr.shared.cmp], shared_­ptr comparisons
  template<class T, class U>
    bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;

  template <class T>
    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
  template <class T>
    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
  template <class T>
    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;

  // [util.smartptr.shared.spec], shared_­ptr specialized algorithms
  template<class T>
    void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;

  // [util.smartptr.shared.cast], shared_­ptr casts
  template<class T, class U>
    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;

  // [util.smartptr.getdeleter], shared_­ptr get_­deleter
  template<class D, class T>
    D* get_deleter(const shared_ptr<T>& p) noexcept;

  // [util.smartptr.shared.io], shared_­ptr I/O
  template<class E, class T, class Y>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);

  // [util.smartptr.weak], class template weak_­ptr
  template<class T> class weak_ptr;

  // [util.smartptr.weak.spec], weak_­ptr specialized algorithms
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;

  // [util.smartptr.ownerless], class template owner_­less
  template<class T = void> struct owner_less;

  // [util.smartptr.enab], class template enable_­shared_­from_­this
  template<class T> class enable_shared_from_this;

  // [util.smartptr.shared.atomic], shared_­ptr atomic access
  template<class T>
    bool atomic_is_lock_free(const shared_ptr<T>* p);

  template<class T>
    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
  template<class T>
    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);

  template<class T>
    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
  template<class T>
    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

  template<class T>
    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
  template<class T>
    shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

  template<class T>
    bool atomic_compare_exchange_weak(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
  template<class T>
    bool atomic_compare_exchange_strong(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
  template<class T>
    bool atomic_compare_exchange_weak_explicit(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
      memory_order success, memory_order failure);
  template<class T>
    bool atomic_compare_exchange_strong_explicit(
      shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
      memory_order success, memory_order failure);

  // [util.smartptr.hash], hash support
  template <class T> struct hash;
  template <class T, class D> struct hash<unique_ptr<T, D>>;
  template <class T> struct hash<shared_ptr<T>>;

  // [allocator.uses.trait], uses_­allocator
  template <class T, class Alloc>
    inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
}

23.10.3 Pointer traits [pointer.traits]

The class template pointer_­traits supplies a uniform interface to certain attributes of pointer-like types.
namespace std {
  template <class Ptr> struct pointer_traits {
    using pointer         = Ptr;
    using element_type    = see below;
    using difference_type = see below;

    template <class U> using rebind = see below;

    static pointer pointer_to(see below r);
  };

  template <class T> struct pointer_traits<T*> {
    using pointer         = T*;
    using element_type    = T;
    using difference_type = ptrdiff_t;

    template <class U> using rebind = U*;

    static pointer pointer_to(see below r) noexcept;
  };
}

23.10.3.1 Pointer traits member types [pointer.traits.types]

using element_type = see below;
Type: Ptr​::​element_­type if the qualified-id Ptr​::​element_­type is valid and denotes a type ([temp.deduct]); otherwise, T if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the specialization is ill-formed.
using difference_type = see below;
Type: Ptr​::​difference_­type if the qualified-id Ptr​::​difference_­type is valid and denotes a type ([temp.deduct]); otherwise, ptrdiff_­t.
template <class U> using rebind = see below;
Alias template: Ptr​::​rebind<U> if the qualified-id Ptr​::​rebind<U> is valid and denotes a type ([temp.deduct]); otherwise, SomePointer<U, Args> if Ptr is a class template instantiation of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind is ill-formed.

23.10.3.2 Pointer traits member functions [pointer.traits.functions]

static pointer pointer_traits::pointer_to(see below r); static pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
Remarks: If element_­type is cv void, the type of r is unspecified; otherwise, it is element_­type&.
Returns: The first member function returns a pointer to r obtained by calling Ptr​::​pointer_­to(r) through which indirection is valid; an instantiation of this function is ill-formed if Ptr does not have a matching pointer_­to static member function.
The second member function returns addressof(r).

23.10.4 Pointer safety [util.dynamic.safety]

A complete object is declared reachable while the number of calls to declare_­reachable with an argument referencing the object exceeds the number of calls to undeclare_­reachable with an argument referencing the object.
void declare_reachable(void* p);
Requires: p shall be a safely-derived pointer ([basic.stc.dynamic.safety]) or a null pointer value.
Effects: If p is not null, the complete object referenced by p is subsequently declared reachable ([basic.stc.dynamic.safety]).
Throws: May throw bad_­alloc if the system cannot allocate additional memory that may be required to track objects declared reachable.
template <class T> T* undeclare_reachable(T* p);
Requires: If p is not null, the complete object referenced by p shall have been previously declared reachable, and shall be live ([basic.life]) from the time of the call until the last undeclare_­reachable(p) call on the object.
Returns: A safely derived copy of p which shall compare equal to p.
Throws: Nothing.
[Note
:
It is expected that calls to declare_­reachable(p) will consume a small amount of memory in addition to that occupied by the referenced object until the matching call to undeclare_­reachable(p) is encountered.
Long running programs should arrange that calls are matched.
end note
]
void declare_no_pointers(char* p, size_t n);
Requires: No bytes in the specified range are currently registered with declare_­no_­pointers().
If the specified range is in an allocated object, then it must be entirely within a single allocated object.
The object must be live until the corresponding undeclare_­no_­pointers() call.
[Note
:
In a garbage-collecting implementation, the fact that a region in an object is registered with declare_­no_­pointers() should not prevent the object from being collected.
end note
]
Effects: The n bytes starting at p no longer contain traceable pointer locations, independent of their type.
Hence indirection through a pointer located there is undefined if the object it points to was created by global operator new and not previously declared reachable.
[Note
:
This may be used to inform a garbage collector or leak detector that this region of memory need not be traced.
end note
]
Throws: Nothing.
[Note
:
Under some conditions implementations may need to allocate memory.
However, the request can be ignored if memory allocation fails.
end note
]
void undeclare_no_pointers(char* p, size_t n);
Requires: The same range must previously have been passed to declare_­no_­pointers().
Effects: Unregisters a range registered with declare_­no_­pointers() for destruction.
It must be called before the lifetime of the object ends.
Throws: Nothing.
pointer_safety get_pointer_safety() noexcept;
Returns: pointer_­safety​::​strict if the implementation has strict pointer safety ([basic.stc.dynamic.safety]).
It is implementation-defined whether get_­pointer_­safety returns pointer_­safety​::​relaxed or pointer_­safety​::​preferred if the implementation has relaxed pointer safety.221
pointer_­safety​::​preferred might be returned to indicate that a leak detector is running so that the program can avoid spurious leak reports.

23.10.5 Align [ptr.align]

void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
Effects: If it is possible to fit size bytes of storage aligned by alignment into the buffer pointed to by ptr with length space, the function updates ptr to represent the first possible address of such storage and decreases space by the number of bytes used for alignment.
Otherwise, the function does nothing.
Requires:
  • alignment shall be a power of two
  • ptr shall represent the address of contiguous storage of at least space bytes
Returns: A null pointer if the requested aligned buffer would not fit into the available space, otherwise the adjusted value of ptr.
[Note
:
The function updates its ptr and space arguments so that it can be called repeatedly with possibly different alignment and size arguments for the same buffer.
end note
]

23.10.6 Allocator argument tag [allocator.tag]

namespace std { struct allocator_arg_t { explicit allocator_arg_t() = default; }; inline constexpr allocator_arg_t allocator_arg{}; }
The allocator_­arg_­t struct is an empty structure type used as a unique type to disambiguate constructor and function overloading.
Specifically, several types (see tuple [tuple]) have constructors with allocator_­arg_­t as the first argument, immediately followed by an argument of a type that satisfies the Allocator requirements ([allocator.requirements]).

23.10.7 uses_­allocator [allocator.uses]

23.10.7.1 uses_­allocator trait [allocator.uses.trait]

template <class T, class Alloc> struct uses_allocator;
Remarks: Automatically detects whether T has a nested allocator_­type that is convertible from Alloc.
Meets the BinaryTypeTrait requirements ([meta.rqmts]).
The implementation shall provide a definition that is derived from true_­type if the qualified-id T​::​allocator_­type is valid and denotes a type ([temp.deduct]) and is_­convertible_­v<Alloc, T​::​allocator_­type> != false, otherwise it shall be derived from false_­type.
A program may specialize this template to derive from true_­type for a user-defined type T that does not have a nested allocator_­type but nonetheless can be constructed with an allocator where either:
  • the first argument of a constructor has type allocator_­arg_­t and the second argument has type Alloc or
  • the last argument of a constructor has type Alloc.

23.10.7.2 Uses-allocator construction [allocator.uses.construction]

Uses-allocator construction with allocator Alloc refers to the construction of an object obj of type T, using constructor arguments v1, v2, ..., vN of types V1, V2, ..., VN, respectively, and an allocator alloc of type Alloc, according to the following rules:
  • if uses_­allocator_­v<T, Alloc> is false and is_­constructible_­v<T, V1, V2, ..., VN> is true, then obj is initialized as obj(v1, v2, ..., vN);
  • otherwise, if uses_­allocator_­v<T, Alloc> is true and is_­constructible_­v<T, allocator_­arg_­t, Alloc, V1, V2, ..., VN> is true, then obj is initialized as obj(allocator_­arg, alloc, v1, v2, ..., vN);
  • otherwise, if uses_­allocator_­v<T, Alloc> is true and is_­constructible_­v<T, V1, V2, ..., VN, Alloc> is true, then obj is initialized as obj(v1, v2, ..., vN, alloc);
  • otherwise, the request for uses-allocator construction is ill-formed.
    [Note
    :
    An error will result if uses_­allocator_­v<T, Alloc> is true but the specific constructor does not take an allocator.
    This definition prevents a silent failure to pass the allocator to an element.
    end note
    ]

23.10.8 Allocator traits [allocator.traits]

The class template allocator_­traits supplies a uniform interface to all allocator types.
An allocator cannot be a non-class type, however, even if allocator_­traits supplies the entire required interface.
[Note
:
Thus, it is always possible to create a derived class from an allocator.
end note
]
namespace std {
  template <class Alloc> struct allocator_traits {
    using allocator_type     = Alloc;

    using value_type         = typename Alloc::value_type;

    using pointer            = see below;
    using const_pointer      = see below;
    using void_pointer       = see below;
    using const_void_pointer = see below;

    using difference_type    = see below;
    using size_type          = see below;

    using propagate_on_container_copy_assignment = see below;
    using propagate_on_container_move_assignment = see below;
    using propagate_on_container_swap            = see below;
    using is_always_equal                        = see below;

    template <class T> using rebind_alloc = see below;
    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;

    static pointer allocate(Alloc& a, size_type n);
    static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);

    static void deallocate(Alloc& a, pointer p, size_type n);

    template <class T, class... Args>
      static void construct(Alloc& a, T* p, Args&&... args);

    template <class T>
      static void destroy(Alloc& a, T* p);

    static size_type max_size(const Alloc& a) noexcept;

    static Alloc select_on_container_copy_construction(const Alloc& rhs);
  };
}

23.10.8.1 Allocator traits member types [allocator.traits.types]

using pointer = see below;
Type: Alloc​::​pointer if the qualified-id Alloc​::​pointer is valid and denotes a type ([temp.deduct]); otherwise, value_­type*.
using const_pointer = see below;
Type: Alloc​::​const_­pointer if the qualified-id Alloc​::​const_­pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​rebind<​const value_­type>.
using void_pointer = see below;
Type: Alloc​::​void_­pointer if the qualified-id Alloc​::​void_­pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​rebind<​void>.
using const_void_pointer = see below;
Type: Alloc​::​const_­void_­pointer if the qualified-id Alloc​::​const_­void_­pointer is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​​rebind<const void>.
using difference_type = see below;
Type: Alloc​::​difference_­type if the qualified-id Alloc​::​difference_­type is valid and denotes a type ([temp.deduct]); otherwise, pointer_­traits<pointer>​::​difference_­type.
using size_type = see below;
Type: Alloc​::​size_­type if the qualified-id Alloc​::​size_­type is valid and denotes a type ([temp.deduct]); otherwise, make_­unsigned_­t<difference_­type>.
using propagate_on_container_copy_assignment = see below;
Type: Alloc​::​propagate_­on_­container_­copy_­assignment if the qualified-id Alloc​::​propagate_­on_­container_­copy_­assignment is valid and denotes a type ([temp.deduct]); otherwise false_­type.
using propagate_on_container_move_assignment = see below;
Type: Alloc​::​propagate_­on_­container_­move_­assignment if the qualified-id Alloc​::​propagate_­on_­container_­move_­assignment is valid and denotes a type ([temp.deduct]); otherwise false_­type.
using propagate_on_container_swap = see below;
Type: Alloc​::​propagate_­on_­container_­swap if the qualified-id Alloc​::​propagate_­on_­container_­swap is valid and denotes a type ([temp.deduct]); otherwise false_­type.
using is_always_equal = see below;
Type: Alloc​::​is_­always_­equal if the qualified-id Alloc​::​is_­always_­equal is valid and denotes a type ([temp.deduct]); otherwise is_­empty<Alloc>​::​type.
template <class T> using rebind_alloc = see below;
Alias template: Alloc​::​rebind<T>​::​other if the qualified-id Alloc​::​rebind<T>​::​other is valid and denotes a type ([temp.deduct]); otherwise, Alloc<T, Args> if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or more type arguments; otherwise, the instantiation of rebind_­alloc is ill-formed.

23.10.8.2 Allocator traits static member functions [allocator.traits.members]

static pointer allocate(Alloc& a, size_type n);
Returns: a.allocate(n).
static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
Returns: a.allocate(n, hint) if that expression is well-formed; otherwise, a.allocate(n).
static void deallocate(Alloc& a, pointer p, size_type n);
Effects: Calls a.deallocate(p, n).
Throws: Nothing.
template <class T, class... Args> static void construct(Alloc& a, T* p, Args&&... args);
Effects: Calls a.construct(p, std​::​forward<Args>(args)...) if that call is well-formed; otherwise, invokes ​::​new (static_­cast<void*>(p)) T(std​::​forward<Args>(args)...).
template <class T> static void destroy(Alloc& a, T* p);
Effects: Calls a.destroy(p) if that call is well-formed; otherwise, invokes p->~T().
static size_type max_size(const Alloc& a) noexcept;
Returns: a.max_­size() if that expression is well-formed; otherwise, numeric_­limits<size_­type>​::​​max()/sizeof(value_­type).
static Alloc select_on_container_copy_construction(const Alloc& rhs);
Returns: rhs.select_­on_­container_­copy_­construction() if that expression is well-formed; otherwise, rhs.

23.10.9 The default allocator [default.allocator]

All specializations of the default allocator satisfy the allocator completeness requirements ([allocator.requirements.completeness]).
namespace std {
  template <class T> class allocator {
   public:
    using value_type      = T;
    using propagate_on_container_move_assignment = true_type;
    using is_always_equal = true_type;

    allocator() noexcept;
    allocator(const allocator&) noexcept;
    template <class U> allocator(const allocator<U>&) noexcept;
    ~allocator();

    T* allocate(size_t n);
    void deallocate(T* p, size_t n);
  };
}

23.10.9.1 allocator members [allocator.members]

Except for the destructor, member functions of the default allocator shall not introduce data races ([intro.multithread]) as a result of concurrent calls to those member functions from different threads.
Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.
T* allocate(size_t n);
Returns: A pointer to the initial element of an array of storage of size n * sizeof(T), aligned appropriately for objects of type T.
Remarks: the storage is obtained by calling ​::​operator new ([new.delete]), but it is unspecified when or how often this function is called.
Throws: bad_­alloc if the storage cannot be obtained.
void deallocate(T* p, size_t n);
Requires: p shall be a pointer value obtained from allocate().
n shall equal the value passed as the first argument to the invocation of allocate which returned p.
Effects: Deallocates the storage referenced by p .
Remarks: Uses ​::​operator delete ([new.delete]), but it is unspecified when this function is called.

23.10.9.2 allocator globals [allocator.globals]

template <class T, class U> bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
Returns: true.
template <class T, class U> bool operator!=(const allocator<T>&, const allocator<U>&) noexcept;
Returns: false.

23.10.10 Specialized algorithms [specialized.algorithms]

Throughout this subclause, the names of template parameters are used to express type requirements.
  • If an algorithm's template parameter is named InputIterator, the template argument shall satisfy the requirements of an input iterator ([input.iterators]).
  • If an algorithm's template parameter is named ForwardIterator, the template argument shall satisfy the requirements of a forward iterator ([forward.iterators]), and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators.
Unless otherwise specified, if an exception is thrown in the following algorithms there are no effects.

23.10.10.1 addressof [specialized.addressof]

template <class T> constexpr T* addressof(T& r) noexcept;
Returns: The actual address of the object or function referenced by r, even in the presence of an overloaded operator&.
Remarks: An expression addressof(E) is a constant subexpression ([defns.const.subexpr]) if E is an lvalue constant subexpression.

23.10.10.2 uninitialized_­default_­construct [uninitialized.construct.default]

template <class ForwardIterator> void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first != last; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type;
template <class ForwardIterator, class Size> ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
Effects: Equivalent to:
for (; n>0; (void)++first, --n)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type;
return first;

23.10.10.3 uninitialized_­value_­construct [uninitialized.construct.value]

template <class ForwardIterator> void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first != last; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type();
template <class ForwardIterator, class Size> ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
Effects: Equivalent to:
for (; n>0; (void)++first, --n)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type();
return first;

23.10.10.4 uninitialized_­copy [uninitialized.copy]

template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
Effects: As if by:
for (; first != last; ++result, (void) ++first)
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(*first);
Returns: result.
template <class InputIterator, class Size, class ForwardIterator> ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
Effects: As if by:
for ( ; n > 0; ++result, (void) ++first, --n) {
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(*first);
}
Returns: result.

23.10.10.5 uninitialized_­move [uninitialized.move]

template <class InputIterator, class ForwardIterator> ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
Effects: Equivalent to:
for (; first != last; (void)++result, ++first)
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
return result;
Remarks: If an exception is thrown, some objects in the range [first, last) are left in a valid but unspecified state.
template <class InputIterator, class Size, class ForwardIterator> pair<InputIterator, ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
Effects: Equivalent to:
for (; n > 0; ++result, (void) ++first, --n)
  ::new (static_cast<void*>(addressof(*result)))
    typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
return {first,result};
Remarks: If an exception is thrown, some objects in the range [first, std​::​next(first,n)) are left in a valid but unspecified state.

23.10.10.6 uninitialized_­fill [uninitialized.fill]

template <class ForwardIterator, class T> void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
Effects: As if by:
for (; first != last; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type(x);
template <class ForwardIterator, class Size, class T> ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
Effects: As if by:
for (; n--; ++first)
  ::new (static_cast<void*>(addressof(*first)))
    typename iterator_traits<ForwardIterator>::value_type(x);
return first;

23.10.10.7 destroy [specialized.destroy]

template <class T> void destroy_at(T* location);
Effects: Equivalent to:
location->~T();
template <class ForwardIterator> void destroy(ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
for (; first!=last; ++first)
  destroy_at(addressof(*first));
template <class ForwardIterator, class Size> ForwardIterator destroy_n(ForwardIterator first, Size n);
Effects: Equivalent to:
for (; n > 0; (void)++first, --n)
  destroy_at(addressof(*first));
return first;

23.10.11 C library memory allocation [c.malloc]

[Note
:
The header <cstdlib> ([cstdlib.syn]) declares the functions described in this subclause.
end note
]
void* aligned_alloc(size_t alignment, size_t size); void* calloc(size_t nmemb, size_t size); void* malloc(size_t size); void* realloc(void* ptr, size_t size);
Effects: These functions have the semantics specified in the C standard library.
Remarks: These functions do not attempt to allocate storage by calling ​::​operator new() ([support.dynamic]).
Storage allocated directly with these functions is implicitly declared reachable (see [basic.stc.dynamic.safety]) on allocation, ceases to be declared reachable on deallocation, and need not cease to be declared reachable as the result of an undeclare_­reachable() call.
[Note
:
This allows existing C libraries to remain unaffected by restrictions on pointers that are not safely derived, at the expense of providing far fewer garbage collection and leak detection options for malloc()-allocated objects.
It also allows malloc() to be implemented with a separate allocation arena, bypassing the normal declare_­reachable() implementation.
The above functions should never intentionally be used as a replacement for declare_­reachable(), and newly written code is strongly encouraged to treat memory allocated with these functions as though it were allocated with operator new.
end note
]
void free(void* ptr);
Effects: This function has the semantics specified in the C standard library.
Remarks: This function does not attempt to deallocate storage by calling ​::​operator delete().
See also: ISO C 7.
22.
3.

23.11 Smart pointers [smartptr]

23.11.1 Class template unique_­ptr [unique.ptr]

A unique pointer is an object that owns another object and manages that other object through a pointer.
More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose of p when u is itself destroyed (e.g., when leaving block scope ([stmt.dcl])).
In this context, u is said to own p.
The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct invocation results in p's appropriate disposition (typically its deletion).
Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter.
Upon request, u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned object via the associated deleter before such replacement is considered completed.
Additionally, u can, upon request, transfer ownership to another unique pointer u2.
Upon completion of such a transfer, the following postconditions hold:
  • u2.p is equal to the pre-transfer u.p,
  • u.p is equal to nullptr, and
  • if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer associated deleter before the ownership transfer is considered complete.
[Note
:
A deleter's state need never be copied, only moved or swapped as ownership is transferred.
end note
]
Each object of a type U instantiated from the unique_­ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer.
In partial satisfaction of these semantics, each such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
The template parameter T of unique_­ptr may be an incomplete type.
[Note
:
The uses of unique_­ptr include providing exception safety for dynamically allocated memory, passing ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from a function.
end note
]
namespace std {
  template<class T> struct default_delete;
  template<class T> struct default_delete<T[]>;

  template<class T, class D = default_delete<T>> class unique_ptr;
  template<class T, class D> class unique_ptr<T[], D>;

  template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
  template<class T> unique_ptr<T> make_unique(size_t n);
  template<class T, class... Args> unspecified make_unique(Args&&...) = delete;

  template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

  template<class T1, class D1, class T2, class D2>
    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

  template <class T, class D>
    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);

}

23.11.1.1 Default deleters [unique.ptr.dltr]

23.11.1.1.1 In general [unique.ptr.dltr.general]

The class template default_­delete serves as the default deleter (destruction policy) for the class template unique_­ptr.
The template parameter T of default_­delete may be an incomplete type.

23.11.1.1.2 default_­delete [unique.ptr.dltr.dflt]

namespace std {
  template <class T> struct default_delete {
    constexpr default_delete() noexcept = default;
    template <class U> default_delete(const default_delete<U>&) noexcept;
    void operator()(T*) const;
  };
}
template <class U> default_delete(const default_delete<U>& other) noexcept;
Effects: Constructs a default_­delete object from another default_­delete<U> object.
Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible to T*.
void operator()(T* ptr) const;
Effects: Calls delete on ptr.
Remarks: If T is an incomplete type, the program is ill-formed.

23.11.1.1.3 default_­delete<T[]> [unique.ptr.dltr.dflt1]

namespace std {
  template <class T> struct default_delete<T[]> {
    constexpr default_delete() noexcept = default;
    template <class U> default_delete(const default_delete<U[]>&) noexcept;
    template <class U> void operator()(U* ptr) const;
  };
}
template <class U> default_delete(const default_delete<U[]>& other) noexcept;
Effects: constructs a default_­delete object from another default_­delete<U[]> object.
Remarks: This constructor shall not participate in overload resolution unless U(*)[] is convertible to T(*)[].
template <class U> void operator()(U* ptr) const;
Effects: Calls delete[] on ptr.
Remarks: If U is an incomplete type, the program is ill-formed.
This function shall not participate in overload resolution unless U(*)[] is convertible to T(*)[].

23.11.1.2 unique_­ptr for single objects [unique.ptr.single]

namespace std {
  template <class T, class D = default_delete<T>> class unique_ptr {
  public:
    using pointer      = see below;
    using element_type = T;
    using deleter_type = D;

    // [unique.ptr.single.ctor], constructors
    constexpr unique_ptr() noexcept;
    explicit unique_ptr(pointer p) noexcept;
    unique_ptr(pointer p, see below d1) noexcept;
    unique_ptr(pointer p, see below d2) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    constexpr unique_ptr(nullptr_t) noexcept;
    template <class U, class E>
      unique_ptr(unique_ptr<U, E>&& u) noexcept;

    // [unique.ptr.single.dtor], destructor
    ~unique_ptr();

    // [unique.ptr.single.asgn], assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // [unique.ptr.single.observers], observers
    add_lvalue_reference_t<T> operator*() const;
    pointer operator->() const noexcept;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // [unique.ptr.single.modifiers], modifiers
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    void swap(unique_ptr& u) noexcept;

    // disable copy from lvalue
    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;
  };
}
The default type for the template parameter D is default_­delete.
A client-supplied template argument D shall be a function object type ([function.objects]), lvalue reference to function, or lvalue reference to function object type for which, given a value d of type D and a value ptr of type unique_­ptr<T, D>​::​pointer, the expression d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible (Table 27).
If the qualified-id remove_­reference_­t<D>​::​pointer is valid and denotes a type ([temp.deduct]), then unique_­ptr<T, D>​::​pointer shall be a synonym for remove_­reference_­t<D>​::​pointer.
Otherwise unique_­ptr<T, D>​::​pointer shall be a synonym for element_­type*.
The type unique_­ptr<T, D>​::​pointer shall satisfy the requirements of NullablePointer ([nullablepointer.requirements]).
[Example
:
Given an allocator type X ([allocator.requirements]) and letting A be a synonym for allocator_­traits<X>, the types A​::​pointer, A​::​const_­pointer, A​::​void_­pointer, and A​::​const_­void_­pointer may be used as unique_­ptr<T, D>​::​pointer.
end example
]

23.11.1.2.1 unique_­ptr constructors [unique.ptr.single.ctor]

constexpr unique_ptr() noexcept; constexpr unique_ptr(nullptr_t) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible (Table 22), and that construction shall not throw an exception.
Effects: Constructs a unique_­ptr object that owns nothing, value-initializing the stored pointer and the stored deleter.
Postconditions: get() == nullptr.
get_­deleter() returns a reference to the stored deleter.
Remarks: If is_­pointer_­v<deleter_­type> is true or is_­default_­constructible_­v<deleter_­type> is false, this constructor shall not participate in overload resolution.
explicit unique_ptr(pointer p) noexcept;
Requires: D shall satisfy the requirements of DefaultConstructible (Table 22), and that construction shall not throw an exception.
Effects: Constructs a unique_­ptr which owns p, initializing the stored pointer with p and value-initializing the stored deleter.
Postconditions: get() == p.
get_­deleter() returns a reference to the stored deleter.
Remarks: If is_­pointer_­v<deleter_­type> is true or is_­default_­constructible_­v<deleter_­type> is false, this constructor shall not participate in overload resolution.
If class template argument deduction ([over.match.class.deduct]) would select the function template corresponding to this constructor, then the program is ill-formed.
unique_ptr(pointer p, see below d1) noexcept; unique_ptr(pointer p, see below d2) noexcept;
The signature of these constructors depends upon whether D is a reference type.
If D is a non-reference type A, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept;
unique_ptr(pointer p, A&& d) noexcept;
If D is an lvalue reference type A&, then the signatures are:
unique_ptr(pointer p, A& d) noexcept;
unique_ptr(pointer p, A&& d) = delete;
If D is an lvalue reference type const A&, then the signatures are:
unique_ptr(pointer p, const A& d) noexcept;
unique_ptr(pointer p, const A&& d) = delete;
Effects: Constructs a unique_­ptr object which owns p, initializing the stored pointer with p and initializing the deleter from std​::​forward<decltype(d)>(d).
Remarks: These constructors shall not participate in overload resolution unless is_­constructible_­v<D, decltype(d)> is true.
Postconditions: get() == p.
get_­deleter() returns a reference to the stored deleter.
If D is a reference type then get_­deleter() returns a reference to the lvalue d.
Remarks: If class template argument deduction ([over.match.class.deduct]) would select a function template corresponding to either of these constructors, then the program is ill-formed.
[Example
:
D d;
unique_ptr<int, D> p1(new int, D());        // D must be MoveConstructible
unique_ptr<int, D> p2(new int, d);          // D must be CopyConstructible
unique_ptr<int, D&> p3(new int, d);         // p3 holds a reference to d
unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined
                                            // with reference deleter type
end example
]
unique_ptr(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveConstructible (Table 23).
Construction of the deleter from an rvalue of type D shall not throw an exception.
Effects: Constructs a unique_­ptr by transferring ownership from u to *this.
If D is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
[Note
:
The deleter constructor can be implemented with std​::​forward<D>.
end note
]
Postconditions: get() yields the value u.get() yielded before the construction.
get_­deleter() returns a reference to the stored deleter that was constructed from u.get_­deleter().
If D is a reference type then get_­deleter() and u.get_­deleter() both reference the same lvalue deleter.
template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
Requires: If E is not a reference type, construction of the deleter from an rvalue of type E shall be well formed and shall not throw an exception.
Otherwise, E is a reference type and construction of the deleter from an lvalue of type E shall be well formed and shall not throw an exception.
Remarks: This constructor shall not participate in overload resolution unless:
  • unique_­ptr<U, E>​::​pointer is implicitly convertible to pointer,
  • U is not an array type, and
  • either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
Effects: Constructs a unique_­ptr by transferring ownership from u to *this.
If E is a reference type, this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
[Note
:
The deleter constructor can be implemented with std​::​forward<E>.
end note
]
Postconditions: get() yields the value u.get() yielded before the construction.
get_­deleter() returns a reference to the stored deleter that was constructed from u.get_­deleter().

23.11.1.2.2 unique_­ptr destructor [unique.ptr.single.dtor]

~unique_ptr();
Requires: The expression get_­deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
[Note
:
The use of default_­delete requires T to be a complete type.
end note
]
Effects: If get() == nullptr there are no effects.
Otherwise get_­deleter()(get()).

23.11.1.2.3 unique_­ptr assignment [unique.ptr.single.asgn]

unique_ptr& operator=(unique_ptr&& u) noexcept;
Requires: If D is not a reference type, D shall satisfy the requirements of MoveAssignable (Table 25) and assignment of the deleter from an rvalue of type D shall not throw an exception.
Otherwise, D is a reference type; remove_­reference_­t<D> shall satisfy the CopyAssignable requirements and assignment of the deleter from an lvalue of type D shall not throw an exception.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_­deleter() = std​::​forward<D>(u.get_­deleter()).
Returns: *this.
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
Requires: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be well-formed and shall not throw an exception.
Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
Remarks: This operator shall not participate in overload resolution unless:
  • unique_­ptr<U, E>​::​pointer is implicitly convertible to pointer, and
  • U is not an array type, and
  • is_­assignable_­v<D&, E&&> is true.
Effects: Transfers ownership from u to *this as if by calling reset(u.release()) followed by get_­deleter() = std​::​forward<E>(u.get_­deleter()).
Returns: *this.
unique_ptr& operator=(nullptr_t) noexcept;
Effects: As if by reset().
Postconditions: get() == nullptr.
Returns: *this.

23.11.1.2.4 unique_­ptr observers [unique.ptr.single.observers]

add_lvalue_reference_t<T> operator*() const;
Requires: get() != nullptr.
Returns: *get().
pointer operator->() const noexcept;
Requires: get() != nullptr.
Returns: get().
[Note
:
The use of this function typically requires that T be a complete type.
end note
]
pointer get() const noexcept;
Returns: The stored pointer.
deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept;
Returns: A reference to the stored deleter.
explicit operator bool() const noexcept;
Returns: get() != nullptr.

23.11.1.2.5 unique_­ptr modifiers [unique.ptr.single.modifiers]

pointer release() noexcept;
Postconditions: get() == nullptr.
Returns: The value get() had at the start of the call to release.
void reset(pointer p = pointer()) noexcept;
Requires: The expression get_­deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: Assigns p to the stored pointer, and then if and only if the old value of the stored pointer, old_­p, was not equal to nullptr, calls get_­deleter()(old_­p).
[Note
:
The order of these operations is significant because the call to get_­deleter() may destroy *this.
end note
]
Postconditions: get() == p.
[Note
:
The postcondition does not hold if the call to get_­deleter() destroys *this since this->get() is no longer a valid expression.
end note
]
void swap(unique_ptr& u) noexcept;
Requires: get_­deleter() shall be swappable ([swappable.requirements]) and shall not throw an exception under swap.
Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.

23.11.1.3 unique_­ptr for array objects with a runtime length [unique.ptr.runtime]

namespace std {
  template <class T, class D> class unique_ptr<T[], D> {
  public:
    using pointer      = see below;
    using element_type = T;
    using deleter_type = D;

    // [unique.ptr.runtime.ctor], constructors
    constexpr unique_ptr() noexcept;
    template <class U> explicit unique_ptr(U p) noexcept;
    template <class U> unique_ptr(U p, see below d) noexcept;
    template <class U> unique_ptr(U p, see below d) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    template <class U, class E>
      unique_ptr(unique_ptr<U, E>&& u) noexcept;
    constexpr unique_ptr(nullptr_t) noexcept;

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template <class U, class E>
      unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // [unique.ptr.runtime.observers], observers
    T& operator[](size_t i) const;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // [unique.ptr.runtime.modifiers], modifiers
    pointer release() noexcept;
    template <class U> void reset(U p) noexcept;
    void reset(nullptr_t = nullptr) noexcept;
    void swap(unique_ptr& u) noexcept;

    // disable copy from lvalue
    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;
  };
}
A specialization for array types is provided with a slightly altered interface.
  • Conversions between different types of unique_­ptr<T[], D> that would be disallowed for the corresponding pointer-to-array types, and conversions to or from the non-array forms of unique_­ptr, produce an ill-formed program.
  • Pointers to types derived from T are rejected by the constructors, and by reset.
  • The observers operator* and operator-> are not provided.
  • The indexing observer operator[] is provided.
  • The default deleter will call delete[].
Descriptions are provided below only for members that differ from the primary template.
The template argument T shall be a complete type.

23.11.1.3.1 unique_­ptr constructors [unique.ptr.runtime.ctor]

template <class U> explicit unique_ptr(U p) noexcept;
This constructor behaves the same as the constructor in the primary template that takes a single parameter of type pointer except that it additionally shall not participate in overload resolution unless
  • U is the same type as pointer, or
  • pointer is the same type as element_­type*, U is a pointer type V*, and V(*)[] is convertible to element_­type(*)[].
template <class U> unique_ptr(U p, see below d) noexcept; template <class U> unique_ptr(U p, see below d) noexcept;
These constructors behave the same as the constructors in the primary template that take a parameter of type pointer and a second parameter except that they shall not participate in overload resolution unless either
  • U is the same type as pointer,
  • U is nullptr_­t, or
  • pointer is the same type as element_­type*, U is a pointer type V*, and V(*)[] is convertible to element_­type(*)[].
template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
This constructor behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_­ptr<U, E>:
  • U is an array type, and
  • pointer is the same type as element_­type*, and
  • UP​::​pointer is the same type as UP​::​element_­type*, and
  • UP​::​element_­type(*)[] is convertible to element_­type(*)[], and
  • either D is a reference type and E is the same type as D, or D is not a reference type and E is implicitly convertible to D.
[Note
:
This replaces the overload-resolution specification of the primary template
end note
]

23.11.1.3.2 unique_­ptr assignment [unique.ptr.runtime.asgn]

template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u)noexcept;
This operator behaves the same as in the primary template, except that it shall not participate in overload resolution unless all of the following conditions hold, where UP is unique_­ptr<U, E>:
  • U is an array type, and
  • pointer is the same type as element_­type*, and
  • UP​::​pointer is the same type as UP​::​element_­type*, and
  • UP​::​element_­type(*)[] is convertible to element_­type(*)[], and
  • is_­assignable_­v<D&, E&&> is true.
[Note
:
This replaces the overload-resolution specification of the primary template
end note
]

23.11.1.3.3 unique_­ptr observers [unique.ptr.runtime.observers]

T& operator[](size_t i) const;
Requires: i < the number of elements in the array to which the stored pointer points.
Returns: get()[i].

23.11.1.3.4 unique_­ptr modifiers [unique.ptr.runtime.modifiers]

void reset(nullptr_t p = nullptr) noexcept;
Effects: Equivalent to reset(pointer()).
template <class U> void reset(U p) noexcept;
This function behaves the same as the reset member of the primary template, except that it shall not participate in overload resolution unless either
  • U is the same type as pointer, or
  • pointer is the same type as element_­type*, U is a pointer type V*, and V(*)[] is convertible to element_­type(*)[].

23.11.1.4 unique_­ptr creation [unique.ptr.create]

template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
Remarks: This function shall not participate in overload resolution unless T is not an array.
Returns: unique_­ptr<T>(new T(std​::​forward<Args>(args)...)).
template <class T> unique_ptr<T> make_unique(size_t n);
Remarks: This function shall not participate in overload resolution unless T is an array of unknown bound.
Returns: unique_­ptr<T>(new remove_­extent_­t<T>[n]()).
template <class T, class... Args> unspecified make_unique(Args&&...) = delete;
Remarks: This function shall not participate in overload resolution unless T is an array of known bound.

23.11.1.5 unique_­ptr specialized algorithms [unique.ptr.special]

template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<D> is true.
Effects: Calls x.swap(y).
template <class T1, class D1, class T2, class D2> bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: x.get() == y.get().
template <class T1, class D1, class T2, class D2> bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: x.get() != y.get().
template <class T1, class D1, class T2, class D2> bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Requires: Let CT denote
common_type_t<typename unique_ptr<T1, D1>::pointer,
              typename unique_ptr<T2, D2>::pointer>
Then the specialization less<CT> shall be a function object type ([function.objects]) that induces a strict weak ordering ([alg.sorting]) on the pointer values.
Returns: less<CT>()(x.get(), y.get()).
Remarks: If unique_­ptr<T1, D1>​::​pointer is not implicitly convertible to CT or unique_­ptr<T2, D2>​::​pointer is not implicitly convertible to CT, the program is ill-formed.
template <class T1, class D1, class T2, class D2> bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: !(y < x).
template <class T1, class D1, class T2, class D2> bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: y < x.
template <class T1, class D1, class T2, class D2> bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
Returns: !(x < y).
template <class T, class D> bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator==(nullptr_t, const unique_ptr<T, D>& x) noexcept;
Returns: !x.
template <class T, class D> bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator!=(nullptr_t, const unique_ptr<T, D>& x) noexcept;
Returns: (bool)x.
template <class T, class D> bool operator<(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<(nullptr_t, const unique_ptr<T, D>& x);
Requires: The specialization less<unique_­ptr<T, D>​::​pointer> shall be a function object type ([function.objects]) that induces a strict weak ordering ([alg.sorting]) on the pointer values.
Returns: The first function template returns less<unique_­ptr<T, D>​::​pointer>()(x.get(),
nullptr)
.
The second function template returns less<unique_­ptr<T, D>​::​pointer>()(nullptr, x.get()).
template <class T, class D> bool operator>(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns nullptr < x.
The second function template returns x < nullptr.
template <class T, class D> bool operator<=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<=(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns !(nullptr < x).
The second function template returns !(x < nullptr).
template <class T, class D> bool operator>=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>=(nullptr_t, const unique_ptr<T, D>& x);
Returns: The first function template returns !(x < nullptr).
The second function template returns !(nullptr < x).

23.11.2 Shared-ownership pointers [util.smartptr]

23.11.2.1 Class bad_­weak_­ptr [util.smartptr.weak.bad]

namespace std {
  class bad_weak_ptr : public exception {
  public:
    bad_weak_ptr() noexcept;
  };
}
An exception of type bad_­weak_­ptr is thrown by the shared_­ptr constructor taking a weak_­ptr.
bad_weak_ptr() noexcept;
Postconditions: what() returns an implementation-defined ntbs.

23.11.2.2 Class template shared_­ptr [util.smartptr.shared]

The shared_­ptr class template stores a pointer, usually obtained via new.
shared_­ptr implements semantics of shared ownership; the last remaining owner of the pointer is responsible for destroying the object, or otherwise releasing the resources associated with the stored pointer.
A shared_­ptr is said to be empty if it does not own a pointer.
namespace std {
  template<class T> class shared_ptr {
  public:
    using element_type = remove_extent_t<T>;
    using weak_type    = weak_ptr<T>;

    // [util.smartptr.shared.const], constructors
    constexpr shared_ptr() noexcept;
    template<class Y> explicit shared_ptr(Y* p);
    template<class Y, class D> shared_ptr(Y* p, D d);
    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
    template <class D> shared_ptr(nullptr_t p, D d);
    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
    template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
    shared_ptr(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
    shared_ptr(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
    constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }

    // [util.smartptr.shared.dest], destructor
    ~shared_ptr();

    // [util.smartptr.shared.assign], assignment
    shared_ptr& operator=(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    shared_ptr& operator=(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);

    // [util.smartptr.shared.mod], modifiers
    void swap(shared_ptr& r) noexcept;
    void reset() noexcept;
    template<class Y> void reset(Y* p);
    template<class Y, class D> void reset(Y* p, D d);
    template<class Y, class D, class A> void reset(Y* p, D d, A a);

    // [util.smartptr.shared.obs], observers
    element_type* get() const noexcept;
    T& operator*() const noexcept;
    T* operator->() const noexcept;
    element_type& operator[](ptrdiff_t i) const;
    long use_count() const noexcept;
    explicit operator bool() const noexcept;
    template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
    template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
  };

  template<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
  template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;

  // [util.smartptr.shared.create], shared_­ptr creation
  template<class T, class... Args>
    shared_ptr<T> make_shared(Args&&... args);
  template<class T, class A, class... Args>
    shared_ptr<T> allocate_shared(const A& a, Args&&... args);

  // [util.smartptr.shared.cmp], shared_­ptr comparisons
  template<class T, class U>
    bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
  template<class T, class U>
    bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;

  template <class T>
    bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator==(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator!=(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator!=(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator<(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator<(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator<=(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator<=(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator>(nullptr_t, const shared_ptr<T>& b) noexcept;
  template <class T>
    bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept;
  template <class T>
    bool operator>=(nullptr_t, const shared_ptr<T>& b) noexcept;

  // [util.smartptr.shared.spec], shared_­ptr specialized algorithms
  template<class T>
    void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;

  // [util.smartptr.shared.cast], shared_­ptr casts
  template<class T, class U>
    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
  template<class T, class U>
    shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;

  // [util.smartptr.getdeleter], shared_­ptr get_­deleter
  template<class D, class T>
    D* get_deleter(const shared_ptr<T>& p) noexcept;

  // [util.smartptr.shared.io], shared_­ptr I/O
  template<class E, class T, class Y>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
}
Specializations of shared_­ptr shall be CopyConstructible, CopyAssignable, and LessThanComparable, allowing their use in standard containers.
Specializations of shared_­ptr shall be contextually convertible to bool, allowing their use in boolean expressions and declarations in conditions.
The template parameter T of shared_­ptr may be an incomplete type.
[Example
:
if (shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
  // do something with px
}
end example
]
For purposes of determining the presence of a data race, member functions shall access and modify only the shared_­ptr and weak_­ptr objects themselves and not objects they refer to.
Changes in use_­count() do not reflect modifications that can introduce data races.
For the purposes of subclause [util.smartptr], a pointer type Y* is said to be compatible with a pointer type T* when either Y* is convertible to T* or Y is U[N] and T is cv U[].

23.11.2.2.1 shared_­ptr constructors [util.smartptr.shared.const]

In the constructor definitions below, enables shared_­from_­this with p, for a pointer p of type Y*, means that if Y has an unambiguous and accessible base class that is a specialization of enable_­shared_­from_­this ([util.smartptr.enab]), then remove_­cv_­t<Y>* shall be implicitly convertible to T* and the constructor evaluates the statement:
if (p != nullptr && p->weak_this.expired())
  p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
The assignment to the weak_­this member is not atomic and conflicts with any potentially concurrent access to the same object ([intro.multithread]).
constexpr shared_ptr() noexcept;
Effects: Constructs an empty shared_­ptr object.
Postconditions: use_­count() == 0 && get() == nullptr.
template<class Y> explicit shared_ptr(Y* p);
Requires: Y shall be a complete type.
The expression delete[] p, when T is an array type, or delete p, when T is not an array type, shall have well-defined behavior, and shall not throw exceptions.
Effects: When T is not an array type, constructs a shared_­ptr object that owns the pointer p.
Otherwise, constructs a shared_­ptr that owns p and a deleter of an unspecified type that calls delete[] p.
When T is not an array type, enables shared_­from_­this with p.
If an exception is thrown, delete p is called when T is not an array type, delete[] p otherwise.
Postconditions: use_­count() == 1 && get() == p.
Throws: bad_­alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
Remarks: When T is an array type, this constructor shall not participate in overload resolution unless the expression delete[] p is well-formed and either T is U[N] and Y(*)[N] is convertible to T*, or T is U[] and Y(*)[] is convertible to T*.
When T is not an array type, this constructor shall not participate in overload resolution unless the expression delete p is well-formed and Y* is convertible to T*.
template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template <class D> shared_ptr(nullptr_t p, D d); template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
Requires: Construction of d and a deleter of type D initialized with std​::​move(d) shall not throw exceptions.
The expression d(p) shall have well-defined behavior and shall not throw exceptions.
A shall be an allocator ([allocator.requirements]).
Effects: Constructs a shared_­ptr object that owns the object p and the deleter d.
When T is not an array type, the first and second constructors enable shared_­from_­this with p.
The second and fourth constructors shall use a copy of a to allocate memory for internal use.
If an exception is thrown, d(p) is called.
Postconditions: use_­count() == 1 && get() == p.
Throws: bad_­alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
Remarks: When T is an array type, this constructor shall not participate in overload resolution unless is_­move_­constructible_­v<D> is true, the expression d(p) is well-formed, and either T is U[N] and Y(*)[N] is convertible to T*, or T is U[] and Y(*)[] is convertible to T*.
When T is not an array type, this constructor shall not participate in overload resolution unless is_­move_­constructible_­v<D> is true, the expression d(p) is well-formed, and Y* is convertible to T*.
template<class Y> shared_ptr(const shared_ptr<Y>& r, element_type* p) noexcept;
Effects: Constructs a shared_­ptr instance that stores p and shares ownership with r.
Postconditions: get() == p && use_­count() == r.use_­count().
[Note
:
To avoid the possibility of a dangling pointer, the user of this constructor must ensure that p remains valid at least until the ownership group of r is destroyed.
end note
]
[Note
:
This constructor allows creation of an empty shared_­ptr instance with a non-null stored pointer.
end note
]
shared_ptr(const shared_ptr& r) noexcept; template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
Effects: If r is empty, constructs an empty shared_­ptr object; otherwise, constructs a shared_­ptr object that shares ownership with r.
Postconditions: get() == r.get() && use_­count() == r.use_­count().
shared_ptr(shared_ptr&& r) noexcept; template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
Effects: Move constructs a shared_­ptr instance from r.
Postconditions: *this shall contain the old value of r.
r shall be empty.
r.get() == nullptr.
template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
Effects: Constructs a shared_­ptr object that shares ownership with r and stores a copy of the pointer stored in r.
If an exception is thrown, the constructor has no effect.
Postconditions: use_­count() == r.use_­count().
Throws: bad_­weak_­ptr when r.expired().
Remarks: This constructor shall not participate in overload resolution unless Y* is compatible with T*.
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
Remarks: This constructor shall not participate in overload resolution unless Y* is compatible with T* and unique_­ptr<Y, D>​::​pointer is convertible to element_­type*.
Effects: If r.get() == nullptr, equivalent to shared_­ptr().
Otherwise, if D is not a reference type, equivalent to shared_­ptr(r.release(), r.get_­deleter()).
Otherwise, equivalent to shared_­ptr(r.release(), ref(r.get_­deleter())).
If an exception is thrown, the constructor has no effect.

23.11.2.2.2 shared_­ptr destructor [util.smartptr.shared.dest]

~shared_ptr();
Effects:
  • If *this is empty or shares ownership with another shared_­ptr instance (use_­count() > 1), there are no side effects.
  • Otherwise, if *this owns an object p and a deleter d, d(p) is called.
  • Otherwise, *this owns a pointer p, and delete p is called.
[Note
:
Since the destruction of *this decreases the number of instances that share ownership with *this by one, after *this has been destroyed all shared_­ptr instances that shared ownership with *this will report a use_­count() that is one less than its previous value.
end note
]

23.11.2.2.3 shared_­ptr assignment [util.smartptr.shared.assign]

shared_ptr& operator=(const shared_ptr& r) noexcept; template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Effects: Equivalent to shared_­ptr(r).swap(*this).
Returns: *this.
[Note
:
The use count updates caused by the temporary object construction and destruction are not observable side effects, so the implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary.
In particular, in the example:
shared_ptr<int> p(new int);
shared_ptr<void> q(p);
p = p;
q = p;
both assignments may be no-ops.
end note
]
shared_ptr& operator=(shared_ptr&& r) noexcept; template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
Effects: Equivalent to shared_­ptr(std​::​move(r)).swap(*this).
Returns: *this.
template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
Effects: Equivalent to shared_­ptr(std​::​move(r)).swap(*this).
Returns: *this.

23.11.2.2.4 shared_­ptr modifiers [util.smartptr.shared.mod]

void swap(shared_ptr& r) noexcept;
Effects: Exchanges the contents of *this and r.
void reset() noexcept;
Effects: Equivalent to shared_­ptr().swap(*this).
template<class Y> void reset(Y* p);
Effects: Equivalent to shared_­ptr(p).swap(*this).
template<class Y, class D> void reset(Y* p, D d);
Effects: Equivalent to shared_­ptr(p, d).swap(*this).
template<class Y, class D, class A> void reset(Y* p, D d, A a);
Effects: Equivalent to shared_­ptr(p, d, a).swap(*this).

23.11.2.2.5 shared_­ptr observers [util.smartptr.shared.obs]

element_type* get() const noexcept;
Returns: The stored pointer.
T& operator*() const noexcept;
Requires: get() != 0.
Returns: *get().
Remarks: When T is an array type or cv void, it is unspecified whether this member function is declared.
If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
T* operator->() const noexcept;
Requires: get() != 0.
Returns: get().
Remarks: When T is an array type, it is unspecified whether this member function is declared.
If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
element_type& operator[](ptrdiff_t i) const;
Requires: get() != 0 && i >= 0.
If T is U[N], i < N.
Returns: get()[i].
Remarks: When T is not an array type, it is unspecified whether this member function is declared.
If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
Throws: Nothing.
long use_count() const noexcept;
Returns: The number of shared_­ptr objects, *this included, that share ownership with *this, or 0 when *this is empty.
Synchronization: None.
[Note
:
get() == nullptr does not imply a specific return value of use_­count().
end note
]
[Note
:
weak_­ptr<T>​::​lock() can affect the return value of use_­count().
end note
]
[Note
:
When multiple threads can affect the return value of use_­count(), the result should be treated as approximate.
In particular, use_­count() == 1 does not imply that accesses through a previously destroyed shared_­ptr have in any sense completed.
end note
]
explicit operator bool() const noexcept;
Returns: get() != 0.
template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept; template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;
Returns: An unspecified value such that
  • x.owner_­before(y) defines a strict weak ordering as defined in [alg.sorting];
  • under the equivalence relation defined by owner_­before, !a.owner_­before(b) && !b.owner_­before(a), two shared_­ptr or weak_­ptr instances are equivalent if and only if they share ownership or are both empty.

23.11.2.2.6 shared_­ptr creation [util.smartptr.shared.create]

template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args); template<class T, class A, class... Args> shared_ptr<T> allocate_shared(const A& a, Args&&... args);
Requires: The expression ​::​new (pv) T(std​::​forward<Args>(args)...), where pv has type void* and points to storage suitable to hold an object of type T, shall be well formed.
A shall be an allocator ([allocator.requirements]).
The copy constructor and destructor of A shall not throw exceptions.
Effects: Allocates memory suitable for an object of type T and constructs an object in that memory via the placement new-expression ​::​new (pv) T(std​::​forward<Args>(args)...).
The template allocate_­shared uses a copy of a to allocate memory.
If an exception is thrown, the functions have no effect.
Returns: A shared_­ptr instance that stores and owns the address of the newly constructed object of type T.
Postconditions: get() != 0 && use_­count() == 1.
Throws: bad_­alloc, or an exception thrown from A​::​allocate or from the constructor of T.
Remarks: The shared_­ptr constructor called by this function enables shared_­from_­this with the address of the newly constructed object of type T.
Implementations should perform no more than one memory allocation.
[Note
:
This provides efficiency equivalent to an intrusive smart pointer.
end note
]
[Note
:
These functions will typically allocate more memory than sizeof(T) to allow for internal bookkeeping structures such as the reference counts.
end note
]

23.11.2.2.7 shared_­ptr comparison [util.smartptr.shared.cmp]

template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
Returns: a.get() == b.get().
template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
Returns: less<>()(a.get(), b.get()).
[Note
:
Defining a comparison function allows shared_­ptr objects to be used as keys in associative containers.
end note
]
template <class T> bool operator==(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator==(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: !a.
template <class T> bool operator!=(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator!=(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: (bool)a.
template <class T> bool operator<(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator<(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns less<shared_­ptr<T>​::​element_­type*>()(a.get(), nullptr).
The second function template returns less<shared_­ptr<T>​::​element_­type*>()(nullptr, a.get()).
template <class T> bool operator>(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator>(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns nullptr < a.
The second function template returns a < nullptr.
template <class T> bool operator<=(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator<=(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns !(nullptr < a).
The second function template returns !(a < nullptr).
template <class T> bool operator>=(const shared_ptr<T>& a, nullptr_t) noexcept; template <class T> bool operator>=(nullptr_t, const shared_ptr<T>& a) noexcept;
Returns: The first function template returns !(a < nullptr).
The second function template returns !(nullptr < a).

23.11.2.2.8 shared_­ptr specialized algorithms [util.smartptr.shared.spec]

template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
Effects: Equivalent to a.swap(b).

23.11.2.2.9 shared_­ptr casts [util.smartptr.shared.cast]

template<class T, class U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression static_­cast<T*>((U*)0) shall be well formed.
Returns:
shared_ptr<T>(r, static_cast<typename shared_ptr<T>::element_type*>(r.get()))
[Note
:
The seemingly equivalent expression shared_­ptr<T>(static_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression dynamic_­cast<T*>((U*)0) shall be well formed and shall have well defined behavior.
Returns:
  • When dynamic_­cast<typename shared_­ptr<T>​::​element_­type*>(r.get()) returns a nonzero value p, shared_­ptr<T>(r, p).
  • Otherwise, shared_­ptr<T>().
[Note
:
The seemingly equivalent expression shared_­ptr<T>(dynamic_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]
template<class T, class U> shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression const_­cast<T*>((U*)0) shall be well formed.
Returns:
shared_ptr<T>(r, const_cast<typename shared_ptr<T>::element_type*>(r.get()))
[Note
:
The seemingly equivalent expression shared_­ptr<T>(const_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]
template<class T, class U> shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
Requires: The expression reinterpret_­cast<T*>((U*)0) shall be well formed.
Returns:
shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()))
[Note
:
The seemingly equivalent expression shared_­ptr<T>(reinterpret_­cast<T*>(r.get())) will eventually result in undefined behavior, attempting to delete the same object twice.
end note
]

23.11.2.2.10 get_­deleter [util.smartptr.getdeleter]

template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
Returns: If p owns a deleter d of type cv-unqualified D, returns addressof(d); otherwise returns nullptr.
The returned pointer remains valid as long as there exists a shared_­ptr instance that owns d.
[Note
:
It is unspecified whether the pointer remains valid longer than that.
This can happen if the implementation doesn't destroy the deleter until all weak_­ptr instances that share ownership with p have been destroyed.
end note
]

23.11.2.2.11 shared_­ptr I/O [util.smartptr.shared.io]

template<class E, class T, class Y> basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, const shared_ptr<Y>& p);
Effects: As if by: os << p.get();
Returns: os.

23.11.2.3 Class template weak_­ptr [util.smartptr.weak]

The weak_­ptr class template stores a weak reference to an object that is already managed by a shared_­ptr.
To access the object, a weak_­ptr can be converted to a shared_­ptr using the member function lock.
namespace std {
  template<class T> class weak_ptr {
  public:
    using element_type = T;

    // [util.smartptr.weak.const], constructors
    constexpr weak_ptr() noexcept;
    template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
    weak_ptr(const weak_ptr& r) noexcept;
    template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
    weak_ptr(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;

    // [util.smartptr.weak.dest], destructor
    ~weak_ptr();

    // [util.smartptr.weak.assign], assignment
    weak_ptr& operator=(const weak_ptr& r) noexcept;
    template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
    template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    weak_ptr& operator=(weak_ptr&& r) noexcept;
    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;

    // [util.smartptr.weak.mod], modifiers
    void swap(weak_ptr& r) noexcept;
    void reset() noexcept;

    // [util.smartptr.weak.obs], observers
    long use_count() const noexcept;
    bool expired() const noexcept;
    shared_ptr<T> lock() const noexcept;
    template<class U> bool owner_before(const shared_ptr<U>& b) const;
    template<class U> bool owner_before(const weak_ptr<U>& b) const;
  };

  template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;


  // [util.smartptr.weak.spec], specialized algorithms
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
}
Specializations of weak_­ptr shall be CopyConstructible and CopyAssignable, allowing their use in standard containers.
The template parameter T of weak_­ptr may be an incomplete type.

23.11.2.3.1 weak_­ptr constructors [util.smartptr.weak.const]

constexpr weak_ptr() noexcept;
Effects: Constructs an empty weak_­ptr object.
Postconditions: use_­count() == 0.
weak_ptr(const weak_ptr& r) noexcept; template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
Remarks: The second and third constructors shall not participate in overload resolution unless Y* is compatible with T*.
Effects: If r is empty, constructs an empty weak_­ptr object; otherwise, constructs a weak_­ptr object that shares ownership with r and stores a copy of the pointer stored in r.
Postconditions: use_­count() == r.use_­count().
weak_ptr(weak_ptr&& r) noexcept; template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
Remarks: The second constructor shall not participate in overload resolution unless Y* is compatible with T*.
Effects: Move constructs a weak_­ptr instance from r.
Postconditions: *this shall contain the old value of r.
r shall be empty.
r.use_­count() == 0.

23.11.2.3.2 weak_­ptr destructor [util.smartptr.weak.dest]

~weak_ptr();
Effects: Destroys this weak_­ptr object but has no effect on the object its stored pointer points to.

23.11.2.3.3 weak_­ptr assignment [util.smartptr.weak.assign]

weak_ptr& operator=(const weak_ptr& r) noexcept; template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept; template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Effects: Equivalent to weak_­ptr(r).swap(*this).
Remarks: The implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary.
Returns: *this.
weak_ptr& operator=(weak_ptr&& r) noexcept; template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
Effects: Equivalent to weak_­ptr(std​::​move(r)).swap(*this).
Returns: *this.

23.11.2.3.4 weak_­ptr modifiers [util.smartptr.weak.mod]

void swap(weak_ptr& r) noexcept;
Effects: Exchanges the contents of *this and r.
void reset() noexcept;
Effects: Equivalent to weak_­ptr().swap(*this).

23.11.2.3.5 weak_­ptr observers [util.smartptr.weak.obs]

long use_count() const noexcept;
Returns: 0 if *this is empty; otherwise, the number of shared_­ptr instances that share ownership with *this.
bool expired() const noexcept;
Returns: use_­count() == 0.
shared_ptr<T> lock() const noexcept;
Returns: expired() ? shared_­ptr<T>() : shared_­ptr<T>(*this), executed atomically.
template<class U> bool owner_before(const shared_ptr<U>& b) const; template<class U> bool owner_before(const weak_ptr<U>& b) const;
Returns: An unspecified value such that
  • x.owner_­before(y) defines a strict weak ordering as defined in [alg.sorting];
  • under the equivalence relation defined by owner_­before, !a.owner_­before(b) && !b.owner_­before(a), two shared_­ptr or weak_­ptr instances are equivalent if and only if they share ownership or are both empty.

23.11.2.3.6 weak_­ptr specialized algorithms [util.smartptr.weak.spec]

template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
Effects: Equivalent to a.swap(b).

23.11.2.4 Class template owner_­less [util.smartptr.ownerless]

The class template owner_­less allows ownership-based mixed comparisons of shared and weak pointers.
namespace std {
  template<class T = void> struct owner_less;

  template<class T> struct owner_less<shared_ptr<T>> {
    bool operator()(const shared_ptr<T>&, const shared_ptr<T>&) const noexcept;
    bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
    bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
  };

  template<class T> struct owner_less<weak_ptr<T>> {
    bool operator()(const weak_ptr<T>&, const weak_ptr<T>&) const noexcept;
    bool operator()(const shared_ptr<T>&, const weak_ptr<T>&) const noexcept;
    bool operator()(const weak_ptr<T>&, const shared_ptr<T>&) const noexcept;
  };

  template<> struct owner_less<void> {
    template<class T, class U>
      bool operator()(const shared_ptr<T>&, const shared_ptr<U>&) const noexcept;
    template<class T, class U>
      bool operator()(const shared_ptr<T>&, const weak_ptr<U>&) const noexcept;
    template<class T, class U>
      bool operator()(const weak_ptr<T>&, const shared_ptr<U>&) const noexcept;
    template<class T, class U>
      bool operator()(const weak_ptr<T>&, const weak_ptr<U>&) const noexcept;

    using is_transparent = unspecified;
  };
}
operator()(x, y) shall return x.owner_­before(y).
[Note
:
Note that
  • operator() defines a strict weak ordering as defined in [alg.sorting];
  • under the equivalence relation defined by operator(), !operator()(a, b) && !operator()(b, a), two shared_­ptr or weak_­ptr instances are equivalent if and only if they share ownership or are both empty.
end note
]

23.11.2.5 Class template enable_­shared_­from_­this [util.smartptr.enab]

A class T can inherit from enable_­shared_­from_­this<T> to inherit the shared_­from_­this member functions that obtain a shared_­ptr instance pointing to *this.
[Example
:
struct X: public enable_shared_from_this<X> { };

int main() {
  shared_ptr<X> p(new X);
  shared_ptr<X> q = p->shared_from_this();
  assert(p == q);
  assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
}
end example
]
namespace std {
  template<class T> class enable_shared_from_this {
  protected:
    constexpr enable_shared_from_this() noexcept;
    enable_shared_from_this(const enable_shared_from_this&) noexcept;
    enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
    ~enable_shared_from_this();
  public:
    shared_ptr<T> shared_from_this();
    shared_ptr<T const> shared_from_this() const;
    weak_ptr<T> weak_from_this() noexcept;
    weak_ptr<T const> weak_from_this() const noexcept;
  private:
    mutable weak_ptr<T> weak_this; // exposition only
  };
}
The template parameter T of enable_­shared_­from_­this may be an incomplete type.
constexpr enable_shared_from_this() noexcept; enable_shared_from_this(const enable_shared_from_this<T>&) noexcept;
Effects: Value-initializes weak_­this.
enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
Returns: *this.
[Note
:
weak_­this is not changed.
end note
]
shared_ptr<T> shared_from_this(); shared_ptr<T const> shared_from_this() const;
Returns: shared_­ptr<T>(weak_­this).
weak_ptr<T> weak_from_this() noexcept; weak_ptr<T const> weak_from_this() const noexcept;
Returns: weak_­this.

23.11.2.6 shared_­ptr atomic access [util.smartptr.shared.atomic]

Concurrent access to a shared_­ptr object from multiple threads does not introduce a data race if the access is done exclusively via the functions in this section and the instance is passed as their first argument.
The meaning of the arguments of type memory_­order is explained in [atomics.order].
template<class T> bool atomic_is_lock_free(const shared_ptr<T>* p);
Requires: p shall not be null.
Returns: true if atomic access to *p is lock-free, false otherwise.
Throws: Nothing.
template<class T> shared_ptr<T> atomic_load(const shared_ptr<T>* p);
Requires: p shall not be null.
Returns: atomic_­load_­explicit(p, memory_­order_­seq_­cst).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
Requires: p shall not be null.
Requires: mo shall not be memory_­order_­release or memory_­order_­acq_­rel.
Returns: *p.
Throws: Nothing.
template<class T> void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
Requires: p shall not be null.
Effects: As if by atomic_­store_­explicit(p, r, memory_­order_­seq_­cst).
Throws: Nothing.
template<class T> void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
Requires: p shall not be null.
Requires: mo shall not be memory_­order_­acquire or memory_­order_­acq_­rel.
Effects: As if by p->swap(r).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
Requires: p shall not be null.
Returns: atomic_­exchange_­explicit(p, r, memory_­order_­seq_­cst).
Throws: Nothing.
template<class T> shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
Requires: p shall not be null.
Effects: As if by p->swap(r).
Returns: The previous value of *p.
Throws: Nothing.
template<class T> bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
Requires: p shall not be null and v shall not be null.
Returns:
atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)
Throws: Nothing.
template<class T> bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
Returns:
atomic_compare_exchange_strong_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)
template<class T> bool atomic_compare_exchange_weak_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure); template<class T> bool atomic_compare_exchange_strong_explicit( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure);
Requires: p shall not be null and v shall not be null.
The failure argument shall not be memory_­order_­release nor memory_­order_­acq_­rel.
Effects: If *p is equivalent to *v, assigns w to *p and has synchronization semantics corresponding to the value of success, otherwise assigns *p to *v and has synchronization semantics corresponding to the value of failure.
Returns: true if *p was equivalent to *v, false otherwise.
Throws: Nothing.
Remarks: Two shared_­ptr objects are equivalent if they store the same pointer value and share ownership.
The weak form may fail spuriously.

23.11.2.7 Smart pointer hash support [util.smartptr.hash]

template <class T, class D> struct hash<unique_ptr<T, D>>;
Letting UP be unique_­ptr<T,D>, the specialization hash<UP> is enabled ([unord.hash]) if and only if hash<typename UP​::​pointer> is enabled.
When enabled, for an object p of type UP, hash<UP>()(p) shall evaluate to the same value as hash<typename UP​::​pointer>()(p.get()).
The member functions are not guaranteed to be noexcept.
template <class T> struct hash<shared_ptr<T>>;
For an object p of type shared_­ptr<T>, hash<shared_­ptr<T>>()(p) shall evaluate to the same value as hash<typename shared_­ptr<T>​::​element_­type*>()(p.get()).

23.12 Memory resources [mem.res]

23.12.1 Header <memory_­resource> synopsis [mem.res.syn]

namespace std::pmr {
  // [mem.res.class], class memory_­resource
  class memory_resource;

  bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
  bool operator!=(const memory_resource& a, const memory_resource& b) noexcept;

  // [mem.poly.allocator.class], class template polymorphic_­allocator
  template <class Tp> class polymorphic_allocator;

  template <class T1, class T2>
    bool operator==(const polymorphic_allocator<T1>& a,
                    const polymorphic_allocator<T2>& b) noexcept;
  template <class T1, class T2>
    bool operator!=(const polymorphic_allocator<T1>& a,
                    const polymorphic_allocator<T2>& b) noexcept;

  // [mem.res.global], global memory resources
  memory_resource* new_delete_resource() noexcept;
  memory_resource* null_memory_resource() noexcept;
  memory_resource* set_default_resource(memory_resource* r) noexcept;
  memory_resource* get_default_resource() noexcept;

  // [mem.res.pool], pool resource classes
  struct pool_options;
  class synchronized_pool_resource;
  class unsynchronized_pool_resource;
  class monotonic_buffer_resource;
}

23.12.2 Class memory_­resource [mem.res.class]

The memory_­resource class is an abstract interface to an unbounded set of classes encapsulating memory resources.
class memory_resource {
  static constexpr size_t max_align = alignof(max_align_t); // exposition only

public:
  virtual ~memory_resource();

  void* allocate(size_t bytes, size_t alignment = max_align);
  void deallocate(void* p, size_t bytes, size_t alignment = max_align);

  bool is_equal(const memory_resource& other) const noexcept;

private:
  virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
  virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;

  virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
};

23.12.2.1 memory_­resource public member functions [mem.res.public]

~memory_resource();
Effects: Destroys this memory_­resource.
void* allocate(size_t bytes, size_t alignment = max_align);
Effects: Equivalent to: return do_­allocate(bytes, alignment);
void deallocate(void* p, size_t bytes, size_t alignment = max_align);
Effects: Equivalent to: do_­deallocate(p, bytes, alignment);
bool is_equal(const memory_resource& other) const noexcept;
Effects: Equivalent to: return do_­is_­equal(other);

23.12.2.2 memory_­resource private virtual member functions [mem.res.private]

virtual void* do_allocate(size_t bytes, size_t alignment) = 0;
Requires: alignment shall be a power of two.
Returns: A derived class shall implement this function to return a pointer to allocated storage ([basic.stc.dynamic.deallocation]) with a size of at least bytes.
The returned storage is aligned to the specified alignment, if such alignment is supported ([basic.align]); otherwise it is aligned to max_­align.
Throws: A derived class implementation shall throw an appropriate exception if it is unable to allocate memory with the requested size and alignment.
virtual void do_deallocate(void* p, size_t bytes, size_t alignment) = 0;
Requires: p shall have been returned from a prior call to allocate(bytes, alignment) on a memory resource equal to *this, and the storage at p shall not yet have been deallocated.
Effects: A derived class shall implement this function to dispose of allocated storage.
Throws: Nothing.
virtual bool do_is_equal(const memory_resource& other) const noexcept = 0;
Returns: A derived class shall implement this function to return true if memory allocated from this can be deallocated from other and vice-versa, otherwise false.
[Note
:
The most-derived type of other might not match the type of this.
For a derived class D, a typical implementation of this function will immediately return false if dynamic_­cast<const D*>(&other) == nullptr.
end note
]

23.12.2.3 memory_­resource equality [mem.res.eq]

bool operator==(const memory_resource& a, const memory_resource& b) noexcept;
Returns: &a == &b || a.is_­equal(b).
bool operator!=(const memory_resource& a, const memory_resource& b) noexcept;
Returns: !(a == b).

23.12.3 Class template polymorphic_­allocator [mem.poly.allocator.class]

A specialization of class template pmr​::​polymorphic_­allocator conforms to the Allocator requirements ([allocator.requirements]).
Constructed with different memory resources, different instances of the same specialization of pmr​::​polymorphic_­allocator can exhibit entirely different allocation behavior.
This runtime polymorphism allows objects that use polymorphic_­allocator to behave as if they used different allocator types at run time even though they use the same static allocator type.
template <class Tp>
class polymorphic_allocator {
  memory_resource* memory_rsrc; // exposition only

public:
  using value_type = Tp;

  // [mem.poly.allocator.ctor], constructors
  polymorphic_allocator() noexcept;
  polymorphic_allocator(memory_resource* r);

  polymorphic_allocator(const polymorphic_allocator& other) = default;

  template <class U>
    polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;

  polymorphic_allocator&
    operator=(const polymorphic_allocator& rhs) = delete;

  // [mem.poly.allocator.mem], member functions
  Tp* allocate(size_t n);
  void deallocate(Tp* p, size_t n);

  template <class T, class... Args>
  void construct(T* p, Args&&... args);

  template <class T1, class T2, class... Args1, class... Args2>
    void construct(pair<T1,T2>* p, piecewise_construct_t,
                   tuple<Args1...> x, tuple<Args2...> y);
  template <class T1, class T2>
    void construct(pair<T1,T2>* p);
  template <class T1, class T2, class U, class V>
    void construct(pair<T1,T2>* p, U&& x, V&& y);
  template <class T1, class T2, class U, class V>
    void construct(pair<T1,T2>* p, const pair<U, V>& pr);
  template <class T1, class T2, class U, class V>
    void construct(pair<T1,T2>* p, pair<U, V>&& pr);

  template <class T>
    void destroy(T* p);

  polymorphic_allocator select_on_container_copy_construction() const;

  memory_resource* resource() const;
};

23.12.3.1 polymorphic_­allocator constructors [mem.poly.allocator.ctor]

polymorphic_allocator() noexcept;
Effects: Sets memory_­rsrc to get_­default_­resource().
polymorphic_allocator(memory_resource* r);
Requires: r is non-null.
Effects: Sets memory_­rsrc to r.
Throws: Nothing.
[Note
:
This constructor provides an implicit conversion from memory_­resource*.
end note
]
template <class U> polymorphic_allocator(const polymorphic_allocator<U>& other) noexcept;
Effects: Sets memory_­rsrc to other.resource().

23.12.3.2 polymorphic_­allocator member functions [mem.poly.allocator.mem]

Tp* allocate(size_t n);
Returns: Equivalent to
return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));
void deallocate(Tp* p, size_t n);
Requires: p was allocated from a memory resource x, equal to *memory_­rsrc, using x.allocate(n * sizeof(Tp), alignof(Tp)).
Effects: Equivalent to memory_­rsrc->deallocate(p, n * sizeof(Tp), alignof(Tp)).
Throws: Nothing.
template <class T, class... Args> void construct(T* p, Args&&... args);
Requires: Uses-allocator construction of T with allocator resource() (see [allocator.uses.construction]) and constructor arguments std​::​forward<Args>(args)... is well-formed.
[Note
:
Uses-allocator construction is always well formed for types that do not use allocators.
end note
]
Effects: Construct a T object in the storage whose address is represented by p by uses-allocator construction with allocator resource() and constructor arguments std​::​forward<Args>(args)....
Throws: Nothing unless the constructor for T throws.
template <class T1, class T2, class... Args1, class... Args2> void construct(pair<T1,T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
[Note
:
This method and the construct methods that follow are overloads for piecewise construction of pairs ([pairs.pair]).
end note
]
Effects: Let xprime be a tuple constructed from x according to the appropriate rule from the following list.
[Note
:
The following description can be summarized as constructing a pair<T1, T2> object in the storage whose address is represented by p, as if by separate uses-allocator construction with allocator resource() ([allocator.uses.construction]) of p->first using the elements of x and p->second using the elements of y.
end note
]
  • If uses_­allocator_­v<T1,memory_­resource*> is false
    and is_­constructible_­v<T1,Args1...> is true,
    then xprime is x.
  • Otherwise, if uses_­allocator_­v<T1,memory_­resource*> is true
    and is_­constructible_­v<T1,allocator_­arg_­t,memory_­resource*,Args1...> is true,
    then xprime is tuple_­cat(make_­tuple(allocator_­arg, resource()), std​::​move(x)).
  • Otherwise, if uses_­allocator_­v<T1,memory_­resource*> is true
    and is_­constructible_­v<T1,Args1...,memory_­resource*> is true,
    then xprime is tuple_­cat(std​::​move(x), make_­tuple(resource())).
  • Otherwise the program is ill formed.
Let yprime be a tuple constructed from y according to the appropriate rule from the following list:
  • If uses_­allocator_­v<T2,memory_­resource*> is false
    and is_­constructible_­v<T2,Args2...> is true,
    then yprime is y.
  • Otherwise, if uses_­allocator_­v<T2,memory_­resource*> is true
    and is_­constructible_­v<T2,allocator_­arg_­t,memory_­resource*,Args2...> is true,
    then yprime is tuple_­cat(make_­tuple(allocator_­arg, resource()), std​::​move(y)).
  • Otherwise, if uses_­allocator_­v<T2,memory_­resource*> is true
    and is_­constructible_­v<T2,Args2...,memory_­resource*> is true,
    then yprime is tuple_­cat(std​::​move(y), make_­tuple(resource())).
  • Otherwise the program is ill formed.
Then, using piecewise_­construct, xprime, and yprime as the constructor arguments, this function constructs a pair<T1, T2> object in the storage whose address is represented by p.
template <class T1, class T2> void construct(pair<T1,T2>* p);
Effects: Equivalent to:
construct(p, piecewise_construct, tuple<>(), tuple<>());
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, U&& x, V&& y);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x)),
          forward_as_tuple(std::forward<V>(y)));
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, const pair<U, V>& pr);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(pr.first),
          forward_as_tuple(pr.second));
template <class T1, class T2, class U, class V> void construct(pair<T1,T2>* p, pair<U, V>&& pr);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(pr.first)),
          forward_as_tuple(std::forward<V>(pr.second)));
template <class T> void destroy(T* p);
Effects: As if by p->~T().
polymorphic_allocator select_on_container_copy_construction() const;
Returns: polymorphic_­allocator().
[Note
:
The memory resource is not propagated.
end note
]
memory_resource* resource() const;
Returns: memory_­rsrc.

23.12.3.3 polymorphic_­allocator equality [mem.poly.allocator.eq]

template <class T1, class T2> bool operator==(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) noexcept;
Returns: *a.resource() == *b.resource().
template <class T1, class T2> bool operator!=(const polymorphic_allocator<T1>& a, const polymorphic_allocator<T2>& b) noexcept;
Returns: !(a == b).

23.12.4 Access to program-wide memory_­resource objects [mem.res.global]

memory_resource* new_delete_resource() noexcept;
Returns: A pointer to a static-duration object of a type derived from memory_­resource that can serve as a resource for allocating memory using ​::​operator new and ​::​operator delete.
The same value is returned every time this function is called.
For a return value p and a memory resource r, p->is_­equal(r) returns &r == p.
memory_resource* null_memory_resource() noexcept;
Returns: A pointer to a static-duration object of a type derived from memory_­resource for which allocate() always throws bad_­alloc and for which deallocate() has no effect.
The same value is returned every time this function is called.
For a return value p and a memory resource r, p->is_­equal(r) returns &r == p.
The default memory resource pointer is a pointer to a memory resource that is used by certain facilities when an explicit memory resource is not supplied through the interface.
Its initial value is the return value of new_­delete_­resource().
memory_resource* set_default_resource(memory_resource* r) noexcept;
Effects: If r is non-null, sets the value of the default memory resource pointer to r, otherwise sets the default memory resource pointer to new_­delete_­resource().
Postconditions: get_­default_­resource() == r.
Returns: The previous value of the default memory resource pointer.
Remarks: Calling the set_­default_­resource and get_­default_­resource functions shall not incur a data race.
A call to the set_­default_­resource function shall synchronize with subsequent calls to the set_­default_­resource and get_­default_­resource functions.
memory_resource* get_default_resource() noexcept;
Returns: The current value of the default memory resource pointer.

23.12.5 Pool resource classes [mem.res.pool]

23.12.5.1 Classes synchronized_­pool_­resource and unsynchronized_­pool_­resource [mem.res.pool.overview]

The synchronized_­pool_­resource and unsynchronized_­pool_­resource classes (collectively called pool resource classes) are general-purpose memory resources having the following qualities:
  • Each resource frees its allocated memory on destruction, even if deallocate has not been called for some of the allocated blocks.
  • A pool resource consists of a collection of pools, serving requests for different block sizes.
    Each individual pool manages a collection of chunks that are in turn divided into blocks of uniform size, returned via calls to do_­allocate.
    Each call to do_­allocate(size, alignment) is dispatched to the pool serving the smallest blocks accommodating at least size bytes.
  • When a particular pool is exhausted, allocating a block from that pool results in the allocation of an additional chunk of memory from the upstream allocator (supplied at construction), thus replenishing the pool.
    With each successive replenishment, the chunk size obtained increases geometrically.
    [Note
    :
    By allocating memory in chunks, the pooling strategy increases the chance that consecutive allocations will be close together in memory.
    end note
    ]
  • Allocation requests that exceed the largest block size of any pool are fulfilled directly from the upstream allocator.
  • A pool_­options struct may be passed to the pool resource constructors to tune the largest block size and the maximum chunk size.
A synchronized_­pool_­resource may be accessed from multiple threads without external synchronization and may have thread-specific pools to reduce synchronization costs.
An unsynchronized_­pool_­resource class may not be accessed from multiple threads simultaneously and thus avoids the cost of synchronization entirely in single-threaded applications.
struct pool_options {
  size_t max_blocks_per_chunk = 0;
  size_t largest_required_pool_block = 0;
};

class synchronized_pool_resource : public memory_resource {
public:
  synchronized_pool_resource(const pool_options& opts,
                             memory_resource* upstream);

  synchronized_pool_resource()
      : synchronized_pool_resource(pool_options(), get_default_resource()) {}
  explicit synchronized_pool_resource(memory_resource* upstream)
      : synchronized_pool_resource(pool_options(), upstream) {}
  explicit synchronized_pool_resource(const pool_options& opts)
      : synchronized_pool_resource(opts, get_default_resource()) {}

  synchronized_pool_resource(const synchronized_pool_resource&) = delete;
  virtual ~synchronized_pool_resource();

  synchronized_pool_resource&
    operator=(const synchronized_pool_resource&) = delete;

  void release();
  memory_resource* upstream_resource() const;
  pool_options options() const;

protected:
  void *do_allocate(size_t bytes, size_t alignment) override;
  void do_deallocate(void *p, size_t bytes, size_t alignment) override;

  bool do_is_equal(const memory_resource& other) const noexcept override;
};

class unsynchronized_pool_resource : public memory_resource {
public:
  unsynchronized_pool_resource(const pool_options& opts,
                               memory_resource* upstream);

  unsynchronized_pool_resource()
      : unsynchronized_pool_resource(pool_options(), get_default_resource()) {}
  explicit unsynchronized_pool_resource(memory_resource* upstream)
      : unsynchronized_pool_resource(pool_options(), upstream) {}
  explicit unsynchronized_pool_resource(const pool_options& opts)
      : unsynchronized_pool_resource(opts, get_default_resource()) {}

  unsynchronized_pool_resource(const unsynchronized_pool_resource&) = delete;
  virtual ~unsynchronized_pool_resource();

  unsynchronized_pool_resource&
    operator=(const unsynchronized_pool_resource&) = delete;

  void release();
  memory_resource *upstream_resource() const;
  pool_options options() const;

protected:
  void* do_allocate(size_t bytes, size_t alignment) override;
  void do_deallocate(void* p, size_t bytes, size_t alignment) override;

  bool do_is_equal(const memory_resource& other) const noexcept override;
};

23.12.5.2 pool_­options data members [mem.res.pool.options]

The members of pool_­options comprise a set of constructor options for pool resources.
The effect of each option on the pool resource behavior is described below:
size_t max_blocks_per_chunk;
The maximum number of blocks that will be allocated at once from the upstream memory resource ([mem.res.monotonic.buffer]) to replenish a pool.
If the value of max_­blocks_­per_­chunk is zero or is greater than an implementation-defined limit, that limit is used instead.
The implementation may choose to use a smaller value than is specified in this field and may use different values for different pools.
size_t largest_required_pool_block;
The largest allocation size that is required to be fulfilled using the pooling mechanism.
Attempts to allocate a single block larger than this threshold will be allocated directly from the upstream memory resource.
If largest_­required_­pool_­block is zero or is greater than an implementation-defined limit, that limit is used instead.
The implementation may choose a pass-through threshold larger than specified in this field.

23.12.5.3 Pool resource constructors and destructors [mem.res.pool.ctor]

synchronized_pool_resource(const pool_options& opts, memory_resource* upstream); unsynchronized_pool_resource(const pool_options& opts, memory_resource* upstream);
Requires: upstream is the address of a valid memory resource.
Effects: Constructs a pool resource object that will obtain memory from upstream whenever the pool resource is unable to satisfy a memory request from its own internal data structures.
The resulting object will hold a copy of upstream, but will not own the resource to which upstream points.
[Note
:
The intention is that calls to upstream->allocate() will be substantially fewer than calls to this->allocate() in most cases.
end note
]
The behavior of the pooling mechanism is tuned according to the value of the opts argument.
Throws: Nothing unless upstream->allocate() throws.
It is unspecified if, or under what conditions, this constructor calls upstream->allocate().
virtual ~synchronized_pool_resource(); virtual ~unsynchronized_pool_resource();
Effects: Calls release().

23.12.5.4 Pool resource members [mem.res.pool.mem]

void release();
Effects: Calls upstream_­resource()->deallocate() as necessary to release all allocated memory.
[Note
:
The memory is released back to upstream_­resource() even if deallocate has not been called for some of the allocated blocks.
end note
]
memory_resource* upstream_resource() const;
Returns: The value of the upstream argument provided to the constructor of this object.
pool_options options() const;
Returns: The options that control the pooling behavior of this resource.
The values in the returned struct may differ from those supplied to the pool resource constructor in that values of zero will be replaced with implementation-defined defaults, and sizes may be rounded to unspecified granularity.
void* do_allocate(size_t bytes, size_t alignment) override;
Returns: A pointer to allocated storage ([basic.stc.dynamic.deallocation]) with a size of at least bytes.
The size and alignment of the allocated memory shall meet the requirements for a class derived from memory_­resource ([mem.res]).
Effects: If the pool selected for a block of size bytes is unable to satisfy the memory request from its own internal data structures, it will call upstream_­resource()->allocate() to obtain more memory.
If bytes is larger than that which the largest pool can handle, then memory will be allocated using upstream_­resource()->allocate().
Throws: Nothing unless upstream_­resource()->allocate() throws.
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
Effects: Returns the memory at p to the pool.
It is unspecified if, or under what circumstances, this operation will result in a call to upstream_­resource()->deallocate().
Throws: Nothing.
bool synchronized_pool_resource::do_is_equal( const memory_resource& other) const noexcept override;
Returns: this == dynamic_­cast<const synchronized_­pool_­resource*>(&other).
bool unsynchronized_pool_resource::do_is_equal( const memory_resource& other) const noexcept override;
Returns: this == dynamic_­cast<const unsynchronized_­pool_­resource*>(&other).

23.12.6 Class monotonic_­buffer_­resource [mem.res.monotonic.buffer]

A monotonic_­buffer_­resource is a special-purpose memory resource intended for very fast memory allocations in situations where memory is used to build up a few objects and then is released all at once when the memory resource object is destroyed.
It has the following qualities:
  • A call to deallocate has no effect, thus the amount of memory consumed increases monotonically until the resource is destroyed.
  • The program can supply an initial buffer, which the allocator uses to satisfy memory requests.
  • When the initial buffer (if any) is exhausted, it obtains additional buffers from an upstream memory resource supplied at construction.
    Each additional buffer is larger than the previous one, following a geometric progression.
  • It is intended for access from one thread of control at a time.
    Specifically, calls to allocate and deallocate do not synchronize with one another.
  • It frees the allocated memory on destruction, even if deallocate has not been called for some of the allocated blocks.
class monotonic_buffer_resource : public memory_resource {
  memory_resource *upstream_rsrc; // exposition only
  void *current_buffer;           // exposition only
  size_t next_buffer_size;        // exposition only

public:
  explicit monotonic_buffer_resource(memory_resource *upstream);
  monotonic_buffer_resource(size_t initial_size, memory_resource *upstream);
  monotonic_buffer_resource(void *buffer, size_t buffer_size,
                            memory_resource *upstream);

  monotonic_buffer_resource()
      : monotonic_buffer_resource(get_default_resource()) {}
  explicit monotonic_buffer_resource(size_t initial_size)
      : monotonic_buffer_resource(initial_size, get_default_resource()) {}
  monotonic_buffer_resource(void *buffer, size_t buffer_size)
      : monotonic_buffer_resource(buffer, buffer_size, get_default_resource()) {}

  monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;

  virtual ~monotonic_buffer_resource();

  monotonic_buffer_resource
    operator=(const monotonic_buffer_resource&) = delete;

  void release();
  memory_resource* upstream_resource() const;

protected:
  void* do_allocate(size_t bytes, size_t alignment) override;
  void do_deallocate(void* p, size_t bytes, size_t alignment) override;

  bool do_is_equal(const memory_resource& other) const noexcept override;
};

23.12.6.1 monotonic_­buffer_­resource constructor and destructor [mem.res.monotonic.buffer.ctor]

explicit monotonic_buffer_resource(memory_resource* upstream); monotonic_buffer_resource(size_t initial_size, memory_resource* upstream);
Requires: upstream shall be the address of a valid memory resource.
initial_­size, if specified, shall be greater than zero.
Effects: Sets upstream_­rsrc to upstream and current_­buffer to nullptr.
If initial_­size is specified, sets next_­buffer_­size to at least initial_­size; otherwise sets next_­buffer_­size to an implementation-defined size.
monotonic_buffer_resource(void* buffer, size_t buffer_size, memory_resource* upstream);
Requires: upstream shall be the address of a valid memory resource.
buffer_­size shall be no larger than the number of bytes in buffer.
Effects: Sets upstream_­rsrc to upstream, current_­buffer to buffer, and next_­buffer_­size to buffer_­size (but not less than 1), then increases next_­buffer_­size by an implementation-defined growth factor (which need not be integral).
~monotonic_buffer_resource();
Effects: Calls release().

23.12.6.2 monotonic_­buffer_­resource members [mem.res.monotonic.buffer.mem]

void release();
Effects: Calls upstream_­rsrc->deallocate() as necessary to release all allocated memory.
[Note
:
The memory is released back to upstream_­rsrc even if some blocks that were allocated from this have not been deallocated from this.
end note
]
memory_resource* upstream_resource() const;
Returns: The value of upstream_­rsrc.
void* do_allocate(size_t bytes, size_t alignment) override;
Returns: A pointer to allocated storage ([basic.stc.dynamic.deallocation]) with a size of at least bytes.
The size and alignment of the allocated memory shall meet the requirements for a class derived from memory_­resource ([mem.res]).
Effects: If the unused space in current_­buffer can fit a block with the specified bytes and alignment, then allocate the return block from current_­buffer; otherwise set current_­buffer to upstream_­rsrc->allocate(n, m), where n is not less than max(bytes, next_­buffer_­size) and m is not less than alignment, and increase next_­buffer_­size by an implementation-defined growth factor (which need not be integral), then allocate the return block from the newly-allocated current_­buffer.
Throws: Nothing unless upstream_­rsrc->allocate() throws.
void do_deallocate(void* p, size_t bytes, size_t alignment) override;
Effects: None.
Throws: Nothing.
Remarks: Memory used by this resource increases monotonically until its destruction.
bool do_is_equal(const memory_resource& other) const noexcept override;
Returns: this == dynamic_­cast<const monotonic_­buffer_­resource*>(&other).

23.13 Class template scoped_­allocator_­adaptor [allocator.adaptor]

23.13.1 Header <scoped_­allocator> synopsis [allocator.adaptor.syn]

  // scoped allocator adaptor
  template <class OuterAlloc, class... InnerAlloc>
    class scoped_allocator_adaptor;
  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
The class template scoped_­allocator_­adaptor is an allocator template that specifies the memory resource (the outer allocator) to be used by a container (as any other allocator does) and also specifies an inner allocator resource to be passed to the constructor of every element within the container.
This adaptor is instantiated with one outer and zero or more inner allocator types.
If instantiated with only one allocator type, the inner allocator becomes the scoped_­allocator_­adaptor itself, thus using the same allocator resource for the container and every element within the container and, if the elements themselves are containers, each of their elements recursively.
If instantiated with more than one allocator, the first allocator is the outer allocator for use by the container, the second allocator is passed to the constructors of the container's elements, and, if the elements themselves are containers, the third allocator is passed to the elements' elements, and so on.
If containers are nested to a depth greater than the number of allocators, the last allocator is used repeatedly, as in the single-allocator case, for any remaining recursions.
[Note
:
The scoped_­allocator_­adaptor is derived from the outer allocator type so it can be substituted for the outer allocator type in most expressions.
end note
]
namespace std {
  template <class OuterAlloc, class... InnerAllocs>
    class scoped_allocator_adaptor : public OuterAlloc {
  private:
    using OuterTraits = allocator_traits<OuterAlloc>; // exposition only
    scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only
  public:
    using outer_allocator_type = OuterAlloc;
    using inner_allocator_type = see below;

    using value_type           = typename OuterTraits::value_type;
    using size_type            = typename OuterTraits::size_type;
    using difference_type      = typename OuterTraits::difference_type;
    using pointer              = typename OuterTraits::pointer;
    using const_pointer        = typename OuterTraits::const_pointer;
    using void_pointer         = typename OuterTraits::void_pointer;
    using const_void_pointer   = typename OuterTraits::const_void_pointer;

    using propagate_on_container_copy_assignment = see below;
    using propagate_on_container_move_assignment = see below;
    using propagate_on_container_swap            = see below;
    using is_always_equal                        = see below;

    template <class Tp>
      struct rebind {
        using other = scoped_allocator_adaptor<
          OuterTraits::template rebind_alloc<Tp>, InnerAllocs...>;
      };

    scoped_allocator_adaptor();
    template <class OuterA2>
      scoped_allocator_adaptor(OuterA2&& outerAlloc,
                               const InnerAllocs&... innerAllocs) noexcept;

    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
    scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;

    template <class OuterA2>
      scoped_allocator_adaptor(
        const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
    template <class OuterA2>
      scoped_allocator_adaptor(
        scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;

    scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
    scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;

    ~scoped_allocator_adaptor();

    inner_allocator_type& inner_allocator() noexcept;
    const inner_allocator_type& inner_allocator() const noexcept;
    outer_allocator_type& outer_allocator() noexcept;
    const outer_allocator_type& outer_allocator() const noexcept;

    pointer allocate(size_type n);
    pointer allocate(size_type n, const_void_pointer hint);
    void deallocate(pointer p, size_type n);
    size_type max_size() const;

    template <class T, class... Args>
      void construct(T* p, Args&&... args);
    template <class T1, class T2, class... Args1, class... Args2>
      void construct(pair<T1, T2>* p, piecewise_construct_t,
                     tuple<Args1...> x, tuple<Args2...> y);
    template <class T1, class T2>
      void construct(pair<T1, T2>* p);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, U&& x, V&& y);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, const pair<U, V>& x);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, pair<U, V>&& x);

    template <class T>
      void destroy(T* p);

    scoped_allocator_adaptor select_on_container_copy_construction() const;
  };

  template<class OuterAlloc, class... InnerAllocs>
    scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
      -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;

  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
  template <class OuterA1, class OuterA2, class... InnerAllocs>
    bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                    const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
}

23.13.2 Scoped allocator adaptor member types [allocator.adaptor.types]

using inner_allocator_type = see below;
Type: scoped_­allocator_­adaptor<OuterAlloc> if sizeof...(InnerAllocs) is zero; otherwise,
scoped_­allocator_­adaptor<InnerAllocs...>.
using propagate_on_container_copy_assignment = see below;
Type: true_­type if allocator_­traits<A>​::​propagate_­on_­container_­copy_­assignment​::​value is true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.
using propagate_on_container_move_assignment = see below;
Type: true_­type if allocator_­traits<A>​::​propagate_­on_­container_­move_­assignment​::​value is true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.
using propagate_on_container_swap = see below;
Type: true_­type if allocator_­traits<A>​::​propagate_­on_­container_­swap​::​value is true for any A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.
using is_always_equal = see below;
Type: true_­type if allocator_­traits<A>​::​is_­always_­equal​::​value is true for every A in the set of OuterAlloc and InnerAllocs...; otherwise, false_­type.

23.13.3 Scoped allocator adaptor constructors [allocator.adaptor.cnstr]

scoped_allocator_adaptor();
Effects: Value-initializes the OuterAlloc base class and the inner allocator object.
template <class OuterA2> scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) noexcept;
Effects: Initializes the OuterAlloc base class with std​::​forward<OuterA2>(outerAlloc) and inner with innerAllocs... (hence recursively initializing each allocator within the adaptor with the corresponding allocator from the argument list).
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<OuterAlloc, OuterA2> is true.
scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
Effects: Initializes each allocator within the adaptor with the corresponding allocator from other.
scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
Effects: Move constructs each allocator within the adaptor with the corresponding allocator from other.
template <class OuterA2> scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
Effects: Initializes each allocator within the adaptor with the corresponding allocator from other.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<OuterAlloc, const OuterA2&> is true.
template <class OuterA2> scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
Effects: Initializes each allocator within the adaptor with the corresponding allocator rvalue from other.
Remarks: This constructor shall not participate in overload resolution unless is_­constructible_­v<OuterAlloc, OuterA2> is true.

23.13.4 Scoped allocator adaptor members [allocator.adaptor.members]

In the construct member functions, OUTERMOST(x) is x if x does not have an outer_­allocator() member function and OUTERMOST(x.outer_­allocator()) otherwise; OUTERMOST_­ALLOC_­TRAITS(x) is allocator_­traits<decltype(OUTERMOST(x))>.
[Note
:
OUTERMOST(x) and OUTERMOST_­ALLOC_­TRAITS(x) are recursive operations.
It is incumbent upon the definition of outer_­allocator() to ensure that the recursion terminates.
It will terminate for all instantiations of scoped_­allocator_­adaptor.
end note
]
inner_allocator_type& inner_allocator() noexcept; const inner_allocator_type& inner_allocator() const noexcept;
Returns: *this if sizeof...(InnerAllocs) is zero; otherwise, inner.
outer_allocator_type& outer_allocator() noexcept;
Returns: static_­cast<OuterAlloc&>(*this).
const outer_allocator_type& outer_allocator() const noexcept;
Returns: static_­cast<const OuterAlloc&>(*this).
pointer allocate(size_type n);
Returns: allocator_­traits<OuterAlloc>​::​allocate(outer_­allocator(), n).
pointer allocate(size_type n, const_void_pointer hint);
Returns: allocator_­traits<OuterAlloc>​::​allocate(outer_­allocator(), n, hint).
void deallocate(pointer p, size_type n) noexcept;
Effects: As if by: allocator_­traits<OuterAlloc>​::​deallocate(outer_­allocator(), p, n);
size_type max_size() const;
Returns: allocator_­traits<OuterAlloc>​::​max_­size(outer_­allocator()).
template <class T, class... Args> void construct(T* p, Args&&... args);
Effects:
  • If uses_­allocator_­v<T, inner_­allocator_­type> is false and is_­constructible_­v<T,
    Args...>
    is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, std::forward<Args>(args)...)
  • Otherwise, if uses_­allocator_­v<T, inner_­allocator_­type> is true and is_­constructible_­v<T, allocator_­arg_­t, inner_­allocator_­type&, Args...> is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, allocator_arg, inner_allocator(), std::forward<Args>(args)...)
  • Otherwise, if uses_­allocator_­v<T, inner_­allocator_­type> is true and is_­constructible_­v<T, Args..., inner_­allocator_­type&> is true, calls:
    OUTERMOST_ALLOC_TRAITS(*this)::construct(
        OUTERMOST(*this), p, std::forward<Args>(args)..., inner_allocator())
  • Otherwise, the program is ill-formed.
    [Note
    :
    An error will result if uses_­allocator evaluates to true but the specific constructor does not take an allocator.
    This definition prevents a silent failure to pass an inner allocator to a contained element.
    end note
    ]
template <class T1, class T2, class... Args1, class... Args2> void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
Requires: all of the types in Args1 and Args2 shall be CopyConstructible (Table 24).
Effects: Constructs a tuple object xprime from x by the following rules:
  • If uses_­allocator_­v<T1, inner_­allocator_­type> is false and is_­constructible_­v<T1,
    Args1...>
    is true, then xprime is x.
  • Otherwise, if uses_­allocator_­v<T1, inner_­allocator_­type> is true and is_­constructible_­v<T1, allocator_­arg_­t, inner_­allocator_­type&, Args1...> is true, then xprime is:
    tuple_cat(
        tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()),
        std::move(x))
  • Otherwise, if uses_­allocator_­v<T1, inner_­allocator_­type> is true and is_­constructible_­v<T1, Args1..., inner_­allocator_­type&> is true, then xprime is:
    tuple_cat(std::move(x), tuple<inner_allocator_type&>(inner_allocator()))
  • Otherwise, the program is ill-formed.
and constructs a tuple object yprime from y by the following rules:
  • If uses_­allocator_­v<T2, inner_­allocator_­type> is false and is_­constructible_­v<T2,
    Args2...>
    is true, then yprime is y.
  • Otherwise, if uses_­allocator_­v<T2, inner_­allocator_­type> is true and is_­constructible_­v<T2, allocator_­arg_­t, inner_­allocator_­type&, Args2...> is true, then yprime is:
    tuple_cat(
        tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator()),
        std::move(y))
  • Otherwise, if uses_­allocator_­v<T2, inner_­allocator_­type> is true and is_­constructible_­v<T2, Args2..., inner_­allocator_­type&> is true, then yprime is:
    tuple_cat(std::move(y), tuple<inner_allocator_type&>(inner_allocator()))
  • Otherwise, the program is ill-formed.
then calls:
OUTERMOST_ALLOC_TRAITS(*this)::construct(
    OUTERMOST(*this), p, piecewise_construct, std::move(xprime), std::move(yprime))
template <class T1, class T2> void construct(pair<T1, T2>* p);
Effects: Equivalent to:
construct(p, piecewise_construct, tuple<>(), tuple<>());
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, U&& x, V&& y);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x)),
          forward_as_tuple(std::forward<V>(y)));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, const pair<U, V>& x);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(x.first),
          forward_as_tuple(x.second));
template <class T1, class T2, class U, class V> void construct(pair<T1, T2>* p, pair<U, V>&& x);
Effects: Equivalent to:
construct(p, piecewise_construct,
          forward_as_tuple(std::forward<U>(x.first)),
          forward_as_tuple(std::forward<V>(x.second)));
template <class T> void destroy(T* p);
Effects: Calls OUTERMOST_­ALLOC_­TRAITS(*this)​::​destroy(OUTERMOST(*this), p).
scoped_allocator_adaptor select_on_container_copy_construction() const;
Returns: A new scoped_­allocator_­adaptor object where each allocator A in the adaptor is initialized from the result of calling allocator_­traits<A>​::​select_­on_­container_­copy_­construction() on the corresponding allocator in *this.

23.13.5 Scoped allocator operators [scoped.adaptor.operators]

template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Returns: If sizeof...(InnerAllocs) is zero,
a.outer_allocator() == b.outer_allocator()
otherwise
a.outer_allocator() == b.outer_allocator() && a.inner_allocator() == b.inner_allocator()
template <class OuterA1, class OuterA2, class... InnerAllocs> bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Returns: !(a == b).

23.14 Function objects [function.objects]

A function object type is an object type ([basic.types]) that can be the type of the postfix-expression in a function call ([expr.call], [over.match.call]).222
A function object is an object of a function object type.
In the places where one would expect to pass a pointer to a function to an algorithmic template (Clause [algorithms]), the interface is specified to accept a function object.
This not only makes algorithmic templates work with pointers to functions, but also enables them to work with arbitrary function objects.
Such a type is a function pointer or a class type which has a member operator() or a class type which has a conversion to a pointer to function.

23.14.1 Header <functional> synopsis [functional.syn]

namespace std {
  // [func.invoke], invoke
  template <class F, class... Args>
    invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
      noexcept(is_nothrow_invocable_v<F, Args...>);

  // [refwrap], reference_­wrapper
  template <class T> class reference_wrapper;

  template <class T> reference_wrapper<T> ref(T&) noexcept;
  template <class T> reference_wrapper<const T> cref(const T&) noexcept;
  template <class T> void ref(const T&&) = delete;
  template <class T> void cref(const T&&) = delete;

  template <class T> reference_wrapper<T> ref(reference_wrapper<T>) noexcept;
  template <class T> reference_wrapper<const T> cref(reference_wrapper<T>) noexcept;

  // [arithmetic.operations], arithmetic operations
  template <class T = void> struct plus;
  template <class T = void> struct minus;
  template <class T = void> struct multiplies;
  template <class T = void> struct divides;
  template <class T = void> struct modulus;
  template <class T = void> struct negate;
  template <> struct plus<void>;
  template <> struct minus<void>;
  template <> struct multiplies<void>;
  template <> struct divides<void>;
  template <> struct modulus<void>;
  template <> struct negate<void>;

  // [comparisons], comparisons
  template <class T = void> struct equal_to;
  template <class T = void> struct not_equal_to;
  template <class T = void> struct greater;
  template <class T = void> struct less;
  template <class T = void> struct greater_equal;
  template <class T = void> struct less_equal;
  template <> struct equal_to<void>;
  template <> struct not_equal_to<void>;
  template <> struct greater<void>;
  template <> struct less<void>;
  template <> struct greater_equal<void>;
  template <> struct less_equal<void>;

  // [logical.operations], logical operations
  template <class T = void> struct logical_and;
  template <class T = void> struct logical_or;
  template <class T = void> struct logical_not;
  template <> struct logical_and<void>;
  template <> struct logical_or<void>;
  template <> struct logical_not<void>;

  // [bitwise.operations], bitwise operations
  template <class T = void> struct bit_and;
  template <class T = void> struct bit_or;
  template <class T = void> struct bit_xor;
  template <class T = void> struct bit_not;
  template <> struct bit_and<void>;
  template <> struct bit_or<void>;
  template <> struct bit_xor<void>;
  template <> struct bit_not<void>;

  // [func.not_fn], function template not_­fn
  template <class F>
    unspecified not_fn(F&& f);

  // [func.bind], bind
  template<class T> struct is_bind_expression;
  template<class T> struct is_placeholder;

  template<class F, class... BoundArgs>
    unspecified bind(F&&, BoundArgs&&...);
  template<class R, class F, class... BoundArgs>
    unspecified bind(F&&, BoundArgs&&...);

  namespace placeholders {
    // M is the implementation-defined number of placeholders
    see below _1;
    see below _2;
               .
               .
               .
    see below _M;
  }

  // [func.memfn], member function adaptors
  template<class R, class T>
    unspecified mem_fn(R T::*) noexcept;

  // [func.wrap], polymorphic function wrappers
  class bad_function_call;

  template<class> class function; // not defined
  template<class R, class... ArgTypes> class function<R(ArgTypes...)>;

  template<class R, class... ArgTypes>
    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;

  template<class R, class... ArgTypes>
    bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
  template<class R, class... ArgTypes>
    bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
  template<class R, class... ArgTypes>
    bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
  template<class R, class... ArgTypes>
    bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;

  // [func.search], searchers
  template<class ForwardIterator, class BinaryPredicate = equal_to<>>
    class default_searcher;

  template<class RandomAccessIterator,
           class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
           class BinaryPredicate = equal_to<>>
    class boyer_moore_searcher;

  template<class RandomAccessIterator,
           class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
           class BinaryPredicate = equal_to<>>
    class boyer_moore_horspool_searcher;

  // [unord.hash], hash function primary template
  template <class T>
    struct hash;

  // [func.bind], function object binders
  template <class T>
    inline constexpr bool is_bind_expression_v = is_bind_expression<T>::value;
  template <class T>
    inline constexpr int is_placeholder_v = is_placeholder<T>::value;
}
[Example
:
If a C++ program wants to have a by-element addition of two vectors a and b containing double and put the result into a, it can do:
transform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
end example
]
[Example
:
To negate every element of a:
transform(a.begin(), a.end(), a.begin(), negate<double>());
end example
]

23.14.2 Definitions [func.def]

The following definitions apply to this Clause:
A call signature is the name of a return type followed by a parenthesized comma-separated list of zero or more argument types.
A callable type is a function object type ([function.objects]) or a pointer to member.
A callable object is an object of a callable type.
A call wrapper type is a type that holds a callable object and supports a call operation that forwards to that object.
A call wrapper is an object of a call wrapper type.
A target object is the callable object held by a call wrapper.

23.14.3 Requirements [func.require]

Define INVOKE(f, t1, t2, ..., tN) as follows:
  • (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and is_­base_­of_­v<T, decay_­t<decltype(t1)>> is true;
  • (t1.get().*f)(t2, ..., tN) when f is a pointer to a member function of a class T and decay_­t<decltype(t1)> is a specialization of reference_­wrapper;
  • ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 does not satisfy the previous two items;
  • t1.*f when N == 1 and f is a pointer to data member of a class T and is_­base_­of_­v<T, decay_­t<decltype(t1)>> is true;
  • t1.get().*f when N == 1 and f is a pointer to data member of a class T and decay_­t<decltype(t1)> is a specialization of reference_­wrapper;
  • (*t1).*f when N == 1 and f is a pointer to data member of a class T and t1 does not satisfy the previous two items;
  • f(t1, t2, ..., tN) in all other cases.
Define INVOKE<R>(f, t1, t2, ..., tN) as static_­cast<void>(INVOKE(f, t1, t2, ..., tN)) if R is cv void, otherwise INVOKE(f, t1, t2, ..., tN) implicitly converted to R.
Every call wrapper ([func.def]) shall be MoveConstructible.
A forwarding call wrapper is a call wrapper that can be called with an arbitrary argument list and delivers the arguments to the wrapped callable object as references.
This forwarding step shall ensure that rvalue arguments are delivered as rvalue references and lvalue arguments are delivered as lvalue references.
A simple call wrapper is a forwarding call wrapper that is CopyConstructible and CopyAssignable and whose copy constructor, move constructor, and assignment operator do not throw exceptions.
[Note
:
In a typical implementation forwarding call wrappers have an overloaded function call operator of the form
template<class... UnBoundArgs>
R operator()(UnBoundArgs&&... unbound_args) cv-qual;
end note
]

23.14.4 Function template invoke [func.invoke]

template <class F, class... Args> invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) noexcept(is_nothrow_invocable_v<F, Args...>);
Returns: INVOKE(std​::​forward<F>(f), std​::​forward<Args>(args)...) ([func.require]).

23.14.5 Class template reference_­wrapper [refwrap]

namespace std {
  template <class T> class reference_wrapper {
  public :
    // types
    using type = T;

    // construct/copy/destroy
    reference_wrapper(T&) noexcept;
    reference_wrapper(T&&) = delete;     // do not bind to temporary objects
    reference_wrapper(const reference_wrapper& x) noexcept;

    // assignment
    reference_wrapper& operator=(const reference_wrapper& x) noexcept;

    // access
    operator T& () const noexcept;
    T& get() const noexcept;

    // invocation
    template <class... ArgTypes>
      invoke_result_t<T&, ArgTypes...>
      operator() (ArgTypes&&...) const;
  };

  template<class T>
    reference_wrapper(reference_wrapper<T>) -> reference_wrapper<T>;
}
reference_­wrapper<T> is a CopyConstructible and CopyAssignable wrapper around a reference to an object or function of type T.
reference_­wrapper<T> shall be a trivially copyable type ([basic.types]).

23.14.5.1 reference_­wrapper construct/copy/destroy [refwrap.const]

reference_wrapper(T& t) noexcept;
Effects: Constructs a reference_­wrapper object that stores a reference to t.
reference_wrapper(const reference_wrapper& x) noexcept;
Effects: Constructs a reference_­wrapper object that stores a reference to x.get().

23.14.5.2 reference_­wrapper assignment [refwrap.assign]

reference_wrapper& operator=(const reference_wrapper& x) noexcept;
Postconditions: *this stores a reference to x.get().

23.14.5.3 reference_­wrapper access [refwrap.access]

operator T& () const noexcept;
Returns: The stored reference.
T& get() const noexcept;
Returns: The stored reference.

23.14.5.4 reference_­wrapper invocation [refwrap.invoke]

template <class... ArgTypes> invoke_result_t<T&, ArgTypes...> operator()(ArgTypes&&... args) const;
Returns: INVOKE(get(), std​::​forward<ArgTypes>(args)...).

23.14.5.5 reference_­wrapper helper functions [refwrap.helpers]

template <class T> reference_wrapper<T> ref(T& t) noexcept;
Returns: reference_­wrapper<T>(t).
template <class T> reference_wrapper<T> ref(reference_wrapper<T> t) noexcept;
Returns: ref(t.get()).
template <class T> reference_wrapper<const T> cref(const T& t) noexcept;
Returns: reference_­wrapper <const T>(t).
template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
Returns: cref(t.get()).

23.14.6 Arithmetic operations [arithmetic.operations]

The library provides basic function object classes for all of the arithmetic operators in the language ([expr.mul], [expr.add]).

23.14.6.1 Class template plus [arithmetic.operations.plus]

template <class T = void> struct plus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x + y.
template <> struct plus<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) + std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) + std::forward<U>(u));
Returns: std​::​forward<T>(t) + std​::​forward<U>(u).

23.14.6.2 Class template minus [arithmetic.operations.minus]

template <class T = void> struct minus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x - y.
template <> struct minus<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) - std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) - std::forward<U>(u));
Returns: std​::​forward<T>(t) - std​::​forward<U>(u).

23.14.6.3 Class template multiplies [arithmetic.operations.multiplies]

template <class T = void> struct multiplies { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x * y.
template <> struct multiplies<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) * std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) * std::forward<U>(u));
Returns: std​::​forward<T>(t) * std​::​forward<U>(u).

23.14.6.4 Class template divides [arithmetic.operations.divides]

template <class T = void> struct divides { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x / y.
template <> struct divides<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) / std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) / std::forward<U>(u));
Returns: std​::​forward<T>(t) / std​::​forward<U>(u).

23.14.6.5 Class template modulus [arithmetic.operations.modulus]

template <class T = void> struct modulus { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x % y.
template <> struct modulus<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) % std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) % std::forward<U>(u));
Returns: std​::​forward<T>(t) % std​::​forward<U>(u).

23.14.6.6 Class template negate [arithmetic.operations.negate]

template <class T = void> struct negate { constexpr T operator()(const T& x) const; };
constexpr T operator()(const T& x) const;
Returns: -x.
template <> struct negate<void> { template <class T> constexpr auto operator()(T&& t) const -> decltype(-std::forward<T>(t)); using is_transparent = unspecified; };
template <class T> constexpr auto operator()(T&& t) const -> decltype(-std::forward<T>(t));
Returns: -std​::​forward<T>(t).

23.14.7 Comparisons [comparisons]

The library provides basic function object classes for all of the comparison operators in the language ([expr.rel], [expr.eq]).
For templates less, greater, less_­equal, and greater_­equal, the specializations for any pointer type yield a strict total order that is consistent among those specializations and is also consistent with the partial order imposed by the built-in operators <, >, <=, >=.
[Note
:
When a < b is well-defined for pointers a and b of type P, this implies (a < b) == less<P>(a, b), (a > b) == greater<P>(a, b), and so forth.
end note
]
For template specializations less<void>, greater<void>, less_­equal<void>, and greater_­equal<void>, if the call operator calls a built-in operator comparing pointers, the call operator yields a strict total order that is consistent among those specializations and is also consistent with the partial order imposed by those built-in operators.

23.14.7.1 Class template equal_­to [comparisons.equal_to]

template <class T = void> struct equal_to { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x == y.
template <> struct equal_to<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u));
Returns: std​::​forward<T>(t) == std​::​forward<U>(u).

23.14.7.2 Class template not_­equal_­to [comparisons.not_equal_to]

template <class T = void> struct not_equal_to { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x != y.
template <> struct not_equal_to<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) != std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) != std::forward<U>(u));
Returns: std​::​forward<T>(t) != std​::​forward<U>(u).

23.14.7.3 Class template greater [comparisons.greater]

template <class T = void> struct greater { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x > y.
template <> struct greater<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u));
Returns: std​::​forward<T>(t) > std​::​forward<U>(u).

23.14.7.4 Class template less [comparisons.less]

template <class T = void> struct less { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x < y.
template <> struct less<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u));
Returns: std​::​forward<T>(t) < std​::​forward<U>(u).

23.14.7.5 Class template greater_­equal [comparisons.greater_equal]

template <class T = void> struct greater_equal { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x >= y.
template <> struct greater_equal<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) >= std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) >= std::forward<U>(u));
Returns: std​::​forward<T>(t) >= std​::​forward<U>(u).

23.14.7.6 Class template less_­equal [comparisons.less_equal]

template <class T = void> struct less_equal { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x <= y.
template <> struct less_equal<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) <= std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) <= std::forward<U>(u));
Returns: std​::​forward<T>(t) <= std​::​forward<U>(u).

23.14.8 Logical operations [logical.operations]

The library provides basic function object classes for all of the logical operators in the language ([expr.log.and], [expr.log.or], [expr.unary.op]).

23.14.8.1 Class template logical_­and [logical.operations.and]

template <class T = void> struct logical_and { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x && y.
template <> struct logical_and<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) && std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) && std::forward<U>(u));
Returns: std​::​forward<T>(t) && std​::​forward<U>(u).

23.14.8.2 Class template logical_­or [logical.operations.or]

template <class T = void> struct logical_or { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
Returns: x || y.
template <> struct logical_or<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) || std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) || std::forward<U>(u));
Returns: std​::​forward<T>(t) || std​::​forward<U>(u).

23.14.8.3 Class template logical_­not [logical.operations.not]

template <class T = void> struct logical_not { constexpr bool operator()(const T& x) const; };
constexpr bool operator()(const T& x) const;
Returns: !x.
template <> struct logical_not<void> { template <class T> constexpr auto operator()(T&& t) const -> decltype(!std::forward<T>(t)); using is_transparent = unspecified; };
template <class T> constexpr auto operator()(T&& t) const -> decltype(!std::forward<T>(t));
Returns: !std​::​forward<T>(t).

23.14.9 Bitwise operations [bitwise.operations]

The library provides basic function object classes for all of the bitwise operators in the language ([expr.bit.and], [expr.or], [expr.xor], [expr.unary.op]).

23.14.9.1 Class template bit_­and [bitwise.operations.and]

template <class T = void> struct bit_and { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x & y.
template <> struct bit_and<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) & std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) & std::forward<U>(u));
Returns: std​::​forward<T>(t) & std​::​forward<U>(u).

23.14.9.2 Class template bit_­or [bitwise.operations.or]

template <class T = void> struct bit_or { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x | y.
template <> struct bit_or<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) | std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) | std::forward<U>(u));
Returns: std​::​forward<T>(t) | std​::​forward<U>(u).

23.14.9.3 Class template bit_­xor [bitwise.operations.xor]

template <class T = void> struct bit_xor { constexpr T operator()(const T& x, const T& y) const; };
constexpr T operator()(const T& x, const T& y) const;
Returns: x ^ y.
template <> struct bit_xor<void> { template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) ^ std::forward<U>(u)); using is_transparent = unspecified; };
template <class T, class U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) ^ std::forward<U>(u));
Returns: std​::​forward<T>(t) ^ std​::​forward<U>(u).

23.14.9.4 Class template bit_­not [bitwise.operations.not]

template <class T = void> struct bit_not { constexpr T operator()(const T& x) const; };
constexpr T operator()(const T& x) const;
Returns: ~x.
template <> struct bit_not<void> { template <class T> constexpr auto operator()(T&& t) const -> decltype(~std::forward<T>(t)); using is_transparent = unspecified; };
template <class T> constexpr auto operator()(T&&) const -> decltype(~std::forward<T>(t));
Returns: ~std​::​forward<T>(t).

23.14.10 Function template not_­fn [func.not_fn]

template <class F> unspecified not_fn(F&& f);
Effects: Equivalent to return call_­wrapper(std​::​forward<F>(f)); where call_­wrapper is an exposition only class defined as follows:
class call_wrapper {
  using FD = decay_t<F>;
  FD fd;

  explicit call_wrapper(F&& f);

public:
  call_wrapper(call_wrapper&&) = default;
  call_wrapper(const call_wrapper&) = default;

  template<class... Args>
    auto operator()(Args&&...) &
      -> decltype(!declval<invoke_result_t<FD&, Args...>>());

  template<class... Args>
    auto operator()(Args&&...) const&
      -> decltype(!declval<invoke_result_t<const FD&, Args...>>());

  template<class... Args>
    auto operator()(Args&&...) &&
      -> decltype(!declval<invoke_result_t<FD, Args...>>());

  template<class... Args>
    auto operator()(Args&&...) const&&
      -> decltype(!declval<invoke_result_t<const FD, Args...>>());
};
explicit call_wrapper(F&& f);
Requires: FD shall satisfy the requirements of MoveConstructible.
is_­constructible_­v<FD, F> shall be true.
fd shall be a callable object ([func.def]).
Effects: Initializes fd from std​::​forward<F>(f).
Throws: Any exception thrown by construction of fd.
template<class... Args> auto operator()(Args&&... args) & -> decltype(!declval<invoke_result_t<FD&, Args...>>()); template<class... Args> auto operator()(Args&&... args) const& -> decltype(!declval<invoke_result_t<const FD&, Args...>>());
Effects: Equivalent to:
return !INVOKE(fd, std::forward<Args>(args)...);              // see [func.require]
template<class... Args> auto operator()(Args&&... args) && -> decltype(!declval<invoke_result_t<FD, Args...>>()); template<class... Args> auto operator()(Args&&... args) const&& -> decltype(!declval<invoke_result_t<const FD, Args...>>());
Effects: Equivalent to:
return !INVOKE(std::move(fd), std::forward<Args>(args)...);   // see [func.require]

23.14.11 Function object binders [func.bind]

This subclause describes a uniform mechanism for binding arguments of callable objects.

23.14.11.1 Class template is_­bind_­expression [func.bind.isbind]

namespace std {
  template<class T> struct is_bind_expression;  // see below
}
The class template is_­bind_­expression can be used to detect function objects generated by bind.
The function template bind uses is_­bind_­expression to detect subexpressions.
Instantiations of the is_­bind_­expression template shall meet the UnaryTypeTrait requirements ([meta.rqmts]).
The implementation shall provide a definition that has a base characteristic of true_­type if T is a type returned from bind, otherwise it shall have a base characteristic of false_­type.
A program may specialize this template for a user-defined type T to have a base characteristic of true_­type to indicate that T should be treated as a subexpression in a bind call.

23.14.11.2 Class template is_­placeholder [func.bind.isplace]

namespace std {
  template<class T> struct is_placeholder;      // see below
}
The class template is_­placeholder can be used to detect the standard placeholders _­1, _­2, and so on.
The function template bind uses is_­placeholder to detect placeholders.
Instantiations of the is_­placeholder template shall meet the UnaryTypeTrait requirements ([meta.rqmts]).
The implementation shall provide a definition that has the base characteristic of integral_­constant<int, J> if T is the type of std​::​placeholders​::​_­J, otherwise it shall have a base characteristic of integral_­constant<int, 0>.
A program may specialize this template for a user-defined type T to have a base characteristic of integral_­constant<int, N> with N > 0 to indicate that T should be treated as a placeholder type.

23.14.11.3 Function template bind [func.bind.bind]

In the text that follows:
  • FD is the type decay_­t<F>,
  • fd is an lvalue of type FD constructed from std​::​forward<F>(f),
  • is the type in the template parameter pack BoundArgs,
  • is the type decay_­t<>,
  • is the argument in the function parameter pack bound_­args,
  • is an lvalue of type constructed from std​::​forward<>(),
  • is the deduced type of the UnBoundArgs&&... parameter of the forwarding call wrapper, and
  • is the argument associated with .
template<class F, class... BoundArgs> unspecified bind(F&& f, BoundArgs&&... bound_args);
Requires: is_­constructible_­v<FD, F> shall be true.
For each in BoundArgs, is_­constructible_­v<, > shall be true.
INVOKE(fd, , , …, ) ([func.require]) shall be a valid expression for some values , , …, , where N has the value sizeof...(bound_­args).
The cv-qualifiers cv of the call wrapper g, as specified below, shall be neither volatile nor const volatile.
Returns: A forwarding call wrapper g ([func.require]).
The effect of g(, , …, ) shall be
INVOKE(fd, std::forward<>(), std::forward<>(), …, std::forward<>())
where the values and types of the bound arguments , , …, are determined as specified below.
The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding constructor of FD or of any of the types throws an exception.
Throws: Nothing unless the construction of fd or of one of the values throws an exception.
Remarks: The return type shall satisfy the requirements of MoveConstructible.
If all of FD and satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements of CopyConstructible.
[Note
:
This implies that all of FD and are MoveConstructible.
end note
]
template<class R, class F, class... BoundArgs> unspecified bind(F&& f, BoundArgs&&... bound_args);
Requires: is_­constructible_­v<FD, F> shall be true.
For each in BoundArgs, is_­constructible_­v<, > shall be true.
INVOKE(fd, , , …, ) shall be a valid expression for some values , , …, , where N has the value sizeof...(bound_­args).
The cv-qualifiers cv of the call wrapper g, as specified below, shall be neither volatile nor const volatile.
Returns: A forwarding call wrapper g ([func.require]).
The effect of g(, , …, ) shall be
INVOKE<R>(fd, std::forward<>(), std::forward<>(), …, std::forward<>())
where the values and types of the bound arguments , , …, are determined as specified below.
The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding constructor of FD or of any of the types throws an exception.
Throws: Nothing unless the construction of fd or of one of the values throws an exception.
Remarks: The return type shall satisfy the requirements of MoveConstructible.
If all of FD and satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements of CopyConstructible.
[Note
:
This implies that all of FD and are MoveConstructible.
end note
]
The values of the bound arguments , , …, and their corresponding types , , …, depend on the types derived from the call to bind and the cv-qualifiers cv of the call wrapper g as follows:
  • if is reference_­wrapper<T>, the argument is .get() and its type is T&;
  • if the value of is_­bind_­expression_­v<> is true, the argument is (std​::​forward<>()...) and its type is invoke_­result_­t< cv &, ...>&&;
  • if the value j of is_­placeholder_­v<> is not zero, the argument is std​::​forward<>() and its type is &&;
  • otherwise, the value is and its type is cv &.

23.14.11.4 Placeholders [func.bind.place]

namespace std::placeholders {
  // M is the implementation-defined number of placeholders
  see below _1;
  see below _2;
              .
              .
              .
  see below _M;
}
All placeholder types shall be DefaultConstructible and CopyConstructible, and their default constructors and copy/move constructors shall not throw exceptions.
It is implementation-defined whether placeholder types are CopyAssignable.
CopyAssignable placeholders' copy assignment operators shall not throw exceptions.
Placeholders should be defined as:
inline constexpr unspecified _1{};
If they are not, they shall be declared as:
extern unspecified _1;

23.14.12 Function template mem_­fn [func.memfn]

template<class R, class T> unspecified mem_fn(R T::* pm) noexcept;
Returns: A simple call wrapper ([func.def]) fn such that the expression fn(t, a2, ..., aN) is equivalent to INVOKE(pm, t, a2, ..., aN) ([func.require]).

23.14.13 Polymorphic function wrappers [func.wrap]

This subclause describes a polymorphic wrapper class that encapsulates arbitrary callable objects.

23.14.13.1 Class bad_­function_­call [func.wrap.badcall]

An exception of type bad_­function_­call is thrown by function​::​operator() ([func.wrap.func.inv]) when the function wrapper object has no target.
namespace std {
  class bad_function_call : public exception {
  public:
    // [func.wrap.badcall.const], constructor
    bad_function_call() noexcept;
  };
}

23.14.13.1.1 bad_­function_­call constructor [func.wrap.badcall.const]

bad_function_call() noexcept;
Effects: Constructs a bad_­function_­call object.
Postconditions: what() returns an implementation-defined ntbs.

23.14.13.2 Class template function [func.wrap.func]

namespace std {
  template<class> class function; // not defined

  template<class R, class... ArgTypes>
  class function<R(ArgTypes...)> {
  public:
    using result_type = R;

    // [func.wrap.func.con], construct/copy/destroy
    function() noexcept;
    function(nullptr_t) noexcept;
    function(const function&);
    function(function&&);
    template<class F> function(F);

    function& operator=(const function&);
    function& operator=(function&&);
    function& operator=(nullptr_t) noexcept;
    template<class F> function& operator=(F&&);
    template<class F> function& operator=(reference_wrapper<F>) noexcept;

    ~function();

    // [func.wrap.func.mod], function modifiers
    void swap(function&) noexcept;

    // [func.wrap.func.cap], function capacity
    explicit operator bool() const noexcept;

    // [func.wrap.func.inv], function invocation
    R operator()(ArgTypes...) const;

    // [func.wrap.func.targ], function target access
    const type_info& target_type() const noexcept;
    template<class T>       T* target() noexcept;
    template<class T> const T* target() const noexcept;
  };

  template<class R, class... ArgTypes>
    function(R(*)(ArgTypes...)) -> function<R(ArgTypes...)>;

  template<class F> function(F) -> function<see below>;

  // [func.wrap.func.nullptr], Null pointer comparisons
  template <class R, class... ArgTypes>
    bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;

  template <class R, class... ArgTypes>
    bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;

  template <class R, class... ArgTypes>
    bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;

  template <class R, class... ArgTypes>
    bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;

  // [func.wrap.func.alg], specialized algorithms
  template <class R, class... ArgTypes>
    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
}
The function class template provides polymorphic wrappers that generalize the notion of a function pointer.
Wrappers can store, copy, and call arbitrary callable objects ([func.def]), given a call signature ([func.def]), allowing functions to be first-class objects.
A callable type ([func.def]) F is Lvalue-Callable for argument types ArgTypes and return type R if the expression INVOKE<R>(declval<F&>(), declval<ArgTypes>()...), considered as an unevaluated operand (Clause [expr]), is well formed ([func.require]).
The function class template is a call wrapper ([func.def]) whose call signature ([func.def]) is R(ArgTypes...).
[Note
:
The types deduced by the deduction guides for function may change in future versions of this International Standard.
end note
]

23.14.13.2.1 function construct/copy/destroy [func.wrap.func.con]

function() noexcept;
Postconditions: !*this.
function(nullptr_t) noexcept;
Postconditions: !*this.
function(const function& f);
Postconditions: !*this if !f; otherwise, *this targets a copy of f.target().
Throws: shall not throw exceptions if f's target is a specialization of reference_­wrapper or a function pointer.
Otherwise, may throw bad_­alloc or any exception thrown by the copy constructor of the stored callable object.
[Note
:
Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer.
end note
]
function(function&& f);
Postconditions: If !f, *this has no target; otherwise, the target of *this is equivalent to the target of f before the construction, and f is in a valid state with an unspecified value.
Throws: shall not throw exceptions if f's target is a specialization of reference_­wrapper or a function pointer.
Otherwise, may throw bad_­alloc or any exception thrown by the copy or move constructor of the stored callable object.
[Note
:
Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer.
end note
]
template<class F> function(F f);
Requires: F shall be CopyConstructible.
Remarks: This constructor template shall not participate in overload resolution unless F is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
Postconditions: !*this if any of the following hold:
  • f is a null function pointer value.
  • f is a null member pointer value.
  • F is an instance of the function class template, and !f.
Otherwise, *this targets a copy of f initialized with std​::​move(f).
[Note
:
Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f is an object holding only a pointer or reference to an object and a member function pointer.
end note
]
Throws: shall not throw exceptions when f is a function pointer or a reference_­wrapper<T> for some T.
Otherwise, may throw bad_­alloc or any exception thrown by F's copy or move constructor.
template<class F> function(F) -> function<see below>;
Remarks: This deduction guide participates in overload resolution only if &F​::​operator() is well-formed when treated as an unevaluated operand.
In that case, if decltype(&F​::​operator()) is of the form R(G​::​*)(A...) cv & noexcept for a class type G, then the deduced type is function<R(A...)>.
[Example
:
void f() {
  int i{5};
  function g = [&](double) { return i; }; // deduces function<int(double)>
}
end example
]
function& operator=(const function& f);
Effects: As if by function(f).swap(*this);
Returns: *this.
function& operator=(function&& f);
Effects: Replaces the target of *this with the target of f.
Returns: *this.
function& operator=(nullptr_t) noexcept;
Effects: If *this != nullptr, destroys the target of this.
Postconditions: !(*this).
Returns: *this.
template<class F> function& operator=(F&& f);
Effects: As if by: function(std​::​forward<F>(f)).swap(*this);
Returns: *this.
Remarks: This assignment operator shall not participate in overload resolution unless decay_­t<F> is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
template<class F> function& operator=(reference_wrapper<F> f) noexcept;
Effects: As if by: function(f).swap(*this);
Returns: *this.
~function();
Effects: If *this != nullptr, destroys the target of this.

23.14.13.2.2 function modifiers [func.wrap.func.mod]

void swap(function& other) noexcept;
Effects: interchanges the targets of *this and other.

23.14.13.2.3 function capacity [func.wrap.func.cap]

explicit operator bool() const noexcept;
Returns: true if *this has a target, otherwise false.

23.14.13.2.4 function invocation [func.wrap.func.inv]

R operator()(ArgTypes... args) const;
Returns: INVOKE<R>(f, std​::​forward<ArgTypes>(args)...) ([func.require]), where f is the target object ([func.def]) of *this.
Throws: bad_­function_­call if !*this; otherwise, any exception thrown by the wrapped callable object.

23.14.13.2.5 function target access [func.wrap.func.targ]

const type_info& target_type() const noexcept;
Returns: If *this has a target of type T, typeid(T); otherwise, typeid(void).
template<class T> T* target() noexcept; template<class T> const T* target() const noexcept;
Returns: If target_­type() == typeid(T) a pointer to the stored function target; otherwise a null pointer.

23.14.13.2.6 null pointer comparison functions [func.wrap.func.nullptr]

template <class R, class... ArgTypes> bool operator==(const function<R(ArgTypes...)>& f, nullptr_t) noexcept; template <class R, class... ArgTypes> bool operator==(nullptr_t, const function<R(ArgTypes...)>& f) noexcept;
Returns: !f.
template <class R, class... ArgTypes> bool operator!=(const function<R(ArgTypes...)>& f, nullptr_t) noexcept; template <class R, class... ArgTypes> bool operator!=(nullptr_t, const function<R(ArgTypes...)>& f) noexcept;
Returns: (bool)f.

23.14.13.2.7 specialized algorithms [func.wrap.func.alg]

template<class R, class... ArgTypes> void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;
Effects: As if by: f1.swap(f2);

23.14.14 Searchers [func.search]

This subclause provides function object types ([function.objects]) for operations that search for a sequence [pat_first, pat_­last) in another sequence [first, last) that is provided to the object's function call operator.
The first sequence (the pattern to be searched for) is provided to the object's constructor, and the second (the sequence to be searched) is provided to the function call operator.
Each specialization of a class template specified in this subclause [func.search] shall meet the CopyConstructible and CopyAssignable requirements.
Template parameters named of templates specified in this subclause [func.search] shall meet the same requirements and semantics as specified in [algorithms.general].
Template parameters named Hash shall meet the requirements as specified in [hash.requirements].
The Boyer-Moore searcher implements the Boyer-Moore search algorithm.
The Boyer-Moore-Horspool searcher implements the Boyer-Moore-Horspool search algorithm.
In general, the Boyer-Moore searcher will use more memory and give better runtime performance than Boyer-Moore-Horspool.

23.14.14.1 Class template default_­searcher [func.search.default]

template <class ForwardIterator1, class BinaryPredicate = equal_to<>>
  class default_searcher {
  public:
    default_searcher(ForwardIterator1 pat_first, ForwardIterator1 pat_last,
                     BinaryPredicate pred = BinaryPredicate());

    template <class ForwardIterator2>
      pair<ForwardIterator2, ForwardIterator2>
        operator()(ForwardIterator2 first, ForwardIterator2 last) const;

  private:
    ForwardIterator1 pat_first_;        // exposition only
    ForwardIterator1 pat_last_;         // exposition only
    BinaryPredicate pred_;              // exposition only
  };
default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, BinaryPredicate pred = BinaryPredicate());
Effects: Constructs a default_­searcher object, initializing pat_­first_­ with pat_­first, pat_­last_­ with pat_­last, and pred_­ with pred.
Throws: Any exception thrown by the copy constructor of BinaryPredicate or ForwardIterator1.
template<class ForwardIterator2> pair<ForwardIterator2, ForwardIterator2> operator()(ForwardIterator2 first, ForwardIterator2 last) const;
Effects: Returns a pair of iterators i and j such that
  • i == search(first, last, pat_­first_­, pat_­last_­, pred_­), and
  • if i == last, then j == last, otherwise j == next(i, distance(pat_­first_­, pat_­last_­)).

23.14.14.2 Class template boyer_­moore_­searcher [func.search.bm]

template <class RandomAccessIterator1,
          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
          class BinaryPredicate = equal_to<>>
  class boyer_moore_searcher {
  public:
    boyer_moore_searcher(RandomAccessIterator1 pat_first,
                         RandomAccessIterator1 pat_last,
                         Hash hf = Hash(),
                         BinaryPredicate pred = BinaryPredicate());

    template <class RandomAccessIterator2>
      pair<RandomAccessIterator2, RandomAccessIterator2>
        operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;

  private:
    RandomAccessIterator1 pat_first_;   // exposition only
    RandomAccessIterator1 pat_last_;    // exposition only
    Hash hash_;                         // exposition only
    BinaryPredicate pred_;              // exposition only
  };
boyer_moore_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
Requires: The value type of RandomAccessIterator1 shall meet the DefaultConstructible requirements, the CopyConstructible requirements, and the CopyAssignable requirements.
Requires: For any two values A and B of the type iterator_­traits<RandomAccessIterator1>​::​value_­type, if pred(A, B) == true, then hf(A) == hf(B) shall be true.
Effects: Constructs a boyer_­moore_­searcher object, initializing pat_­first_­ with pat_­first, pat_­last_­ with pat_­last, hash_­ with hf, and pred_­ with pred.
Throws: Any exception thrown by the copy constructor of RandomAccessIterator1, or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1, or the copy constructor or operator() of BinaryPredicate or Hash.
May throw bad_­alloc if additional memory needed for internal data structures cannot be allocated.
template <class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
Requires: RandomAccessIterator1 and RandomAccessIterator2 shall have the same value type.
Effects: Finds a subsequence of equal values in a sequence.
Returns: A pair of iterators i and j such that
  • i is the first iterator in the range [first, last - (pat_­last_­ - pat_­first_­)) such that for every non-negative integer n less than pat_­last_­ - pat_­first_­ the following condition holds: pred(*(i + n), *(pat_­first_­ + n)) != false, and
  • j == next(i, distance(pat_­first_­, pat_­last_­)).
Returns make_­pair(first, first) if [pat_­first_­, pat_­last_­) is empty, otherwise returns make_­pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_­last_­ - pat_­first_­) applications of the predicate.

23.14.14.3 Class template boyer_­moore_­horspool_­searcher [func.search.bmh]

template <class RandomAccessIterator1,
          class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,
          class BinaryPredicate = equal_to<>>
  class boyer_moore_horspool_searcher {
  public:
    boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first,
                                  RandomAccessIterator1 pat_last,
                                  Hash hf = Hash(),
                                  BinaryPredicate pred = BinaryPredicate());

    template <class RandomAccessIterator2>
      pair<RandomAccessIterator2, RandomAccessIterator2>
        operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;

  private:
    RandomAccessIterator1 pat_first_;   // exposition only
    RandomAccessIterator1 pat_last_;    // exposition only
    Hash hash_;                         // exposition only
    BinaryPredicate pred_;              // exposition only
  };
boyer_moore_horspool_searcher(RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
Requires: The value type of RandomAccessIterator1 shall meet the DefaultConstructible, CopyConstructible, and CopyAssignable requirements.
Requires: For any two values A and B of the type iterator_­traits<RandomAccessIterator1>​::​value_­type, if pred(A, B) == true, then hf(A) == hf(B) shall be true.
Effects: Constructs a boyer_­moore_­horspool_­searcher object, initializing pat_­first_­ with pat_­first, pat_­last_­ with pat_­last, hash_­ with hf, and pred_­ with pred.
Throws: Any exception thrown by the copy constructor of RandomAccessIterator1, or by the default constructor, copy constructor, or the copy assignment operator of the value type of RandomAccessIterator1 or the copy constructor or operator() of BinaryPredicate or Hash.
May throw bad_­alloc if additional memory needed for internal data structures cannot be allocated.
template <class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const;
Requires: RandomAccessIterator1 and RandomAccessIterator2 shall have the same value type.
Effects: Finds a subsequence of equal values in a sequence.
Returns: A pair of iterators i and j such that
  • i is the first iterator i in the range [first, last - (pat_­last_­ - pat_­first_­)) such that for every non-negative integer n less than pat_­last_­ - pat_­first_­ the following condition holds: pred(*(i + n), *(pat_­first_­ + n)) != false, and
  • j == next(i, distance(pat_­first_­, pat_­last_­)).
Returns make_­pair(first, first) if [pat_­first_­, pat_­last_­) is empty, otherwise returns make_­pair(last, last) if no such iterator is found.
Complexity: At most (last - first) * (pat_­last_­ - pat_­first_­) applications of the predicate.

23.14.15 Class template hash [unord.hash]

The unordered associative containers defined in [unord] use specializations of the class template hash ([functional.syn]) as the default hash function.
Each specialization of hash is either enabled or disabled, as described below.
[Note
:
Enabled specializations meet the requirements of Hash, and disabled specializations do not.
end note
]
Each header that declares the template hash provides enabled specializations of hash for nullptr_­t and all cv-unqualified arithmetic, enumeration, and pointer types.
For any type Key for which neither the library nor the user provides an explicit or partial specialization of the class template hash, hash<Key> is disabled.
If the library provides an explicit or partial specialization of hash<Key>, that specialization is enabled except as noted otherwise, and its member functions are noexcept except as noted otherwise.
If H is a disabled specialization of hash, these values are false: is_­default_­constructible_­v<H>, is_­copy_­constructible_­v<H>, is_­move_­constructible_­v<H>, is_­copy_­assignable_­v<H>, and is_­move_­assignable_­v<H>.
Disabled specializations of hash are not function object types ([function.objects]).
[Note
:
This means that the specialization of hash exists, but any attempts to use it as a Hash will be ill-formed.
end note
]
An enabled specialization hash<Key> will:
  • satisfy the Hash requirements ([hash.requirements]), with Key as the function call argument type, the DefaultConstructible requirements (Table 22), the CopyAssignable requirements (Table 26),
  • be swappable ([swappable.requirements]) for lvalues,
  • satisfy the requirement that if k1 == k2 is true, h(k1) == h(k2) is also true, where h is an object of type hash<Key> and k1 and k2 are objects of type Key;
  • satisfy the requirement that the expression h(k), where h is an object of type hash<Key> and k is an object of type Key, shall not throw an exception unless hash<Key> is a user-defined specialization that depends on at least one user-defined type.

23.15 Metaprogramming and type traits [meta]

This subclause describes components used by C++ programs, particularly in templates, to support the widest possible range of types, optimise template code usage, detect type related user errors, and perform type inference and transformation at compile time.
It includes type classification traits, type property inspection traits, and type transformations.
The type classification traits describe a complete taxonomy of all possible C++ types, and state where in that taxonomy a given type belongs.
The type property inspection traits allow important characteristics of types or of combinations of types to be inspected.
The type transformations allow certain properties of types to be manipulated.
All functions specified in this subclause are signal-safe ([csignal.syn]).

23.15.1 Requirements [meta.rqmts]

A UnaryTypeTrait describes a property of a type.
It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the property being described.
It shall be DefaultConstructible, CopyConstructible, and publicly and unambiguously derived, directly or indirectly, from its base characteristic, which is a specialization of the template integral_­constant ([meta.help]), with the arguments to the template integral_­constant determined by the requirements for the particular property being described.
The member names of the base characteristic shall not be hidden and shall be unambiguously available in the UnaryTypeTrait.
A BinaryTypeTrait describes a relationship between two types.
It shall be a class template that takes two template type arguments and, optionally, additional arguments that help define the relationship being described.
It shall be DefaultConstructible, CopyConstructible, and publicly and unambiguously derived, directly or indirectly, from its base characteristic, which is a specialization of the template integral_­constant ([meta.help]), with the arguments to the template integral_­constant determined by the requirements for the particular relationship being described.
The member names of the base characteristic shall not be hidden and shall be unambiguously available in the BinaryTypeTrait.
A TransformationTrait modifies a property of a type.
It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the modification.
It shall define a publicly accessible nested type named type, which shall be a synonym for the modified type.

23.15.2 Header <type_­traits> synopsis [meta.type.synop]

namespace std {
  // [meta.help], helper class
  template <class T, T v> struct integral_constant;

  template <bool B>
    using bool_constant = integral_constant<bool, B>;
  using true_type  = bool_constant<true>;
  using false_type = bool_constant<false>;

  // [meta.unary.cat], primary type categories
  template <class T> struct is_void;
  template <class T> struct is_null_pointer;
  template <class T> struct is_integral;
  template <class T> struct is_floating_point;
  template <class T> struct is_array;
  template <class T> struct is_pointer;
  template <class T> struct is_lvalue_reference;
  template <class T> struct is_rvalue_reference;
  template <class T> struct is_member_object_pointer;
  template <class T> struct is_member_function_pointer;
  template <class T> struct is_enum;
  template <class T> struct is_union;
  template <class T> struct is_class;
  template <class T> struct is_function;

  // [meta.unary.comp], composite type categories
  template <class T> struct is_reference;
  template <class T> struct is_arithmetic;
  template <class T> struct is_fundamental;
  template <class T> struct is_object;
  template <class T> struct is_scalar;
  template <class T> struct is_compound;
  template <class T> struct is_member_pointer;

  // [meta.unary.prop], type properties
  template <class T> struct is_const;
  template <class T> struct is_volatile;
  template <class T> struct is_trivial;
  template <class T> struct is_trivially_copyable;
  template <class T> struct is_standard_layout;
  template <class T> struct is_pod;
  template <class T> struct is_empty;
  template <class T> struct is_polymorphic;
  template <class T> struct is_abstract;
  template <class T> struct is_final;
  template <class T> struct is_aggregate;

  template <class T> struct is_signed;
  template <class T> struct is_unsigned;

  template <class T, class... Args> struct is_constructible;
  template <class T> struct is_default_constructible;
  template <class T> struct is_copy_constructible;
  template <class T> struct is_move_constructible;

  template <class T, class U> struct is_assignable;
  template <class T> struct is_copy_assignable;
  template <class T> struct is_move_assignable;

  template <class T, class U> struct is_swappable_with;
  template <class T> struct is_swappable;

  template <class T> struct is_destructible;

  template <class T, class... Args> struct is_trivially_constructible;
  template <class T> struct is_trivially_default_constructible;
  template <class T> struct is_trivially_copy_constructible;
  template <class T> struct is_trivially_move_constructible;

  template <class T, class U> struct is_trivially_assignable;
  template <class T> struct is_trivially_copy_assignable;
  template <class T> struct is_trivially_move_assignable;
  template <class T> struct is_trivially_destructible;

  template <class T, class... Args> struct is_nothrow_constructible;
  template <class T> struct is_nothrow_default_constructible;
  template <class T> struct is_nothrow_copy_constructible;
  template <class T> struct is_nothrow_move_constructible;

  template <class T, class U> struct is_nothrow_assignable;
  template <class T> struct is_nothrow_copy_assignable;
  template <class T> struct is_nothrow_move_assignable;

  template <class T, class U> struct is_nothrow_swappable_with;
  template <class T> struct is_nothrow_swappable;

  template <class T> struct is_nothrow_destructible;

  template <class T> struct has_virtual_destructor;

  template <class T> struct has_unique_object_representations;

  // [meta.unary.prop.query], type property queries
  template <class T> struct alignment_of;
  template <class T> struct rank;
  template <class T, unsigned I = 0> struct extent;

  // [meta.rel], type relations
  template <class T, class U> struct is_same;
  template <class Base, class Derived> struct is_base_of;
  template <class From, class To> struct is_convertible;

  template <class Fn, class... ArgTypes> struct is_invocable;
  template <class R, class Fn, class... ArgTypes> struct is_invocable_r;

  template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
  template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;

  // [meta.trans.cv], const-volatile modifications
  template <class T> struct remove_const;
  template <class T> struct remove_volatile;
  template <class T> struct remove_cv;
  template <class T> struct add_const;
  template <class T> struct add_volatile;
  template <class T> struct add_cv;

  template <class T>
    using remove_const_t    = typename remove_const<T>::type;
  template <class T>
    using remove_volatile_t = typename remove_volatile<T>::type;
  template <class T>
    using remove_cv_t       = typename remove_cv<T>::type;
  template <class T>
    using add_const_t       = typename add_const<T>::type;
  template <class T>
    using add_volatile_t    = typename add_volatile<T>::type;
  template <class T>
    using add_cv_t          = typename add_cv<T>::type;

  // [meta.trans.ref], reference modifications
  template <class T> struct remove_reference;
  template <class T> struct add_lvalue_reference;
  template <class T> struct add_rvalue_reference;

  template <class T>
    using remove_reference_t     = typename remove_reference<T>::type;
  template <class T>
    using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
  template <class T>
    using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;

  // [meta.trans.sign], sign modifications
  template <class T> struct make_signed;
  template <class T> struct make_unsigned;

  template <class T>
    using make_signed_t   = typename make_signed<T>::type;
  template <class T>
    using make_unsigned_t = typename make_unsigned<T>::type;

  // [meta.trans.arr], array modifications
  template <class T> struct remove_extent;
  template <class T> struct remove_all_extents;

  template <class T>
    using remove_extent_t      = typename remove_extent<T>::type;
  template <class T>
    using remove_all_extents_t = typename remove_all_extents<T>::type;

  // [meta.trans.ptr], pointer modifications
  template <class T> struct remove_pointer;
  template <class T> struct add_pointer;

  template <class T>
    using remove_pointer_t = typename remove_pointer<T>::type;
  template <class T>
    using add_pointer_t    = typename add_pointer<T>::type;

  // [meta.trans.other], other transformations
  template <size_t Len,
            size_t Align = default-alignment> // see [meta.trans.other]
    struct aligned_storage;
  template <size_t Len, class... Types> struct aligned_union;
  template <class T> struct decay;
  template <bool, class T = void> struct enable_if;
  template <bool, class T, class F> struct conditional;
  template <class... T> struct common_type;
  template <class T> struct underlying_type;
  template <class Fn, class... ArgTypes> struct invoke_result;

  template <size_t Len,
            size_t Align = default-alignment> // see [meta.trans.other]
    using aligned_storage_t = typename aligned_storage<Len, Align>::type;
  template <size_t Len, class... Types>
    using aligned_union_t   = typename aligned_union<Len, Types...>::type;
  template <class T>
    using decay_t           = typename decay<T>::type;
  template <bool b, class T = void>
    using enable_if_t       = typename enable_if<b, T>::type;
  template <bool b, class T, class F>
    using conditional_t     = typename conditional<b, T, F>::type;
  template <class... T>
    using common_type_t     = typename common_type<T...>::type;
  template <class T>
    using underlying_type_t = typename underlying_type<T>::type;
  template <class Fn, class... ArgTypes>
    using invoke_result_t   = typename invoke_result<Fn, ArgTypes...>::type;
  template <class...>
    using void_t            = void;

  // [meta.logical], logical operator traits
  template<class... B> struct conjunction;
  template<class... B> struct disjunction;
  template<class B> struct negation;

  // [meta.unary.cat], primary type categories
  template <class T> inline constexpr bool is_void_v
    = is_void<T>::value;
  template <class T> inline constexpr bool is_null_pointer_v
    = is_null_pointer<T>::value;
  template <class T> inline constexpr bool is_integral_v
    = is_integral<T>::value;
  template <class T> inline constexpr bool is_floating_point_v
    = is_floating_point<T>::value;
  template <class T> inline constexpr bool is_array_v
    = is_array<T>::value;
  template <class T> inline constexpr bool is_pointer_v
    = is_pointer<T>::value;
  template <class T> inline constexpr bool is_lvalue_reference_v
    = is_lvalue_reference<T>::value;
  template <class T> inline constexpr bool is_rvalue_reference_v
    = is_rvalue_reference<T>::value;
  template <class T> inline constexpr bool is_member_object_pointer_v
    = is_member_object_pointer<T>::value;
  template <class T> inline constexpr bool is_member_function_pointer_v
    = is_member_function_pointer<T>::value;
  template <class T> inline constexpr bool is_enum_v
    = is_enum<T>::value;
  template <class T> inline constexpr bool is_union_v
    = is_union<T>::value;
  template <class T> inline constexpr bool is_class_v
    = is_class<T>::value;
  template <class T> inline constexpr bool is_function_v
    = is_function<T>::value;

  // [meta.unary.comp], composite type categories
  template <class T> inline constexpr bool is_reference_v
    = is_reference<T>::value;
  template <class T> inline constexpr bool is_arithmetic_v
    = is_arithmetic<T>::value;
  template <class T> inline constexpr bool is_fundamental_v
    = is_fundamental<T>::value;
  template <class T> inline constexpr bool is_object_v
    = is_object<T>::value;
  template <class T> inline constexpr bool is_scalar_v
    = is_scalar<T>::value;
  template <class T> inline constexpr bool is_compound_v
    = is_compound<T>::value;
  template <class T> inline constexpr bool is_member_pointer_v
    = is_member_pointer<T>::value;

  // [meta.unary.prop], type properties
  template <class T> inline constexpr bool is_const_v
    = is_const<T>::value;
  template <class T> inline constexpr bool is_volatile_v
    = is_volatile<T>::value;
  template <class T> inline constexpr bool is_trivial_v
    = is_trivial<T>::value;
  template <class T> inline constexpr bool is_trivially_copyable_v
    = is_trivially_copyable<T>::value;
  template <class T> inline constexpr bool is_standard_layout_v
    = is_standard_layout<T>::value;
  template <class T> inline constexpr bool is_pod_v
    = is_pod<T>::value;
  template <class T> inline constexpr bool is_empty_v
    = is_empty<T>::value;
  template <class T> inline constexpr bool is_polymorphic_v
    = is_polymorphic<T>::value;
  template <class T> inline constexpr bool is_abstract_v
    = is_abstract<T>::value;
  template <class T> inline constexpr bool is_final_v
    = is_final<T>::value;
  template <class T> inline constexpr bool is_aggregate_v
    = is_aggregate<T>::value;
  template <class T> inline constexpr bool is_signed_v
    = is_signed<T>::value;
  template <class T> inline constexpr bool is_unsigned_v
    = is_unsigned<T>::value;
  template <class T, class... Args> inline constexpr bool is_constructible_v
    = is_constructible<T, Args...>::value;
  template <class T> inline constexpr bool is_default_constructible_v
    = is_default_constructible<T>::value;
  template <class T> inline constexpr bool is_copy_constructible_v
    = is_copy_constructible<T>::value;
  template <class T> inline constexpr bool is_move_constructible_v
    = is_move_constructible<T>::value;
  template <class T, class U> inline constexpr bool is_assignable_v
    = is_assignable<T, U>::value;
  template <class T> inline constexpr bool is_copy_assignable_v
    = is_copy_assignable<T>::value;
  template <class T> inline constexpr bool is_move_assignable_v
    = is_move_assignable<T>::value;
  template <class T, class U> inline constexpr bool is_swappable_with_v
    = is_swappable_with<T, U>::value;
  template <class T> inline constexpr bool is_swappable_v
    = is_swappable<T>::value;
  template <class T> inline constexpr bool is_destructible_v
    = is_destructible<T>::value;
  template <class T, class... Args> inline constexpr bool is_trivially_constructible_v
    = is_trivially_constructible<T, Args...>::value;
  template <class T> inline constexpr bool is_trivially_default_constructible_v
    = is_trivially_default_constructible<T>::value;
  template <class T> inline constexpr bool is_trivially_copy_constructible_v
    = is_trivially_copy_constructible<T>::value;
  template <class T> inline constexpr bool is_trivially_move_constructible_v
    = is_trivially_move_constructible<T>::value;
  template <class T, class U> inline constexpr bool is_trivially_assignable_v
    = is_trivially_assignable<T, U>::value;
  template <class T> inline constexpr bool is_trivially_copy_assignable_v
    = is_trivially_copy_assignable<T>::value;
  template <class T> inline constexpr bool is_trivially_move_assignable_v
    = is_trivially_move_assignable<T>::value;
  template <class T> inline constexpr bool is_trivially_destructible_v
    = is_trivially_destructible<T>::value;
  template <class T, class... Args> inline constexpr bool is_nothrow_constructible_v
    = is_nothrow_constructible<T, Args...>::value;
  template <class T> inline constexpr bool is_nothrow_default_constructible_v
    = is_nothrow_default_constructible<T>::value;
  template <class T> inline constexpr bool is_nothrow_copy_constructible_v
    = is_nothrow_copy_constructible<T>::value;
  template <class T> inline constexpr bool is_nothrow_move_constructible_v
    = is_nothrow_move_constructible<T>::value;
  template <class T, class U> inline constexpr bool is_nothrow_assignable_v
    = is_nothrow_assignable<T, U>::value;
  template <class T> inline constexpr bool is_nothrow_copy_assignable_v
    = is_nothrow_copy_assignable<T>::value;
  template <class T> inline constexpr bool is_nothrow_move_assignable_v
    = is_nothrow_move_assignable<T>::value;
  template <class T, class U> inline constexpr bool is_nothrow_swappable_with_v
    = is_nothrow_swappable_with<T, U>::value;
  template <class T> inline constexpr bool is_nothrow_swappable_v
    = is_nothrow_swappable<T>::value;
  template <class T> inline constexpr bool is_nothrow_destructible_v
    = is_nothrow_destructible<T>::value;
  template <class T> inline constexpr bool has_virtual_destructor_v
    = has_virtual_destructor<T>::value;
  template <class T> inline constexpr bool has_unique_object_representations_v
    = has_unique_object_representations<T>::value;

  // [meta.unary.prop.query], type property queries
  template <class T> inline constexpr size_t alignment_of_v
    = alignment_of<T>::value;
  template <class T> inline constexpr size_t rank_v
    = rank<T>::value;
  template <class T, unsigned I = 0> inline constexpr size_t extent_v
    = extent<T, I>::value;

  // [meta.rel], type relations
  template <class T, class U> inline constexpr bool is_same_v
    = is_same<T, U>::value;
  template <class Base, class Derived> inline constexpr bool is_base_of_v
    = is_base_of<Base, Derived>::value;
  template <class From, class To> inline constexpr bool is_convertible_v
    = is_convertible<From, To>::value;
  template <class Fn, class... ArgTypes> inline constexpr bool is_invocable_v
    = is_invocable<Fn, ArgTypes...>::value;
  template <class R, class Fn, class... ArgTypes> inline constexpr bool is_invocable_r_v
    = is_invocable_r<R, Fn, ArgTypes...>::value;
  template <class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_v
    = is_nothrow_invocable<Fn, ArgTypes...>::value;
  template <class R, class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_r_v
    = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;

  // [meta.logical], logical operator traits
  template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value;
  template<class... B> inline constexpr bool disjunction_v = disjunction<B...>::value;
  template<class B> inline constexpr bool negation_v = negation<B>::value;
}
The behavior of a program that adds specializations for any of the templates defined in this subclause is undefined unless otherwise specified.
Unless otherwise specified, an incomplete type may be used to instantiate a template in this subclause.

23.15.3 Helper classes [meta.help]

namespace std {
  template <class T, T v>
  struct integral_constant {
    static constexpr T value = v;
    using value_type = T;
    using type       = integral_constant<T, v>;
    constexpr operator value_type() const noexcept { return value; }
    constexpr value_type operator()() const noexcept { return value; }
  };
}
The class template integral_­constant, alias template bool_­constant, and its associated typedef-names true_­type and false_­type are used as base classes to define the interface for various type traits.

23.15.4 Unary type traits [meta.unary]

This subclause contains templates that may be used to query the properties of a type at compile time.
Each of these templates shall be a UnaryTypeTrait ([meta.rqmts]) with a base characteristic of true_­type if the corresponding condition is true, otherwise false_­type.

23.15.4.1 Primary type categories [meta.unary.cat]

The primary type categories correspond to the descriptions given in section [basic.types] of the C++ standard.
For any given type T, the result of applying one of these templates to T and to cv T shall yield the same result.
[Note
:
For any given type T, exactly one of the primary type categories has a value member that evaluates to true.
end note
]
Table 35 — Primary type category predicates
Template
Condition
Comments
template <class T>
struct is_­void;
T is void
template <class T>
struct is_­null_­pointer;
T is nullptr_­t ([basic.fundamental])
template <class T>
struct is_­integral;
T is an integral type ([basic.fundamental])
template <class T>
struct is_­floating_­point;
T is a floating-point type ([basic.fundamental])
template <class T>
struct is_­array;
T is an array type ([basic.compound]) of known or unknown extent
Class template array ([array]) is not an array type.
template <class T>
struct is_­pointer;
T is a pointer type ([basic.compound])
Includes pointers to functions but not pointers to non-static members.
template <class T>
struct is_­lvalue_­reference;
T is an lvalue reference type ([dcl.ref])
template <class T>
struct is_­rvalue_­reference;
T is an rvalue reference type ([dcl.ref])
template <class T>
struct is_­member_­object_­pointer;
T is a pointer to non-static data member
template <class T>
struct is_­member_­function_­pointer;
T is a pointer to non-static member function
template <class T>
struct is_­enum;
T is an enumeration type ([basic.compound])
template <class T>
struct is_­union;
T is a union type ([basic.compound])
template <class T>
struct is_­class;
T is a non-union class type ([basic.compound])
template <class T>
struct is_­function;
T is a function type ([basic.compound])

23.15.4.2 Composite type traits [meta.unary.comp]

These templates provide convenient compositions of the primary type categories, corresponding to the descriptions given in section [basic.types].
For any given type T, the result of applying one of these templates to T and to cv T shall yield the same result.
Table 36 — Composite type category predicates
Template
Condition
Comments
template <class T>
struct is_­reference;
T is an lvalue reference or an rvalue reference
template <class T>
struct is_­arithmetic;
T is an arithmetic type ([basic.fundamental])
template <class T>
struct is_­fundamental;
T is a fundamental type ([basic.fundamental])
template <class T>
struct is_­object;
T is an object type ([basic.types])
template <class T>
struct is_­scalar;
T is a scalar type ([basic.types])
template <class T>
struct is_­compound;
T is a compound type ([basic.compound])
template <class T>
struct is_­member_­pointer;
T is a pointer to non-static data member or non-static member function

23.15.4.3 Type properties [meta.unary.prop]

These templates provide access to some of the more important properties of types.
It is unspecified whether the library defines any full or partial specializations of any of these templates.
For all of the class templates X declared in this subclause, instantiating that template with a template-argument that is a class template specialization may result in the implicit instantiation of the template argument if and only if the semantics of X require that the argument must be a complete type.
For the purpose of defining the templates in this subclause, a function call expression declval<T>() for any type T is considered to be a trivial ([basic.types], [special]) function call that is not an odr-use ([basic.def.odr]) of declval in the context of the corresponding definition notwithstanding the restrictions of [declval].
Table 37 — Type property predicates
Template
Condition
Preconditions
template <class T>
struct is_­const;
T is const-qualified ([basic.type.qualifier])
template <class T>
struct is_­volatile;
T is volatile-qualified ([basic.type.qualifier])
template <class T>
struct is_­trivial;
T is a trivial type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­trivially_­copyable;
T is a trivially copyable type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­standard_­layout;
T is a standard-layout type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­pod;
T is a POD type ([basic.types])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­empty;
T is a class type, but not a union type, with no non-static data members other than bit-fields of length 0, no virtual member functions, no virtual base classes, and no base class B for which is_­empty_­v<B> is false.
If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_­polymorphic;
T is a polymorphic class ([class.virtual])
If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_­abstract;
T is an abstract class ([class.abstract])
If T is a non-union class type, T shall be a complete type.
template <class T>
struct is_­final;
T is a class type marked with the class-virt-specifier final (Clause [class]).
[Note
:
A union is a class type that can be marked with final.
end note
]
If T is a class type, T shall be a complete type.
template <class T>
struct is_­aggregate;
T is an aggregate type ([dcl.init.aggr])
remove_­all_­extents_­t<T> shall be a complete type or cv void.
template <class T>
struct is_­signed;
If is_­arithmetic_­v<T> is true, the same result as T(-1) < T(0); otherwise, false
template <class T>
struct is_­unsigned;
If is_­arithmetic_­v<T> is true, the same result as T(0) < T(-1); otherwise, false
template <class T, class... Args>
struct is_­constructible;
For a function type T or for a cv void type T, is_­constructible_­v<T, Args...> is false, otherwise see below
T and all types in the parameter pack Args shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­default_­constructible;
is_­constructible_­v<T> is true.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­copy_­constructible;
For a referenceable type T ([defns.referenceable]), the same result as is_­constructible_­v<T, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­move_­constructible;
For a referenceable type T, the same result as is_­constructible_­v<T, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­assignable;
The expression declval<T>() = declval<U>() is well-formed when treated as an unevaluated operand (Clause [expr]).
Access checking is performed as if in a context unrelated to T and U.
Only the validity of the immediate context of the assignment expression is considered.
[Note
:
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­copy_­assignable;
For a referenceable type T, the same result as is_­assignable_­v<T&, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­move_­assignable;
For a referenceable type T, the same result as is_­assignable_­v<T&, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­swappable_­with;
The expressions swap(declval<T>(), declval<U>()) and swap(declval<U>(), declval<T>()) are each well-formed when treated as an unevaluated operand (Clause [expr]) in an overload-resolution context for swappable values ([swappable.requirements]).
Access checking is performed as if in a context unrelated to T and U.
Only the validity of the immediate context of the swap expressions is considered.
[Note
:
The compilation of the expressions can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­swappable;
For a referenceable type T, the same result as is_­swappable_­with_­v<T&, T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­destructible;
Either T is a reference type, or T is a complete object type for which the expression declval<U&>().~U() is well-formed when treated as an unevaluated operand (Clause [expr]), where U is remove_­all_­extents<T>.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class... Args>
struct
is_­trivially_­constructible;
is_­constructible_­v<T,
Args...> is true and the variable definition for is_­constructible, as defined below, is known to call no operation that is not trivial ([basic.types], [special]).
T and all types in the parameter pack Args shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­trivially_­default_­constructible;
is_­trivially_­constructible_­v<T> is true.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­copy_­constructible;
For a referenceable type T, the same result as is_­trivially_­constructible_­v<T, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­move_­constructible;
For a referenceable type T, the same result as is_­trivially_­constructible_­v<T, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­trivially_­assignable;
is_­assignable_­v<T, U> is true and the assignment, as defined by is_­assignable, is known to call no operation that is not trivial ([basic.types], [special]).
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­trivially_­copy_­assignable;
For a referenceable type T, the same result as is_­trivially_­assignable_­v<T&, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­move_­assignable;
For a referenceable type T, the same result as is_­trivially_­assignable_­v<T&, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­trivially_­destructible;
is_­destructible_­v<T> is true and the indicated destructor is known to be trivial.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class... Args>
struct is_­nothrow_­constructible;
is_­constructible_­v<T, Args...> is true and the variable definition for is_­constructible, as defined below, is known not to throw any exceptions ([expr.unary.noexcept]).
T and all types in the parameter pack Args shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­nothrow_­default_­constructible;
is_­nothrow_­constructible_­v<T> is true.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­copy_­constructible;
For a referenceable type T, the same result as is_­nothrow_­constructible_­v<T, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­move_­constructible;
For a referenceable type T, the same result as is_­nothrow_­constructible_­v<T, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­nothrow_­assignable;
is_­assignable_­v<T, U> is true and the assignment is known not to throw any exceptions ([expr.unary.noexcept]).
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­nothrow_­copy_­assignable;
For a referenceable type T, the same result as is_­nothrow_­assignable_­v<T&, const T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­move_­assignable;
For a referenceable type T, the same result as is_­nothrow_­assignable_­v<T&, T&&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T, class U>
struct is_­nothrow_­swappable_­with;
is_­swappable_­with_­v<T, U> is true and each swap expression of the definition of is_­swappable_­with<T, U> is known not to throw any exceptions ([expr.unary.noexcept]).
T and U shall be complete types, cv void, or arrays of unknown bound.
template <class T>
struct is_­nothrow_­swappable;
For a referenceable type T, the same result as is_­nothrow_­swappable_­with_­v<T&, T&>, otherwise false.
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct is_­nothrow_­destructible;
is_­destructible_­v<T> is true and the indicated destructor is known not to throw any exceptions ([expr.unary.noexcept]).
T shall be a complete type, cv void, or an array of unknown bound.
template <class T>
struct has_­virtual_­destructor;
T has a virtual destructor ([class.dtor])
If T is a non-union class type, T shall be a complete type.
template <class T>
struct has_­unique_­object_­representations;
For an array type T, the same result as has_­unique_­object_­representations_­v<remove_­all_­extents_­t<T>>, otherwise see below.
T shall be a complete type, cv void, or an array of unknown bound.
[Example
:
is_const_v<const volatile int>     // true
is_const_v<const int*>             // false
is_const_v<const int&>             // false
is_const_v<int[3]>                 // false
is_const_v<const int[3]>           // true
end example
]
[Example
:
remove_const_t<const volatile int>  // volatile int
remove_const_t<const int* const>    // const int*
remove_const_t<const int&>          // const int&
remove_const_t<const int[3]>        // int[3]
end example
]
[Example
:
// Given:
struct P final { };
union U1 { };
union U2 final { };

// the following assertions hold:
static_assert(!is_final_v<int>);
static_assert(is_final_v<P>);
static_assert(!is_final_v<U1>);
static_assert(is_final_v<U2>);
end example
]
The predicate condition for a template specialization is_­constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:
T t(declval<Args>()...);
[Note
:
These tokens are never interpreted as a function declaration.
end note
]
Access checking is performed as if in a context unrelated to T and any of the Args.
Only the validity of the immediate context of the variable initialization is considered.
[Note
:
The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]
The predicate condition for a template specialization has_­unique_­object_­representations<T> shall be satisfied if and only if:
  • T is trivially copyable, and
  • any two objects of type T with the same value have the same object representation, where two objects of array or non-union class type are considered to have the same value if their respective sequences of direct subobjects have the same values, and two objects of union type are considered to have the same value if they have the same active member and the corresponding members have the same value.
The set of scalar types for which this condition holds is implementation-defined.
[Note
:
If a type has padding bits, the condition does not hold; otherwise, the condition holds true for unsigned integral types.
end note
]

23.15.5 Type property queries [meta.unary.prop.query]

This subclause contains templates that may be used to query properties of types at compile time.
Table 38 — Type property queries
Template
Value
template <class T>
struct alignment_­of;
alignof(T).

Requires: alignof(T) shall be a valid expression ([expr.alignof])
template <class T>
struct rank;
If T names an array type, an integer value representing the number of dimensions of T; otherwise, 0.
template <class T,
unsigned I = 0>
struct extent;
If T is not an array type, or if it has rank less than or equal to I, or if I is 0 and T has type “array of unknown bound of U”, then 0; otherwise, the bound ([dcl.array]) of the I'th dimension of T, where indexing of I is zero-based
Each of these templates shall be a UnaryTypeTrait ([meta.rqmts]) with a base characteristic of integral_­constant<size_­t, Value>.
[Example
:
// the following assertions hold:
assert(rank_v<int> == 0);
assert(rank_v<int[2]> == 1);
assert(rank_v<int[][4]> == 2);
end example
]
[Example
:
// the following assertions hold:
assert(extent_v<int> == 0);
assert(extent_v<int[2]> == 2);
assert(extent_v<int[2][4]> == 2);
assert(extent_v<int[][4]> == 0);
assert((extent_v<int, 1>) == 0);
assert((extent_v<int[2], 1>) == 0);
assert((extent_v<int[2][4], 1>) == 4);
assert((extent_v<int[][4], 1>) == 4);
end example
]

23.15.6 Relationships between types [meta.rel]

This subclause contains templates that may be used to query relationships between types at compile time.
Each of these templates shall be a BinaryTypeTrait ([meta.rqmts]) with a base characteristic of true_­type if the corresponding condition is true, otherwise false_­type.
Table 39 — Type relationship predicates
Template
Condition
Comments
template <class T, class U>
struct is_­same;
T and U name the same type with the same cv-qualifications
template <class Base, class Derived>
struct is_­base_­of;
Base is a base class of Derived (Clause [class.derived]) without regard to cv-qualifiers or Base and Derived are not unions and name the same class type without regard to cv-qualifiers
If Base and Derived are non-union class types and are not possibly cv-qualified versions of the same type, Derived shall be a complete type.
[Note
:
Base classes that are private, protected, or ambiguous are, nonetheless, base classes.
end note
]
template <class From, class To>
struct is_­convertible;
see below
From and To shall be complete types, arrays of unknown bound, or cv void types.
template <class Fn, class... ArgTypes>
struct is_­invocable;
The expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand
Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes>
struct is_­invocable_­r;
The expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand
Fn, R, and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class Fn, class... ArgTypes>
struct is_­nothrow_­invocable;
is_­invocable_­v<
Fn, ArgTypes...> is true and the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions
Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes>
struct is_­nothrow_­invocable_­r;
is_­invocable_­r_­v<
R, Fn, ArgTypes...> is true and the expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions
Fn, R, and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
For the purpose of defining the templates in this subclause, a function call expression declval<T>() for any type T is considered to be a trivial ([basic.types], [special]) function call that is not an odr-use ([basic.def.odr]) of declval in the context of the corresponding definition notwithstanding the restrictions of [declval].
[Example
:
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : private B1, private B2 {};

is_base_of_v<B, D>         // true
is_base_of_v<const B, D>   // true
is_base_of_v<B, const D>   // true
is_base_of_v<B, const B>   // true
is_base_of_v<D, B>         // false
is_base_of_v<B&, D&>       // false
is_base_of_v<B[3], D[3]>   // false
is_base_of_v<int, int>     // false
end example
]
The predicate condition for a template specialization is_­convertible<From, To> shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:
To test() {
  return declval<From>();
}
[Note
:
This requirement gives well defined results for reference types, void types, array types, and function types.
end note
]
Access checking is performed in a context unrelated to To and From.
Only the validity of the immediate context of the expression of the return statement (including initialization of the returned object or reference) is considered.
[Note
:
The initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]

23.15.7 Transformations between types [meta.trans]

This subclause contains templates that may be used to transform one type to another following some predefined rule.
Each of the templates in this subclause shall be a TransformationTrait ([meta.rqmts]).

23.15.7.1 Const-volatile modifications [meta.trans.cv]

Table 40 — Const-volatile modifications
Template
Comments
template <class T>
struct remove_­const;
The member typedef type names the same type as T except that any top-level const-qualifier has been removed.
[Example
:
remove_­const_­t<const volatile int> evaluates to volatile int, whereas remove_­const_­t<const int*> evaluates to const int*.
end example
]
template <class T>
struct remove_­volatile;
The member typedef type names the same type as T except that any top-level volatile-qualifier has been removed.
[Example
:
remove_­volatile_­t<const volatile int> evaluates to const int, whereas remove_­volatile_­t<volatile int*> evaluates to volatile int*.
end example
]
template <class T>
struct remove_­cv;
The member typedef type shall be the same as T except that any top-level cv-qualifier has been removed.
[Example
:
remove_­cv_­t<const volatile int> evaluates to int, whereas remove_­cv_­t<const volatile int*> evaluates to const volatile int*.
end example
]
template <class T>
struct add_­const;
If T is a reference, function, or top-level const-qualified type, then type names the same type as T, otherwise T const.
template <class T>
struct add_­volatile;
If T is a reference, function, or top-level volatile-qualified type, then type names the same type as T, otherwise T volatile.
template <class T>
struct add_­cv;
The member typedef type names the same type as add_­const_­t<add_­volatile_­t<T>>.

23.15.7.2 Reference modifications [meta.trans.ref]

Table 41 — Reference modifications
Template
Comments
template <class T>
struct remove_­reference;
If T has type “reference to T1” then the member typedef type names T1; otherwise, type names T.
template <class T>
struct add_­lvalue_­reference;
If T names a referenceable type ([defns.referenceable]) then the member typedef type names T&; otherwise, type names T.
[Note
:
This rule reflects the semantics of reference collapsing ([dcl.ref]).
end note
]
template <class T>
struct add_­rvalue_­reference;
If T names a referenceable type then the member typedef type names T&&; otherwise, type names T.
[Note
:
This rule reflects the semantics of reference collapsing ([dcl.ref]).
For example, when a type T names a type T1&, the type add_­rvalue_­reference_­t<T> is not an rvalue reference.
end note
]

23.15.7.3 Sign modifications [meta.trans.sign]

Table 42 — Sign modifications
Template
Comments
template <class T>
struct make_­signed;
If T names a (possibly cv-qualified) signed integer type ([basic.fundamental]) then the member typedef type names the type T; otherwise, if T names a (possibly cv-qualified) unsigned integer type then type names the corresponding signed integer type, with the same cv-qualifiers as T; otherwise, type names the signed integer type with smallest rank ([conv.rank]) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T.

Requires: T shall be a (possibly cv-qualified) integral type or enumeration but not a bool type.
template <class T>
struct make_­unsigned;
If T names a (possibly cv-qualified) unsigned integer type ([basic.fundamental]) then the member typedef type names the type T; otherwise, if T names a (possibly cv-qualified) signed integer type then type names the corresponding unsigned integer type, with the same cv-qualifiers as T; otherwise, type names the unsigned integer type with smallest rank ([conv.rank]) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T.

Requires: T shall be a (possibly cv-qualified) integral type or enumeration but not a bool type.

23.15.7.4 Array modifications [meta.trans.arr]

Table 43 — Array modifications
Template
Comments
template <class T>
struct remove_­extent;
If T names a type “array of U”, the member typedef type shall be U, otherwise T.
[Note
:
For multidimensional arrays, only the first array dimension is removed.
For a type “array of const U”, the resulting type is const U.
end note
]
template <class T>
struct remove_­all_­extents;
If T is “multi-dimensional array of U”, the resulting member typedef type is U, otherwise T.
[Example
:
// the following assertions hold:
assert((is_same_v<remove_extent_t<int>, int>));
assert((is_same_v<remove_extent_t<int[2]>, int>));
assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>));
assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));
end example
]
[Example
:
// the following assertions hold:
assert((is_same_v<remove_all_extents_t<int>, int>));
assert((is_same_v<remove_all_extents_t<int[2]>, int>));
assert((is_same_v<remove_all_extents_t<int[2][3]>, int>));
assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
end example
]

23.15.7.5 Pointer modifications [meta.trans.ptr]

Table 44 — Pointer modifications
Template
Comments
template <class T>
struct remove_­pointer;
If T has type “(possibly cv-qualified) pointer to T1” then the member typedef type names T1; otherwise, it names T.
template <class T>
struct add_­pointer;
If T names a referenceable type ([defns.referenceable]) or a cv void type then the member typedef type names the same type as remove_­reference_­t<T>*; otherwise, type names T.

23.15.7.6 Other transformations [meta.trans.other]

Table 45 — Other transformations
Template
Comments
template <size_­t Len,
size_­t Align
= default-alignment>
struct aligned_­storage;
The value of default-alignment shall be the most stringent alignment requirement for any C++ object type whose size is no greater than Len ([basic.types]).
The member typedef type shall be a POD type suitable for use as uninitialized storage for any object whose size is at most Len and whose alignment is a divisor of Align.

Requires: Len shall not be zero.
Align shall be equal to alignof(T) for some type T or to default-alignment.
template <size_­t Len,
class... Types>
struct aligned_­union;
The member typedef type shall be a POD type suitable for use as uninitialized storage for any object whose type is listed in Types; its size shall be at least Len.
The static member alignment_­value shall be an integral constant of type size_­t whose value is the strictest alignment of all types listed in Types.

Requires: At least one type is provided.
template <class T>
struct decay;
Let U be remove_­reference_­t<T>.
If is_­array_­v<U> is true, the member typedef type shall equal remove_­extent_­t<U>*.
If is_­function_­v<U> is true, the member typedef type shall equal add_­pointer_­t<U>.
Otherwise the member typedef type equals remove_­cv_­t<U>.
[Note
:
This behavior is similar to the lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) conversions applied when an lvalue expression is used as an rvalue, but also strips cv-qualifiers from class types in order to more closely model by-value argument passing.
end note
]
template <bool B, class T = void> struct enable_­if;
If B is true, the member typedef type shall equal T; otherwise, there shall be no member type.
template <bool B, class T, class F>
struct conditional;
If B is true, the member typedef type shall equal T.
If B is false, the member typedef type shall equal F.
template <class... T> struct common_­type;
Unless this trait is specialized (as specified in Note B, below), the member type shall be defined or omitted as specified in Note A, below.
If it is omitted, there shall be no member type.
Each type in the parameter pack T shall be complete, cv void, or an array of unknown bound.
template <class T>
struct underlying_­type;
The member typedef type names the underlying type of T.

Requires: T shall be a complete enumeration type ([dcl.enum])
template <class Fn,
class... ArgTypes>
struct invoke_­result;
If the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is well formed when treated as an unevaluated operand (Clause [expr]), the member typedef type names the type decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...)); otherwise, there shall be no member type.
Access checking is performed as if in a context unrelated to Fn and ArgTypes.
Only the validity of the immediate context of the expression is considered.
[Note
:
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on.
Such side effects are not in the “immediate context” and can result in the program being ill-formed.
end note
]

Requires: Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
[Note
:
A typical implementation would define aligned_­storage as:
template <size_t Len, size_t Alignment>
struct aligned_storage {
  typedef struct {
    alignas(Alignment) unsigned char __data[Len];
  } type;
};
end note
]
It is implementation-defined whether any extended alignment is supported ([basic.align]).
Note A: For the common_­type trait applied to a parameter pack T of types, the member type shall be either defined or not present as follows:
  • If sizeof...(T) is zero, there shall be no member type.
  • If sizeof...(T) is one, let T0 denote the sole type constituting the pack T.
    The member typedef-name type shall denote the same type, if any, as common_­type_­t<T0, T0>; otherwise there shall be no member type.
  • If sizeof...(T) is two, let the first and second types constituting T be denoted by T1 and T2, respectively, and let D1 and D2 denote the same types as decay_­t<T1> and decay_­t<T2>, respectively.
    • If is_­same_­v<T1, D1> is false or is_­same_­v<T2, D2> is false, let C denote the same type, if any, as common_­type_­t<D1, D2>.
    • Otherwise, let C denote the same type, if any, as
      decay_t<decltype(false ? declval<D1>() : declval<D2>())>
      [Note
      :
      This will not apply if there is a specialization common_­type<D1, D2>.
      end note
      ]
    In either case, the member typedef-name type shall denote the same type, if any, as C.
    Otherwise, there shall be no member type.
  • If sizeof...(T) is greater than two, let T1, T2, and R, respectively, denote the first, second, and (pack of) remaining types constituting T.
    Let C denote the same type, if any, as common_­type_­t<T1, T2>.
    If there is such a type C, the member typedef-name type shall denote the same type, if any, as common_­type_­t<C, R...>.
    Otherwise, there shall be no member type.
Note B: Notwithstanding the provisions of [meta.type.synop], and pursuant to [namespace.std], a program may specialize common_­type<T1, T2> for types T1 and T2 such that is_­same_­v<T1, decay_­t<T1>> and is_­same_­v<T2, decay_­t<T2>> are each true.
[Note
:
Such specializations are needed when only explicit conversions are desired between the template arguments.
end note
]
Such a specialization need not have a member named type, but if it does, that member shall be a typedef-name for an accessible and unambiguous cv-unqualified non-reference type C to which each of the types T1 and T2 is explicitly convertible.
Moreover, common_­type_­t<T1, T2> shall denote the same type, if any, as does common_­type_­t<T2, T1>.
No diagnostic is required for a violation of this Note's rules.
[Example
:
Given these definitions:
using PF1 = bool  (&)();
using PF2 = short (*)(long);

struct S {
  operator PF2() const;
  double operator()(char, int&);
  void fn(long) const;
  char data;
};

using PMF = void (S::*)(long) const;
using PMD = char  S::*;
the following assertions will hold:
static_assert(is_same_v<invoke_result_t<S, int>, short>);
static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);
static_assert(is_same_v<invoke_result_t<PF1>, bool>);
static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);
static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);
static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
end example
]

23.15.8 Logical operator traits [meta.logical]

This subclause describes type traits for applying logical operators to other type traits.
template<class... B> struct conjunction : see below { };
The class template conjunction forms the logical conjunction of its template type arguments.
For a specialization conjunction<B1, ..., BN>, if there is a template type argument Bi for which bool(Bi​::​value) is false, then instantiating conjunction<B1, ..., BN>​::​value does not require the instantiation of Bj​::​value for j > i.
[Note
:
This is analogous to the short-circuiting behavior of the built-in operator &&.
end note
]
Every template type argument for which Bi​::​value is instantiated shall be usable as a base class and shall have a member value which is convertible to bool, is not hidden, and is unambiguously available in the type.
The specialization conjunction<B1, ..., BN> has a public and unambiguous base that is either
  • the first type Bi in the list true_­type, B1, ..., BN for which bool(Bi​::​value) is false, or
  • if there is no such Bi, the last type in the list.
[Note
:
This means a specialization of conjunction does not necessarily inherit from either true_­type or false_­type.
end note
]
The member names of the base class, other than conjunction and operator=, shall not be hidden and shall be unambiguously available in conjunction.
template<class... B> struct disjunction : see below { };
The class template disjunction forms the logical disjunction of its template type arguments.
For a specialization disjunction<B1, ..., BN>, if there is a template type argument Bi for which bool(Bi​::​value) is true, then instantiating disjunction<B1, ..., BN>​::​value does not require the instantiation of Bj​::​value for j > i.
[Note
:
This is analogous to the short-circuiting behavior of the built-in operator ||.
end note
]
Every template type argument for which Bi​::​value is instantiated shall be usable as a base class and shall have a member value which is convertible to bool, is not hidden, and is unambiguously available in the type.
The specialization disjunction<B1, ..., BN> has a public and unambiguous base that is either
  • the first type Bi in the list false_­type, B1, ..., BN for which bool(Bi​::​value) is true, or
  • if there is no such Bi, the last type in the list.
[Note
:
This means a specialization of disjunction does not necessarily inherit from either true_­type or false_­type.
end note
]
The member names of the base class, other than disjunction and operator=, shall not be hidden and shall be unambiguously available in disjunction.
template<class B> struct negation : see below { };
The class template negation forms the logical negation of its template type argument.
The type negation<B> is a UnaryTypeTrait with a base characteristic of bool_­constant<!bool(B​::​value)>.

23.16 Compile-time rational arithmetic [ratio]

23.16.1 In general [ratio.general]

This subclause describes the ratio library.
It provides a class template ratio which exactly represents any finite rational number with a numerator and denominator representable by compile-time constants of type intmax_­t.
Throughout this subclause, the names of template parameters are used to express type requirements.
If a template parameter is named R1 or R2, and the template argument is not a specialization of the ratio template, the program is ill-formed.

23.16.2 Header <ratio> synopsis [ratio.syn]

namespace std {
  // [ratio.ratio], class template ratio
  template <intmax_t N, intmax_t D = 1> class ratio;

  // [ratio.arithmetic], ratio arithmetic
  template <class R1, class R2> using ratio_add = see below;
  template <class R1, class R2> using ratio_subtract = see below;
  template <class R1, class R2> using ratio_multiply = see below;
  template <class R1, class R2> using ratio_divide = see below;

  // [ratio.comparison], ratio comparison
  template <class R1, class R2> struct ratio_equal;
  template <class R1, class R2> struct ratio_not_equal;
  template <class R1, class R2> struct ratio_less;
  template <class R1, class R2> struct ratio_less_equal;
  template <class R1, class R2> struct ratio_greater;
  template <class R1, class R2> struct ratio_greater_equal;

  template <class R1, class R2>
    inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
  template <class R1, class R2>
    inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;

  // [ratio.si], convenience SI typedefs
  using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>;  // see below
  using zepto = ratio<1,     1'000'000'000'000'000'000'000>;  // see below
  using atto  = ratio<1,         1'000'000'000'000'000'000>;
  using femto = ratio<1,             1'000'000'000'000'000>;
  using pico  = ratio<1,                 1'000'000'000'000>;
  using nano  = ratio<1,                     1'000'000'000>;
  using micro = ratio<1,                         1'000'000>;
  using milli = ratio<1,                             1'000>;
  using centi = ratio<1,                               100>;
  using deci  = ratio<1,                                10>;
  using deca  = ratio<                               10, 1>;
  using hecto = ratio<                              100, 1>;
  using kilo  = ratio<                            1'000, 1>;
  using mega  = ratio<                        1'000'000, 1>;
  using giga  = ratio<                    1'000'000'000, 1>;
  using tera  = ratio<                1'000'000'000'000, 1>;
  using peta  = ratio<            1'000'000'000'000'000, 1>;
  using exa   = ratio<        1'000'000'000'000'000'000, 1>;
  using zetta = ratio<    1'000'000'000'000'000'000'000, 1>;  // see below
  using yotta = ratio<1'000'000'000'000'000'000'000'000, 1>;  // see below
}

23.16.3 Class template ratio [ratio.ratio]

namespace std {
  template <intmax_t N, intmax_t D = 1>
  class ratio {
  public:
    static constexpr intmax_t num;
    static constexpr intmax_t den;
    using type = ratio<num, den>;
  };
}
If the template argument D is zero or the absolute values of either of the template arguments N and D is not representable by type intmax_­t, the program is ill-formed.
[Note
:
These rules ensure that infinite ratios are avoided and that for any negative input, there exists a representable value of its absolute value which is positive.
In a two's complement representation, this excludes the most negative value.
end note
]
The static data members num and den shall have the following values, where gcd represents the greatest common divisor of the absolute values of N and D:
  • num shall have the value sign(N) * sign(D) * abs(N) / gcd.
  • den shall have the value abs(D) / gcd.

23.16.4 Arithmetic on ratios [ratio.arithmetic]

Each of the alias templates ratio_­add, ratio_­subtract, ratio_­multiply, and ratio_­divide denotes the result of an arithmetic computation on two ratios R1 and R2.
With X and Y computed (in the absence of arithmetic overflow) as specified by Table 46, each alias denotes a ratio<U, V> such that U is the same as ratio<X, Y>​::​num and V is the same as ratio<X, Y>​::​den.
If it is not possible to represent U or V with intmax_­t, the program is ill-formed.
Otherwise, an implementation should yield correct values of U and V.
If it is not possible to represent X or Y with intmax_­t, the program is ill-formed unless the implementation yields correct values of U and V.
Table 46 — Expressions used to perform ratio arithmetic
Type
Value of X
Value of Y
ratio_­add<R1, R2>
R1​::​num * R2​::​den +
R1​::​den * R2​::​den
R2​::​num * R1​::​den
ratio_­subtract<R1, R2>
R1​::​num * R2​::​den -
R1​::​den * R2​::​den
R2​::​num * R1​::​den
ratio_­multiply<R1, R2>
R1​::​num * R2​::​num
R1​::​den * R2​::​den
ratio_­divide<R1, R2>
R1​::​num * R2​::​den
R1​::​den * R2​::​num
[Example
:
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::num == 1, "1/3+1/6 == 1/2");
static_assert(ratio_add<ratio<1, 3>, ratio<1, 6>>::den == 2, "1/3+1/6 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::num == 1, "1/3*3/2 == 1/2");
static_assert(ratio_multiply<ratio<1, 3>, ratio<3, 2>>::den == 2, "1/3*3/2 == 1/2");

// The following cases may cause the program to be ill-formed under some implementations
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::num == 2,
  "1/MAX+1/MAX == 2/MAX");
static_assert(ratio_add<ratio<1, INT_MAX>, ratio<1, INT_MAX>>::den == INT_MAX,
  "1/MAX+1/MAX == 2/MAX");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::num == 1,
  "1/MAX * MAX/2 == 1/2");
static_assert(ratio_multiply<ratio<1, INT_MAX>, ratio<INT_MAX, 2>>::den == 2,
  "1/MAX * MAX/2 == 1/2");
end example
]

23.16.5 Comparison of ratios [ratio.comparison]

template <class R1, class R2> struct ratio_equal : bool_constant<R1::num == R2::num && R1::den == R2::den> { };
template <class R1, class R2> struct ratio_not_equal : bool_constant<!ratio_equal_v<R1, R2>> { };
template <class R1, class R2> struct ratio_less : bool_constant<see below> { };
If R1​::​num × R2​::​den is less than R2​::​num × R1​::​den, ratio_­less<R1, R2> shall be derived from bool_­constant<true>; otherwise it shall be derived from bool_­constant<false>.
Implementations may use other algorithms to compute this relationship to avoid overflow.
If overflow occurs, the program is ill-formed.
template <class R1, class R2> struct ratio_less_equal : bool_constant<!ratio_less_v<R2, R1>> { };
template <class R1, class R2> struct ratio_greater : bool_constant<ratio_less_v<R2, R1>> { };
template <class R1, class R2> struct ratio_greater_equal : bool_constant<!ratio_less_v<R1, R2>> { };

23.16.6 SI types for ratio [ratio.si]

For each of the typedef-names yocto, zepto, zetta, and yotta, if both of the constants used in its specification are representable by intmax_­t, the typedef shall be defined; if either of the constants is not representable by intmax_­t, the typedef shall not be defined.

23.17 Time utilities [time]

23.17.1 In general [time.general]

This subclause describes the chrono library ([time.syn]) and various C functions ([ctime.syn]) that provide generally useful time utilities.

23.17.2 Header <chrono> synopsis [time.syn]

namespace std {
  namespace chrono {
    // [time.duration], class template duration
    template <class Rep, class Period = ratio<1>> class duration;

    // [time.point], class template time_­point
    template <class Clock, class Duration = typename Clock::duration> class time_point;
  }

  // [time.traits.specializations], common_­type specializations
  template <class Rep1, class Period1, class Rep2, class Period2>
    struct common_type<chrono::duration<Rep1, Period1>,
                       chrono::duration<Rep2, Period2>>;

  template <class Clock, class Duration1, class Duration2>
    struct common_type<chrono::time_point<Clock, Duration1>,
                       chrono::time_point<Clock, Duration2>>;

  namespace chrono {
    // [time.traits], customization traits
    template <class Rep> struct treat_as_floating_point;
    template <class Rep> struct duration_values;
    template <class Rep> inline constexpr bool treat_as_floating_point_v
      = treat_as_floating_point<Rep>::value;

    // [time.duration.nonmember], duration arithmetic
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      constexpr operator+(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      constexpr operator-(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period, class Rep2>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator*(const duration<Rep1, Period>& d, const Rep2& s);
    template <class Rep1, class Rep2, class Period>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator*(const Rep1& s, const duration<Rep2, Period>& d);
    template <class Rep1, class Period, class Rep2>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator/(const duration<Rep1, Period>& d, const Rep2& s);
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<Rep1, Rep2>
      constexpr operator/(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period, class Rep2>
      duration<common_type_t<Rep1, Rep2>, Period>
      constexpr operator%(const duration<Rep1, Period>& d, const Rep2& s);
    template <class Rep1, class Period1, class Rep2, class Period2>
      common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      constexpr operator%(const duration<Rep1, Period1>& lhs,
                          const duration<Rep2, Period2>& rhs);

    // [time.duration.comparisons], duration comparisons
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator==(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator!=(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator< (const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator> (const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
      constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
                                const duration<Rep2, Period2>& rhs);

    // [time.duration.cast], duration_­cast
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration floor(const duration<Rep, Period>& d);
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration ceil(const duration<Rep, Period>& d);
    template <class ToDuration, class Rep, class Period>
      constexpr ToDuration round(const duration<Rep, Period>& d);

    // convenience typedefs
    using nanoseconds  = duration<signed integer type of at least 64 bits, nano>;
    using microseconds = duration<signed integer type of at least 55 bits, micro>;
    using milliseconds = duration<signed integer type of at least 45 bits, milli>;
    using seconds      = duration<signed integer type of at least 35 bits>;
    using minutes      = duration<signed integer type of at least 29 bits, ratio<  60>>;
    using hours        = duration<signed integer type of at least 23 bits, ratio<3600>>;

    // [time.point.nonmember], time_­point arithmetic
    template <class Clock, class Duration1, class Rep2, class Period2>
      constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
      operator+(const time_point<Clock, Duration1>& lhs,
                const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Clock, class Duration2>
      constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
      operator+(const duration<Rep1, Period1>& lhs,
                const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Rep2, class Period2>
      constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
      operator-(const time_point<Clock, Duration1>& lhs,
                const duration<Rep2, Period2>& rhs);
    template <class Clock, class Duration1, class Duration2>
      constexpr common_type_t<Duration1, Duration2>
      operator-(const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

    // [time.point.comparisons], time_­point comparisons
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator!=(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator< (const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator> (const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
       constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
                                 const time_point<Clock, Duration2>& rhs);

    // [time.point.cast], time_­point_­cast
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      time_point_cast(const time_point<Clock, Duration>& t);
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      floor(const time_point<Clock, Duration>& tp);
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      ceil(const time_point<Clock, Duration>& tp);
    template <class ToDuration, class Clock, class Duration>
      constexpr time_point<Clock, ToDuration>
      round(const time_point<Clock, Duration>& tp);

    // [time.duration.alg], specialized algorithms
    template <class Rep, class Period>
      constexpr duration<Rep, Period> abs(duration<Rep, Period> d);

    // [time.clock], clocks
    class system_clock;
    class steady_clock;
    class high_resolution_clock;
  }

  inline namespace literals {
    inline namespace chrono_literals {
      // [time.duration.literals], suffixes for duration literals
      constexpr chrono::hours                                operator""h(unsigned long long);
      constexpr chrono::duration<unspecified, ratio<3600,1>> operator""h(long double);
      constexpr chrono::minutes                              operator""min(unsigned long long);
      constexpr chrono::duration<unspecified, ratio<60,1>>   operator""min(long double);
      constexpr chrono::seconds                              operator""s(unsigned long long);
      constexpr chrono::duration<unspecified>                operator""s(long double);
      constexpr chrono::milliseconds                         operator""ms(unsigned long long);
      constexpr chrono::duration<unspecified, milli>          operator""ms(long double);
      constexpr chrono::microseconds                         operator""us(unsigned long long);
      constexpr chrono::duration<unspecified, micro>         operator""us(long double);
      constexpr chrono::nanoseconds                          operator""ns(unsigned long long);
      constexpr chrono::duration<unspecified, nano>          operator""ns(long double);
    }
  }

  namespace chrono {
    using namespace literals::chrono_literals;
  }
}

23.17.3 Clock requirements [time.clock.req]

A clock is a bundle consisting of a duration, a time_­point, and a function now() to get the current time_­point.
The origin of the clock's time_­point is referred to as the clock's epoch.
A clock shall meet the requirements in Table 47.
In Table 47 C1 and C2 denote clock types.
t1 and t2 are values returned by C1​::​now() where the call returning t1 happens before ([intro.multithread]) the call returning t2 and both of these calls occur before C1​::​time_­point​::​max().
[Note
:
This means C1 did not wrap around between t1 and t2.
end note
]
Table 47 — Clock requirements
Expression
Return type
Operational semantics
C1​::​rep
An arithmetic type or a class emulating an arithmetic type
The representation type of C1​::​duration.
C1​::​period
a specialization of ratio
The tick period of the clock in seconds.
C1​::​duration
chrono​::​duration<C1​::​rep, C1​::​period>
The duration type of the clock.
C1​::​time_­point
chrono​::​time_­point<C1> or chrono​::​time_­point<C2, C1​::​duration>
The time_­point type of the clock.
C1 and C2 shall refer to the same epoch.
C1​::​is_­steady
const bool
true if t1 <= t2 is always true and the time between clock ticks is constant, otherwise false.
C1​::​now()
C1​::​time_­point
Returns a time_­point object representing the current point in time.
[Note
:
The relative difference in durations between those reported by a given clock and the SI definition is a measure of the quality of implementation.
end note
]
A type TC meets the TrivialClock requirements if:
  • TC satisfies the Clock requirements ([time.clock.req]),
  • the types TC​::​rep, TC​::​duration, and TC​::​time_­point satisfy the requirements of EqualityComparable (Table 20), LessThanComparable (Table 21), DefaultConstructible (Table 22), CopyConstructible (Table 24), CopyAssignable (Table 26), Destructible (Table 27), and the requirements of numeric types ([numeric.requirements]).
    [Note
    :
    This means, in particular, that operations on these types will not throw exceptions.
    end note
    ]
  • lvalues of the types TC​::​rep, TC​::​duration, and TC​::​time_­point are swappable ([swappable.requirements]),
  • the function TC​::​now() does not throw exceptions, and
  • the type TC​::​time_­point​::​clock meets the TrivialClock requirements, recursively.

23.17.4 Time-related traits [time.traits]

23.17.4.1 treat_­as_­floating_­point [time.traits.is_fp]

template <class Rep> struct treat_as_floating_point : is_floating_point<Rep> { };
The duration template uses the treat_­as_­floating_­point trait to help determine if a duration object can be converted to another duration with a different tick period.
If treat_­as_­floating_­point_­v<Rep> is true, then implicit conversions are allowed among durations.
Otherwise, the implicit convertibility depends on the tick periods of the durations.
[Note
:
The intention of this trait is to indicate whether a given class behaves like a floating-point type, and thus allows division of one value by another with acceptable loss of precision.
If treat_­as_­floating_­point_­v<Rep> is false, Rep will be treated as if it behaved like an integral type for the purpose of these conversions.
end note
]

23.17.4.2 duration_­values [time.traits.duration_values]

template <class Rep> struct duration_values { public: static constexpr Rep zero(); static constexpr Rep min(); static constexpr Rep max(); };
The duration template uses the duration_­values trait to construct special values of the durations representation (Rep).
This is done because the representation might be a class type with behavior which requires some other implementation to return these special values.
In that case, the author of that class type should specialize duration_­values to return the indicated values.
static constexpr Rep zero();
Returns: Rep(0).
[Note
:
Rep(0) is specified instead of Rep() because Rep() may have some other meaning, such as an uninitialized value.
end note
]
Remarks: The value returned shall be the additive identity.
static constexpr Rep min();
Returns: numeric_­limits<Rep>​::​lowest().
Remarks: The value returned shall compare less than or equal to zero().
static constexpr Rep max();
Returns: numeric_­limits<Rep>​::​max().
Remarks: The value returned shall compare greater than zero().

23.17.4.3 Specializations of common_­type [time.traits.specializations]

template <class Rep1, class Period1, class Rep2, class Period2> struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> { using type = chrono::duration<common_type_t<Rep1, Rep2>, see below>; };
The period of the duration indicated by this specialization of common_­type shall be the greatest common divisor of Period1 and Period2.
[Note
:
This can be computed by forming a ratio of the greatest common divisor of Period1​::​num and Period2​::​num and the least common multiple of Period1​::​den and Period2​::​den.
end note
]
[Note
:
The typedef name type is a synonym for the duration with the largest tick period possible where both duration arguments will convert to it without requiring a division operation.
The representation of this type is intended to be able to hold any value resulting from this conversion with no truncation error, although floating-point durations may have round-off errors.
end note
]
template <class Clock, class Duration1, class Duration2> struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>> { using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>; };
The common type of two time_­point types is a time_­point with the same clock as the two types and the common type of their two durations.

23.17.5 Class template duration [time.duration]

A duration type measures time between two points in time (time_­points).
A duration has a representation which holds a count of ticks and a tick period.
The tick period is the amount of time which occurs from one tick to the next, in units of seconds.
It is expressed as a rational constant using the template ratio.
template <class Rep, class Period = ratio<1>>
class duration {
public:
  using rep    = Rep;
  using period = typename Period::type;
private:
  rep rep_;  // exposition only
public:
  // [time.duration.cons], construct/copy/destroy
  constexpr duration() = default;
  template <class Rep2>
      constexpr explicit duration(const Rep2& r);
  template <class Rep2, class Period2>
     constexpr duration(const duration<Rep2, Period2>& d);
  ~duration() = default;
  duration(const duration&) = default;
  duration& operator=(const duration&) = default;

  // [time.duration.observer], observer
  constexpr rep count() const;

  // [time.duration.arithmetic], arithmetic
  constexpr common_type_t<duration> operator+() const;
  constexpr common_type_t<duration> operator-() const;
  constexpr duration& operator++();
  constexpr duration  operator++(int);
  constexpr duration& operator--();
  constexpr duration  operator--(int);

  constexpr duration& operator+=(const duration& d);
  constexpr duration& operator-=(const duration& d);

  constexpr duration& operator*=(const rep& rhs);
  constexpr duration& operator/=(const rep& rhs);
  constexpr duration& operator%=(const rep& rhs);
  constexpr duration& operator%=(const duration& rhs);

  // [time.duration.special], special values
  static constexpr duration zero();
  static constexpr duration min();
  static constexpr duration max();
};
Rep shall be an arithmetic type or a class emulating an arithmetic type.
If duration is instantiated with a duration type as the argument for the template parameter Rep, the program is ill-formed.
If Period is not a specialization of ratio, the program is ill-formed.
If Period​::​num is not positive, the program is ill-formed.
Members of duration shall not throw exceptions other than those thrown by the indicated operations on their representations.
The defaulted copy constructor of duration shall be a constexpr function if and only if the required initialization of the member rep_­ for copy and move, respectively, would satisfy the requirements for a constexpr function.
[Example
:
duration<long, ratio<60>> d0;       // holds a count of minutes using a long
duration<long long, milli> d1;      // holds a count of milliseconds using a long long
duration<double, ratio<1, 30>>  d2; // holds a count with a tick period of  of a second
                                    // (30 Hz) using a double
end example
]

23.17.5.1 duration constructors [time.duration.cons]

template <class Rep2> constexpr explicit duration(const Rep2& r);
Remarks: This constructor shall not participate in overload resolution unless Rep2 is implicitly convertible to rep and
  • treat_­as_­floating_­point_­v<rep> is true or
  • treat_­as_­floating_­point_­v<Rep2> is false.
[Example
:
duration<int, milli> d(3);          // OK
duration<int, milli> d(3.5);        // error
end example
]
Effects: Constructs an object of type duration.
Postconditions: count() == static_­cast<rep>(r).
template <class Rep2, class Period2> constexpr duration(const duration<Rep2, Period2>& d);
Remarks: This constructor shall not participate in overload resolution unless no overflow is induced in the conversion and treat_­as_­floating_­point_­v<rep> is true or both ratio_­divide<Period2, period>​::​den is 1 and treat_­as_­floating_­point_­v<Rep2> is false.
[Note
:
This requirement prevents implicit truncation error when converting between integral-based duration types.
Such a construction could easily lead to confusion about the value of the duration.
end note
]
[Example
:
duration<int, milli> ms(3);
duration<int, micro> us = ms;       // OK
duration<int, milli> ms2 = us;      // error
end example
]
Effects: Constructs an object of type duration, constructing rep_­ from
duration_­cast<duration>(d).count().

23.17.5.2 duration observer [time.duration.observer]

constexpr rep count() const;
Returns: rep_­.

23.17.5.3 duration arithmetic [time.duration.arithmetic]

constexpr common_type_t<duration> operator+() const;
Returns: common_­type_­t<duration>(*this).
constexpr common_type_t<duration> operator-() const;
Returns: common_­type_­t<duration>(-rep_­).
constexpr duration& operator++();
Effects: As if by ++rep_­.
Returns: *this.
constexpr duration operator++(int);
Returns: duration(rep_­++).
constexpr duration& operator--();
Effects: As if by --rep_­.
Returns: *this.
constexpr duration operator--(int);
Returns: duration(rep_­--).
constexpr duration& operator+=(const duration& d);
Effects: As if by: rep_­ += d.count();
Returns: *this.
constexpr duration& operator-=(const duration& d);
Effects: As if by: rep_­ -= d.count();
Returns: *this.
constexpr duration& operator*=(const rep& rhs);
Effects: As if by: rep_­ *= rhs;
Returns: *this.
constexpr duration& operator/=(const rep& rhs);
Effects: As if by: rep_­ /= rhs;
Returns: *this.
constexpr duration& operator%=(const rep& rhs);
Effects: As if by: rep_­ %= rhs;
Returns: *this.
constexpr duration& operator%=(const duration& rhs);
Effects: As if by: rep_­ %= rhs.count();
Returns: *this.

23.17.5.4 duration special values [time.duration.special]

static constexpr duration zero();
Returns: duration(duration_­values<rep>​::​zero()).
static constexpr duration min();
Returns: duration(duration_­values<rep>​::​min()).
static constexpr duration max();
Returns: duration(duration_­values<rep>​::​max()).

23.17.5.5 duration non-member arithmetic [time.duration.nonmember]

In the function descriptions that follow, CD represents the return type of the function.
CR(A, B) represents common_­type_­t<A, B>.
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() + CD(rhs).count()).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() - CD(rhs).count()).
template <class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const duration<Rep1, Period>& d, const Rep2& s);
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2).
Returns: CD(CD(d).count() * s).
template <class Rep1, class Rep2, class Period> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator*(const Rep1& s, const duration<Rep2, Period>& d);
Remarks: This operator shall not participate in overload resolution unless Rep1 is implicitly convertible to CR(Rep1, Rep2).
Returns: d * s.
template <class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator/(const duration<Rep1, Period>& d, const Rep2& s);
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2) and Rep2 is not a specialization of duration.
Returns: CD(CD(d).count() / s).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<Rep1, Rep2> operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(lhs).count() / CD(rhs).count().
template <class Rep1, class Period, class Rep2> constexpr duration<common_type_t<Rep1, Rep2>, Period> operator%(const duration<Rep1, Period>& d, const Rep2& s);
Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible to CR(Rep1, Rep2) and Rep2 is not a specialization of duration.
Returns: CD(CD(d).count() % s).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>> operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CD(CD(lhs).count() % CD(rhs).count()).

23.17.5.6 duration comparisons [time.duration.comparisons]

In the function descriptions that follow, CT represents common_­type_­t<A, B>, where A and B are the types of the two arguments to the function.
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs).count() == CT(rhs).count().
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(lhs == rhs).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator<(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs).count() < CT(rhs).count().
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(rhs < lhs).
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: rhs < lhs.
template <class Rep1, class Period1, class Rep2, class Period2> constexpr bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: !(lhs < rhs).

23.17.5.7 duration_­cast [time.duration.cast]

template <class ToDuration, class Rep, class Period> constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: Let CF be ratio_­divide<Period, typename ToDuration​::​period>, and CR be common_­type< typename ToDuration​::​rep, Rep, intmax_­t>​::​type.
  • If CF​::​num == 1 and CF​::​den == 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(d.count()))
  • otherwise, if CF​::​num != 1 and CF​::​den == 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) * static_cast<CR>(CF::num)))
  • otherwise, if CF​::​num == 1 and CF​::​den != 1, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) / static_cast<CR>(CF::den)))
  • otherwise, returns
    ToDuration(static_cast<typename ToDuration::rep>(
      static_cast<CR>(d.count()) * static_cast<CR>(CF::num) / static_cast<CR>(CF::den)))
[Note
:
This function does not use any implicit conversions; all conversions are done with static_­cast.
It avoids multiplications and divisions when it is known at compile time that one or more arguments is 1.
Intermediate computations are carried out in the widest representation and only converted to the destination representation at the final step.
end note
]
template <class ToDuration, class Rep, class Period> constexpr ToDuration floor(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: The greatest result t representable in ToDuration for which t <= d.
template <class ToDuration, class Rep, class Period> constexpr ToDuration ceil(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: The least result t representable in ToDuration for which t >= d.
template <class ToDuration, class Rep, class Period> constexpr ToDuration round(const duration<Rep, Period>& d);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration, and treat_­as_­floating_­point_­v<typename ToDuration​::​rep> is false.
Returns: The value of ToDuration that is closest to d.
If there are two closest values, then return the value t for which t % 2 == 0.

23.17.5.8 Suffixes for duration literals [time.duration.literals]

This section describes literal suffixes for constructing duration literals.
The suffixes h, min, s, ms, us, ns denote duration values of the corresponding types hours, minutes, seconds, milliseconds, microseconds, and nanoseconds respectively if they are applied to integral literals.
If any of these suffixes are applied to a floating-point literal the result is a chrono​::​duration literal with an unspecified floating-point representation.
If any of these suffixes are applied to an integer literal and the resulting chrono​::​duration value cannot be represented in the result type because of overflow, the program is ill-formed.
[Example
:
The following code shows some duration literals.
using namespace std::chrono_literals;
auto constexpr aday=24h;
auto constexpr lesson=45min;
auto constexpr halfanhour=0.5h;
end example
]
constexpr chrono::hours operator""h(unsigned long long hours); constexpr chrono::duration<unspecified, ratio<3600, 1>> operator""h(long double hours);
Returns: A duration literal representing hours hours.
constexpr chrono::minutes operator""min(unsigned long long minutes); constexpr chrono::duration<unspecified, ratio<60, 1>> operator""min(long double minutes);
Returns: A duration literal representing minutes minutes.
constexpr chrono::seconds operator""s(unsigned long long sec); constexpr chrono::duration<unspecified> operator""s(long double sec);
Returns: A duration literal representing sec seconds.
[Note
:
The same suffix s is used for basic_­string but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals.
end note
]
constexpr chrono::milliseconds operator""ms(unsigned long long msec); constexpr chrono::duration<unspecified, milli> operator""ms(long double msec);
Returns: A duration literal representing msec milliseconds.
constexpr chrono::microseconds operator""us(unsigned long long usec); constexpr chrono::duration<unspecified, micro> operator""us(long double usec);
Returns: A duration literal representing usec microseconds.
constexpr chrono::nanoseconds operator""ns(unsigned long long nsec); constexpr chrono::duration<unspecified, nano> operator""ns(long double nsec);
Returns: A duration literal representing nsec nanoseconds.

23.17.5.9 duration algorithms [time.duration.alg]

template <class Rep, class Period> constexpr duration<Rep, Period> abs(duration<Rep, Period> d);
Remarks: This function shall not participate in overload resolution unless numeric_­limits<Rep>​::​is_­signed is true.
Returns: If d >= d.zero(), return d, otherwise return -d.

23.17.6 Class template time_­point [time.point]

template <class Clock, class Duration = typename Clock::duration>
class time_point {
public:
  using clock    = Clock;
  using duration = Duration;
  using rep      = typename duration::rep;
  using period   = typename duration::period;
private:
  duration d_;  // exposition only

public:
  // [time.point.cons], construct
  constexpr time_point();  // has value epoch
  constexpr explicit time_point(const duration& d);  // same as time_­point() + d
  template <class Duration2>
    constexpr time_point(const time_point<clock, Duration2>& t);

  // [time.point.observer], observer
  constexpr duration time_since_epoch() const;

  // [time.point.arithmetic], arithmetic
  constexpr time_point& operator+=(const duration& d);
  constexpr time_point& operator-=(const duration& d);

  // [time.point.special], special values
  static constexpr time_point min();
  static constexpr time_point max();
};
Clock shall meet the Clock requirements ([time.clock.req]).
If Duration is not an instance of duration, the program is ill-formed.

23.17.6.1 time_­point constructors [time.point.cons]

constexpr time_point();
Effects: Constructs an object of type time_­point, initializing d_­ with duration​::​zero().
Such a time_­point object represents the epoch.
constexpr explicit time_point(const duration& d);
Effects: Constructs an object of type time_­point, initializing d_­ with d.
Such a time_­point object represents the epoch + d.
template <class Duration2> constexpr time_point(const time_point<clock, Duration2>& t);
Remarks: This constructor shall not participate in overload resolution unless Duration2 is implicitly convertible to duration.
Effects: Constructs an object of type time_­point, initializing d_­ with t.time_­since_­epoch().

23.17.6.2 time_­point observer [time.point.observer]

constexpr duration time_since_epoch() const;
Returns: d_­.

23.17.6.3 time_­point arithmetic [time.point.arithmetic]

constexpr time_point& operator+=(const duration& d);
Effects: As if by: d_­ += d;
Returns: *this.
constexpr time_point& operator-=(const duration& d);
Effects: As if by: d_­ -= d;
Returns: *this.

23.17.6.4 time_­point special values [time.point.special]

static constexpr time_point min();
Returns: time_­point(duration​::​min()).
static constexpr time_point max();
Returns: time_­point(duration​::​max()).

23.17.6.5 time_­point non-member arithmetic [time.point.nonmember]

template <class Clock, class Duration1, class Rep2, class Period2> constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>> operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs.time_­since_­epoch() + rhs), where CT is the type of the return value.
template <class Rep1, class Period1, class Clock, class Duration2> constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>> operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: rhs + lhs.
template <class Clock, class Duration1, class Rep2, class Period2> constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>> operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
Returns: CT(lhs.time_­since_­epoch() - rhs), where CT is the type of the return value.
template <class Clock, class Duration1, class Duration2> constexpr common_type_t<Duration1, Duration2> operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: lhs.time_­since_­epoch() - rhs.time_­since_­epoch().

23.17.6.6 time_­point comparisons [time.point.comparisons]

template <class Clock, class Duration1, class Duration2> constexpr bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: lhs.time_­since_­epoch() == rhs.time_­since_­epoch().
template <class Clock, class Duration1, class Duration2> constexpr bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: !(lhs == rhs).
template <class Clock, class Duration1, class Duration2> constexpr bool operator<(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: lhs.time_­since_­epoch() < rhs.time_­since_­epoch().
template <class Clock, class Duration1, class Duration2> constexpr bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: !(rhs < lhs).
template <class Clock, class Duration1, class Duration2> constexpr bool operator>(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: rhs < lhs.
template <class Clock, class Duration1, class Duration2> constexpr bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
Returns: !(lhs < rhs).

23.17.6.7 time_­point_­cast [time.point.cast]

template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns:
time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch()))
template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> floor(const time_point<Clock, Duration>& tp);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: time_­point<Clock, ToDuration>(floor<ToDuration>(tp.time_­since_­epoch())).
template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> ceil(const time_point<Clock, Duration>& tp);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration.
Returns: time_­point<Clock, ToDuration>(ceil<ToDuration>(tp.time_­since_­epoch())).
template <class ToDuration, class Clock, class Duration> constexpr time_point<Clock, ToDuration> round(const time_point<Clock, Duration>& tp);
Remarks: This function shall not participate in overload resolution unless ToDuration is a specialization of duration, and treat_­as_­floating_­point_­v<typename ToDuration​::​rep> is false.
Returns: time_­point<Clock, ToDuration>(round<ToDuration>(tp.time_­since_­epoch())).

23.17.7 Clocks [time.clock]

The types defined in this subclause shall satisfy the TrivialClock requirements ([time.clock.req]).

23.17.7.1 Class system_­clock [time.clock.system]

Objects of class system_­clock represent wall clock time from the system-wide realtime clock.
class system_clock {
public:
  using rep        = see below;
  using period     = ratio<unspecified, unspecified>;
  using duration   = chrono::duration<rep, period>;
  using time_point = chrono::time_point<system_clock>;
  static constexpr bool is_steady = unspecified;

  static time_point now() noexcept;

  // Map to C API
  static time_t      to_time_t  (const time_point& t) noexcept;
  static time_point  from_time_t(time_t t) noexcept;
};
using system_clock::rep = unspecified;
Requires: system_­clock​::​duration​::​min() < system_­clock​::​duration​::​zero() shall be true.

[Note
:
This implies that rep is a signed type.
end note
]
static time_t to_time_t(const time_point& t) noexcept;
Returns: A time_­t object that represents the same point in time as t when both values are restricted to the coarser of the precisions of time_­t and time_­point.
It is implementation-defined whether values are rounded or truncated to the required precision.
static time_point from_time_t(time_t t) noexcept;
Returns: A time_­point object that represents the same point in time as t when both values are restricted to the coarser of the precisions of time_­t and time_­point.
It is implementation-defined whether values are rounded or truncated to the required precision.

23.17.7.2 Class steady_­clock [time.clock.steady]

Objects of class steady_­clock represent clocks for which values of time_­point never decrease as physical time advances and for which values of time_­point advance at a steady rate relative to real time.
That is, the clock may not be adjusted.
class steady_clock {
public:
  using rep        = unspecified;
  using period     = ratio<unspecified, unspecified>;
  using duration   = chrono::duration<rep, period>;
  using time_point = chrono::time_point<unspecified, duration>;
  static constexpr bool is_steady = true;

  static time_point now() noexcept;
};

23.17.7.3 Class high_­resolution_­clock [time.clock.hires]

Objects of class high_­resolution_­clock represent clocks with the shortest tick period.
high_­resolution_­clock may be a synonym for system_­clock or steady_­clock.
class high_resolution_clock {
public:
  using rep        = unspecified;
  using period     = ratio<unspecified, unspecified>;
  using duration   = chrono::duration<rep, period>;
  using time_point = chrono::time_point<unspecified, duration>;
  static constexpr bool is_steady = unspecified;

  static time_point now() noexcept;
};

23.17.8 Header <ctime> synopsis [ctime.syn]

#define NULL see [support.types.nullptr]
#define CLOCKS_PER_SEC see below
#define TIME_UTC see below

namespace std {
  using size_t = see [support.types.layout];
  using clock_t = see below;
  using time_t = see below;

  struct timespec;
  struct tm;

  clock_t clock();
  double difftime(time_t time1, time_t time0);
  time_t mktime(struct tm* timeptr);
  time_t time(time_t* timer);
  int timespec_get(timespec* ts, int base);
  char* asctime(const struct tm* timeptr);
  char* ctime(const time_t* timer);
  struct tm* gmtime(const time_t* timer);
  struct tm* localtime(const time_t* timer);
  size_t strftime(char* s, size_t maxsize, const char* format, const struct tm* timeptr);
}
The contents of the header <ctime> are the same as the C standard library header <time.h>.223
The functions asctime, ctime, gmtime, and localtime are not required to avoid data races ([res.on.data.races]).
See also: ISO C 7.
27.
strftime supports the C conversion specifiers C, D, e, F, g, G, h, r, R, t, T, u, V, and z, and the modifiers E and O.

23.18 Class type_­index [type.index]

23.18.1 Header <typeindex> synopsis [type.index.synopsis]

namespace std {
  class type_index;
  template <class T> struct hash;
  template<> struct hash<type_index>;
}

23.18.2 type_­index overview [type.index.overview]

namespace std {
  class type_index {
  public:
    type_index(const type_info& rhs) noexcept;
    bool operator==(const type_index& rhs) const noexcept;
    bool operator!=(const type_index& rhs) const noexcept;
    bool operator< (const type_index& rhs) const noexcept;
    bool operator<= (const type_index& rhs) const noexcept;
    bool operator> (const type_index& rhs) const noexcept;
    bool operator>= (const type_index& rhs) const noexcept;
    size_t hash_code() const noexcept;
    const char* name() const noexcept;
  private:
    const type_info* target;    // exposition only
    // Note that the use of a pointer here, rather than a reference,
    // means that the default copy/move constructor and assignment
    // operators will be provided and work as expected.
  };
}
The class type_­index provides a simple wrapper for type_­info which can be used as an index type in associative containers ([associative]) and in unordered associative containers ([unord]).

23.18.3 type_­index members [type.index.members]

type_index(const type_info& rhs) noexcept;
Effects: Constructs a type_­index object, the equivalent of target = &rhs.
bool operator==(const type_index& rhs) const noexcept;
Returns: *target == *rhs.target.
bool operator!=(const type_index& rhs) const noexcept;
Returns: *target != *rhs.target.
bool operator<(const type_index& rhs) const noexcept;
Returns: target->before(*rhs.target).
bool operator<=(const type_index& rhs) const noexcept;
Returns: !rhs.target->before(*target).
bool operator>(const type_index& rhs) const noexcept;
Returns: rhs.target->before(*target).
bool operator>=(const type_index& rhs) const noexcept;
Returns: !target->before(*rhs.target).
size_t hash_code() const noexcept;
Returns: target->hash_­code().
const char* name() const noexcept;
Returns: target->name().

23.18.4 Hash support [type.index.hash]

template <> struct hash<type_index>;
For an object index of type type_­index, hash<type_­index>()(index) shall evaluate to the same result as index.hash_­code().

23.19 Execution policies [execpol]

23.19.1 In general [execpol.general]

This subclause describes classes that are execution policy types.
An object of an execution policy type indicates the kinds of parallelism allowed in the execution of an algorithm and expresses the consequent requirements on the element access functions.
[Example
:
using namespace std;
vector<int> v = /* ... */;

// standard sequential sort
sort(v.begin(), v.end());

// explicitly sequential sort
sort(execution::seq, v.begin(), v.end());

// permitting parallel execution
sort(execution::par, v.begin(), v.end());

// permitting vectorization as well
sort(execution::par_unseq, v.begin(), v.end());
end example
]
[Note
:
Because different parallel architectures may require idiosyncratic parameters for efficient execution, implementations may provide additional execution policies to those described in this standard as extensions.
end note
]

23.19.2 Header <execution> synopsis [execution.syn]

namespace std {
  // [execpol.type], execution policy type trait
  template<class T> struct is_execution_policy;
  template<class T> inline constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
}

namespace std::execution {
  // [execpol.seq], sequenced execution policy
  class sequenced_policy;

  // [execpol.par], parallel execution policy
  class parallel_policy;

  // [execpol.parunseq], parallel and unsequenced execution policy
  class parallel_unsequenced_policy;

  // [execpol.objects], execution policy objects
  inline constexpr sequenced_policy            seq{ unspecified };
  inline constexpr parallel_policy             par{ unspecified };
  inline constexpr parallel_unsequenced_policy par_unseq{ unspecified };
}

23.19.3 Execution policy type trait [execpol.type]

template<class T> struct is_execution_policy { see below };
is_­execution_­policy can be used to detect execution policies for the purpose of excluding function signatures from otherwise ambiguous overload resolution participation.
is_­execution_­policy<T> shall be a UnaryTypeTrait with a base characteristic of true_­type if T is the type of a standard or implementation-defined execution policy, otherwise false_­type.
[Note
:
This provision reserves the privilege of creating non-standard execution policies to the library implementation.
end note
]
The behavior of a program that adds specializations for is_­execution_­policy is undefined.

23.19.4 Sequenced execution policy [execpol.seq]

class execution::sequenced_policy { unspecified };
The class execution​::​sequenced_­policy is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and require that a parallel algorithm's execution may not be parallelized.
During the execution of a parallel algorithm with the execution​::​sequenced_­policy policy, if the invocation of an element access function exits via an uncaught exception, terminate() shall be called.

23.19.5 Parallel execution policy [execpol.par]

class execution::parallel_policy { unspecified };
The class execution​::​parallel_­policy is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm's execution may be parallelized.
During the execution of a parallel algorithm with the execution​::​parallel_­policy policy, if the invocation of an element access function exits via an uncaught exception, terminate() shall be called.

23.19.6 Parallel and unsequenced execution policy [execpol.parunseq]

class execution::parallel_unsequenced_policy { unspecified };
The class execution​::​parallel_­unsequenced_­policy is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm's execution may be parallelized and vectorized.
During the execution of a parallel algorithm with the execution​::​parallel_­unsequenced_­policy policy, if the invocation of an element access function exits via an uncaught exception, terminate() shall be called.

23.19.7 Execution policy objects [execpol.objects]

inline constexpr execution::sequenced_policy execution::seq{ unspecified }; inline constexpr execution::parallel_policy execution::par{ unspecified }; inline constexpr execution::parallel_unsequenced_policy execution::par_unseq{ unspecified };
The header <execution> declares global objects associated with each type of execution policy.

24 Strings library [strings]

24.1 General [strings.general]

This Clause describes components for manipulating sequences of any non-array POD ([basic.types]) type.
Such types are called char-like types, and objects of char-like types are called char-like objects or simply characters.
The following subclauses describe a character traits class, a string class, and null-terminated sequence utilities, as summarized in Table 48.
Table 48 — Strings library summary
Subclause
Header(s)
Character traits
<string>
String classes
<string>
String view classes
<string_­view>
<cctype>
<cwctype>
Null-terminated sequence utilities
<cstring>
<cwchar>
<cstdlib>
<cuchar>

24.2 Character traits [char.traits]

This subclause defines requirements on classes representing character traits, and defines a class template char_­traits<charT>, along with four specializations, char_­traits<char>, char_­traits<char16_­t>,
char_­traits<char32_­t>, and char_­traits<wchar_­t>, that satisfy those requirements.
Most classes specified in Clauses [string.classes] and [input.output] need a set of related types and functions to complete the definition of their semantics.
These types and functions are provided as a set of member typedef-names and functions in the template parameter traits used by each such template.
This subclause defines the semantics of these members.
To specialize those templates to generate a string or iostream class to handle a particular character container type CharT, that and its related character traits class Traits are passed as a pair of parameters to the string or iostream template as parameters charT and traits.
Traits​::​char_­type shall be the same as CharT.
This subclause specifies a class template, char_­traits<charT>, and four explicit specializations of it, char_­traits<​char>, char_­traits<char16_­t>, char_­traits<char32_­t>, and char_­traits<wchar_­t>, all of which appear in the header <string> and satisfy the requirements below.

24.2.1 Character traits requirements [char.traits.require]

In Table 49, X denotes a Traits class defining types and functions for the character container type CharT; c and d denote values of type CharT; p and q denote values of type const CharT*; s denotes a value of type CharT*; n, i and j denote values of type size_­t; e and f denote values of type X​::​int_­type; pos denotes a value of type X​::​pos_­type; state denotes a value of type X​::​state_­type; and r denotes an lvalue of type CharT.
Operations on Traits shall not throw exceptions.
Table 49 — Character traits requirements
Expression
Return type
Assertion/note
Complexity
pre-/post-condition
X​::​char_­type
charT
(described in [char.traits.typedefs])
compile-time
X​::​int_­type
(described in [char.traits.typedefs])
compile-time
X​::​off_­type
(described in [char.traits.typedefs])
compile-time
X​::​pos_­type
(described in [char.traits.typedefs])
compile-time
X​::​state_­type
(described in [char.traits.typedefs])
compile-time
X​::​eq(c,d)
bool
Returns: whether c is to be treated as equal to d.
constant
X​::​lt(c,d)
bool
Returns: whether c is to be treated as less than d.
constant
X​::​compare(p,q,n)
int
Returns: 0 if for each i in [0,n), X​::​eq(p[i],q[i]) is true; else, a negative value if, for some j in [0,n), X​::​lt(p[j],q[j]) is true and for each i in [0,j) X​::​eq(p[i],q[i]) is true; else a positive value.
linear
X​::​length(p)
size_­t
Returns: the smallest i such that X​::​eq(p[i],charT()) is true.
linear
X​::​find(p,n,c)
const X​::​char_­type*
Returns: the smallest q in [p,p+n) such that X​::​eq(*q,c) is true, zero otherwise.
linear
X​::​move(s,p,n)
X​::​char_­type*
for each i in [0,n), performs X​::​assign(s[i],p[i]).
Copies correctly even where the ranges [p,p+n) and [s,s+n) overlap.

Returns: s.
linear
X​::​copy(s,p,n)
X​::​char_­type*
Requires: p not in [s,s+n).
Returns: s.

for each i in [0,n), performs X​::​assign(s[i],p[i]).
linear
X​::​assign(r,d)
(not used)
assigns r=d.
constant
X​::​assign(s,n,c)
X​::​char_­type*
for each i in [0,n), performs X​::​assign(s[i],c).

Returns: s.
linear
X​::​not_­eof(e)
int_­type
Returns: e if X​::​eq_­int_­type(e,X​::​eof()) is false, otherwise a value f such that X​::​eq_­int_­type(f,X​::​eof()) is false.
constant
X​::​to_­char_­type(e)
X​::​char_­type
Returns: if for some c, X​::​eq_­int_­type(e,X​::​to_­int_­type(c)) is true, c; else some unspecified value.
constant
X​::​to_­int_­type(c)
X​::​int_­type
Returns: some value e, constrained by the definitions of to_­char_­type and eq_­int_­type.
constant
X​::​eq_­int_­type(e,f)
bool
Returns: for all c and d, X​::​eq(c,d) is equal to X​::​eq_­int_­type(X​::​to_­int_­type(c), X​::​to_­int_­type(d)); otherwise, yields true if e and f are both copies of X​::​eof(); otherwise, yields false if one of e and f is a copy of X​::​eof() and the other is not; otherwise the value is unspecified.
constant
X​::​eof()
X​::​int_­type
Returns: a value e such that X​::​eq_­int_­type(e,X​::​to_­int_­type(c)) is false for all values c.
constant
The class template
template<class charT> struct char_traits;
shall be provided in the header <string> as a basis for explicit specializations.

24.2.2 Traits typedefs [char.traits.typedefs]

using char_type = CHAR_T;
The type char_­type is used to refer to the character container type in the implementation of the library classes defined in [string.classes] and Clause [input.output].
using int_type = INT_T;
Requires: For a certain character container type char_­type, a related container type INT_­T shall be a type or class which can represent all of the valid characters converted from the corresponding char_­type values, as well as an end-of-file value, eof().
The type int_­type represents a character container type which can hold end-of-file to be used as a return type of the iostream class member functions.224
using off_type = implementation-defined; using pos_type = implementation-defined;
Requires: Requirements for off_­type and pos_­type are described in [iostreams.limits.pos] and [iostream.forward].
using state_type = STATE_T;
Requires: state_­type shall meet the requirements of CopyAssignable (Table 26), CopyConstructible (Table 24), and DefaultConstructible (Table 22) types.
If eof() can be held in char_­type then some iostreams operations may give surprising results.

24.2.3 char_­traits specializations [char.traits.specializations]

namespace std {
  template<> struct char_traits<char>;
  template<> struct char_traits<char16_t>;
  template<> struct char_traits<char32_t>;
  template<> struct char_traits<wchar_t>;
}
The header <string> shall define four specializations of the class template char_­traits: char_­traits<​char>, char_­traits<char16_­t>, char_­traits<char32_­t>, and char_­traits<wchar_­t>.
The requirements for the members of these specializations are given in Clause [char.traits.require].

24.2.3.1 struct char_­traits<char> [char.traits.specializations.char]

namespace std {
  template<> struct char_traits<char> {
    using char_type  = char;
    using int_type   = int;
    using off_type   = streamoff;
    using pos_type   = streampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}
The defined types for int_­type, pos_­type, off_­type, and state_­type shall be int, streampos, streamoff, and mbstate_­t respectively.
The type streampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].
The type streamoff shall be an implementation-defined type that satisfies the requirements for off_­type in [iostreams.limits.pos] and [iostream.forward].
The type mbstate_­t is defined in <cwchar> and can represent any of the conversion states that can occur in an implementation-defined set of supported multibyte character encoding rules.
The two-argument member assign shall be defined identically to the built-in operator =.
The two-argument members eq and lt shall be defined identically to the built-in operators == and < for type unsigned char.
The member eof() shall return EOF.

24.2.3.2 struct char_­traits<char16_­t> [char.traits.specializations.char16_t]

namespace std {
  template<> struct char_traits<char16_t> {
    using char_type  = char16_t;
    using int_type   = uint_least16_t;
    using off_type   = streamoff;
    using pos_type   = u16streampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}
The type u16streampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].
The two-argument members assign, eq, and lt shall be defined identically to the built-in operators =, ==, and < respectively.
The member eof() shall return an implementation-defined constant that cannot appear as a valid UTF-16 code unit.

24.2.3.3 struct char_­traits<char32_­t> [char.traits.specializations.char32_t]

namespace std {
  template<> struct char_traits<char32_t> {
    using char_type  = char32_t;
    using int_type   = uint_least32_t;
    using off_type   = streamoff;
    using pos_type   = u32streampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}
The type u32streampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].
The two-argument members assign, eq, and lt shall be defined identically to the built-in operators =, ==, and < respectively.
The member eof() shall return an implementation-defined constant that cannot appear as a Unicode code point.

24.2.3.4 struct char_­traits<wchar_­t> [char.traits.specializations.wchar.t]

namespace std {
  template<> struct char_traits<wchar_t> {
    using char_type  = wchar_t;
    using int_type   = wint_t;
    using off_type   = streamoff;
    using pos_type   = wstreampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}
The defined types for int_­type, pos_­type, and state_­type shall be wint_­t, wstreampos, and mbstate_­t respectively.
The type wstreampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].
The type mbstate_­t is defined in <cwchar> and can represent any of the conversion states that can occur in an implementation-defined set of supported multibyte character encoding rules.
The two-argument members assign, eq, and lt shall be defined identically to the built-in operators =, ==, and < respectively.
The member eof() shall return WEOF.

24.3 String classes [string.classes]

The header <string> defines the basic_­string class template for manipulating varying-length sequences of char-like objects and four typedef-names, string, u16string, u32string, and wstring, that name the specializations basic_­string<char>, basic_­string<char16_­t>, basic_­string<char32_­t>, and basic_­string<​wchar_­t>, respectively.

24.3.1 Header <string> synopsis [string.syn]

#include <initializer_list>

namespace std {
  // [char.traits], character traits
  template<class charT> struct char_traits;
  template<> struct char_traits<char>;
  template<> struct char_traits<char16_t>;
  template<> struct char_traits<char32_t>;
  template<> struct char_traits<wchar_t>;

  // [basic.string], basic_­string
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT>>
      class basic_string;

  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs,
                const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs,
                const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs,
                basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs,
                basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const charT* lhs,
                const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const charT* lhs,
                basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(charT lhs, const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(charT lhs, basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs,
                const charT* rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs,
                const charT* rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs, charT rhs);

  template<class charT, class traits, class Allocator>
    bool operator==(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator==(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator==(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator!=(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator!=(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator!=(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);

  template<class charT, class traits, class Allocator>
    bool operator< (const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator< (const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator< (const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator> (const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator> (const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator> (const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);

  template<class charT, class traits, class Allocator>
    bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator<=(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator>=(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);

  // [string.special], swap
  template<class charT, class traits, class Allocator>
    void swap(basic_string<charT, traits, Allocator>& lhs,
              basic_string<charT, traits, Allocator>& rhs)
      noexcept(noexcept(lhs.swap(rhs)));

  // [string.io], inserters and extractors
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      operator>>(basic_istream<charT, traits>& is,
                 basic_string<charT, traits, Allocator>& str);
  template<class charT, class traits, class Allocator>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os,
                 const basic_string<charT, traits, Allocator>& str);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>& is,
              basic_string<charT, traits, Allocator>& str,
              charT delim);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>&& is,
              basic_string<charT, traits, Allocator>& str,
              charT delim);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>& is,
              basic_string<charT, traits, Allocator>& str);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>&& is,
              basic_string<charT, traits, Allocator>& str);

  // basic_­string typedef names
  using string    = basic_string<char>;
  using u16string = basic_string<char16_t>;
  using u32string = basic_string<char32_t>;
  using wstring   = basic_string<wchar_t>;

  // [string.conversions], numeric conversions
  int stoi(const string& str, size_t* idx = 0, int base = 10);
  long stol(const string& str, size_t* idx = 0, int base = 10);
  unsigned long stoul(const string& str, size_t* idx = 0, int base = 10);
  long long stoll(const string& str, size_t* idx = 0, int base = 10);
  unsigned long long stoull(const string& str, size_t* idx = 0, int base = 10);
  float stof(const string& str, size_t* idx = 0);
  double stod(const string& str, size_t* idx = 0);
  long double stold(const string& str, size_t* idx = 0);
  string to_string(int val);
  string to_string(unsigned val);
  string to_string(long val);
  string to_string(unsigned long val);
  string to_string(long long val);
  string to_string(unsigned long long val);
  string to_string(float val);
  string to_string(double val);
  string to_string(long double val);

  int stoi(const wstring& str, size_t* idx = 0, int base = 10);
  long stol(const wstring& str, size_t* idx = 0, int base = 10);
  unsigned long stoul(const wstring& str, size_t* idx = 0, int base = 10);
  long long stoll(const wstring& str, size_t* idx = 0, int base = 10);
  unsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10);
  float stof(const wstring& str, size_t* idx = 0);
  double stod(const wstring& str, size_t* idx = 0);
  long double stold(const wstring& str, size_t* idx = 0);
  wstring to_wstring(int val);
  wstring to_wstring(unsigned val);
  wstring to_wstring(long val);
  wstring to_wstring(unsigned long val);
  wstring to_wstring(long long val);
  wstring to_wstring(unsigned long long val);
  wstring to_wstring(float val);
  wstring to_wstring(double val);
  wstring to_wstring(long double val);

  // [basic.string.hash], hash support
  template<class T> struct hash;
  template<> struct hash<string>;
  template<> struct hash<u16string>;
  template<> struct hash<u32string>;
  template<> struct hash<wstring>;

  namespace pmr {
    template <class charT, class traits = char_traits<charT>>
      using basic_string =
        std::basic_string<charT, traits, polymorphic_allocator<charT>>;

    using string    = basic_string<char>;
    using u16string = basic_string<char16_t>;
    using u32string = basic_string<char32_t>;
    using wstring   = basic_string<wchar_t>;
  }

  inline namespace literals {
  inline namespace string_literals {
    // [basic.string.literals], suffix for basic_­string literals
    string    operator""s(const char* str, size_t len);
    u16string operator""s(const char16_t* str, size_t len);
    u32string operator""s(const char32_t* str, size_t len);
    wstring   operator""s(const wchar_t* str, size_t len);
  }
  }
}

24.3.2 Class template basic_­string [basic.string]

The class template basic_­string describes objects that can store a sequence consisting of a varying number of arbitrary char-like objects with the first element of the sequence at position zero.
Such a sequence is also called a “string” if the type of the char-like objects that it holds is clear from context.
In the rest of this Clause, the type of the char-like objects held in a basic_­string object is designated by charT.
The member functions of basic_­string use an object of the Allocator class passed as a template parameter to allocate and free storage for the contained char-like objects.225
A basic_­string is a contiguous container ([container.requirements.general]).
In all cases, size() <= capacity().
The functions described in this Clause can report two kinds of errors, each associated with an exception type:
namespace std {
  template<class charT, class traits = char_traits<charT>,
           class Allocator = allocator<charT>>
  class basic_string {
  public:
    // types:
    using traits_type            = traits;
    using value_type             = charT;
    using allocator_type         = Allocator;
    using size_type              = typename allocator_traits<Allocator>::size_type;
    using difference_type        = typename allocator_traits<Allocator>::difference_type;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;

    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    static const size_type npos  = -1;

    // [string.cons], construct/copy/destroy
    basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
    explicit basic_string(const Allocator& a) noexcept;
    basic_string(const basic_string& str);
    basic_string(basic_string&& str) noexcept;
    basic_string(const basic_string& str, size_type pos,
                 const Allocator& a = Allocator());
    basic_string(const basic_string& str, size_type pos, size_type n,
                 const Allocator& a = Allocator());
    template<class T>
      basic_string(const T& t, size_type pos, size_type n,
                   const Allocator& a = Allocator());
    explicit basic_string(basic_string_view<charT, traits> sv,
                          const Allocator& a = Allocator());
    basic_string(const charT* s,
                 size_type n, const Allocator& a = Allocator());
    basic_string(const charT* s, const Allocator& a = Allocator());
    basic_string(size_type n, charT c, const Allocator& a = Allocator());
    template<class InputIterator>
      basic_string(InputIterator begin, InputIterator end,
                   const Allocator& a = Allocator());
    basic_string(initializer_list<charT>, const Allocator& = Allocator());
    basic_string(const basic_string&, const Allocator&);
    basic_string(basic_string&&, const Allocator&);

    ~basic_string();
    basic_string& operator=(const basic_string& str);
    basic_string& operator=(basic_string&& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    basic_string& operator=(basic_string_view<charT, traits> sv);
    basic_string& operator=(const charT* s);
    basic_string& operator=(charT c);
    basic_string& operator=(initializer_list<charT>);

    // [string.iterators], iterators
    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [string.capacity], capacity
    size_type size() const noexcept;
    size_type length() const noexcept;
    size_type max_size() const noexcept;
    void resize(size_type n, charT c);
    void resize(size_type n);
    size_type capacity() const noexcept;
    void reserve(size_type res_arg = 0);
    void shrink_to_fit();
    void clear() noexcept;
    bool empty() const noexcept;

    // [string.access], element access
    const_reference operator[](size_type pos) const;
    reference       operator[](size_type pos);
    const_reference at(size_type n) const;
    reference       at(size_type n);

    const charT& front() const;
    charT&       front();
    const charT& back() const;
    charT&       back();

    // [string.modifiers], modifiers
    basic_string& operator+=(const basic_string& str);
    basic_string& operator+=(basic_string_view<charT, traits> sv);
    basic_string& operator+=(const charT* s);
    basic_string& operator+=(charT c);
    basic_string& operator+=(initializer_list<charT>);
    basic_string& append(const basic_string& str);
    basic_string& append(const basic_string& str, size_type pos,
                         size_type n = npos);
    basic_string& append(basic_string_view<charT, traits> sv);
    template<class T>
      basic_string& append(const T& t, size_type pos, size_type n = npos);
    basic_string& append(const charT* s, size_type n);
    basic_string& append(const charT* s);
    basic_string& append(size_type n, charT c);
    template<class InputIterator>
      basic_string& append(InputIterator first, InputIterator last);
    basic_string& append(initializer_list<charT>);
    void push_back(charT c);

    basic_string& assign(const basic_string& str);
    basic_string& assign(basic_string&& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    basic_string& assign(const basic_string& str, size_type pos,
                         size_type n = npos);
    basic_string& assign(basic_string_view<charT, traits> sv);
    template<class T>
      basic_string& assign(const T& t, size_type pos, size_type n = npos);
    basic_string& assign(const charT* s, size_type n);
    basic_string& assign(const charT* s);
    basic_string& assign(size_type n, charT c);
    template<class InputIterator>
      basic_string& assign(InputIterator first, InputIterator last);
    basic_string& assign(initializer_list<charT>);

    basic_string& insert(size_type pos, const basic_string& str);
    basic_string& insert(size_type pos1, const basic_string& str,
                         size_type pos2, size_type n = npos);
    basic_string& insert(size_type pos, basic_string_view<charT, traits> sv);
    template<class T>
      basic_string& insert(size_type pos1, const T& t,
                           size_type pos2, size_type n = npos);
    basic_string& insert(size_type pos, const charT* s, size_type n);
    basic_string& insert(size_type pos, const charT* s);
    basic_string& insert(size_type pos, size_type n, charT c);
    iterator insert(const_iterator p, charT c);
    iterator insert(const_iterator p, size_type n, charT c);
    template<class InputIterator>
      iterator insert(const_iterator p, InputIterator first, InputIterator last);
    iterator insert(const_iterator p, initializer_list<charT>);

    basic_string& erase(size_type pos = 0, size_type n = npos);
    iterator erase(const_iterator p);
    iterator erase(const_iterator first, const_iterator last);

    void pop_back();

    basic_string& replace(size_type pos1, size_type n1,
                          const basic_string& str);
    basic_string& replace(size_type pos1, size_type n1,
                          const basic_string& str,
                          size_type pos2, size_type n2 = npos);
    basic_string& replace(size_type pos1, size_type n1,
                          basic_string_view<charT, traits> sv);
    template<class T>
      basic_string& replace(size_type pos1, size_type n1, const T& t,
                            size_type pos2, size_type n2 = npos);
    basic_string& replace(size_type pos, size_type n1, const charT* s,
                          size_type n2);
    basic_string& replace(size_type pos, size_type n1, const charT* s);
    basic_string& replace(size_type pos, size_type n1, size_type n2,
                          charT c);

    basic_string& replace(const_iterator i1, const_iterator i2,
                          const basic_string& str);
    basic_string& replace(const_iterator i1, const_iterator i2,
                          basic_string_view<charT, traits> sv);
    basic_string& replace(const_iterator i1, const_iterator i2, const charT* s,
                          size_type n);
    basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
    basic_string& replace(const_iterator i1, const_iterator i2,
                          size_type n, charT c);
    template<class InputIterator>
      basic_string& replace(const_iterator i1, const_iterator i2,
                            InputIterator j1, InputIterator j2);
    basic_string& replace(const_iterator, const_iterator, initializer_list<charT>);

    size_type copy(charT* s, size_type n, size_type pos = 0) const;
    void swap(basic_string& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
               allocator_traits<Allocator>::is_always_equal::value);

    // [string.ops], string operations
    const charT* c_str() const noexcept;
    const charT* data() const noexcept;
    charT* data() noexcept;
    operator basic_string_view<charT, traits>() const noexcept;
    allocator_type get_allocator() const noexcept;

    size_type find (basic_string_view<charT, traits> sv,
                    size_type pos = 0) const noexcept;
    size_type find (const basic_string& str, size_type pos = 0) const noexcept;
    size_type find (const charT* s, size_type pos, size_type n) const;
    size_type find (const charT* s, size_type pos = 0) const;
    size_type find (charT c, size_type pos = 0) const;
    size_type rfind(basic_string_view<charT, traits> sv,
                    size_type pos = npos) const noexcept;
    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
    size_type rfind(const charT* s, size_type pos, size_type n) const;
    size_type rfind(const charT* s, size_type pos = npos) const;
    size_type rfind(charT c, size_type pos = npos) const;

    size_type find_first_of(basic_string_view<charT, traits> sv,
                            size_type pos = 0) const noexcept;
    size_type find_first_of(const basic_string& str,
                            size_type pos = 0) const noexcept;
    size_type find_first_of(const charT* s,
                            size_type pos, size_type n) const;
    size_type find_first_of(const charT* s, size_type pos = 0) const;
    size_type find_first_of(charT c, size_type pos = 0) const;
    size_type find_last_of (basic_string_view<charT, traits> sv,
                            size_type pos = npos) const noexcept;
    size_type find_last_of (const basic_string& str,
                            size_type pos = npos) const noexcept;
    size_type find_last_of (const charT* s,
                            size_type pos, size_type n) const;
    size_type find_last_of (const charT* s, size_type pos = npos) const;
    size_type find_last_of (charT c, size_type pos = npos) const;

    size_type find_first_not_of(basic_string_view<charT, traits> sv,
                                size_type pos = 0) const noexcept;
    size_type find_first_not_of(const basic_string& str,
                                size_type pos = 0) const noexcept;
    size_type find_first_not_of(const charT* s, size_type pos,
                                size_type n) const;
    size_type find_first_not_of(const charT* s, size_type pos = 0) const;
    size_type find_first_not_of(charT c, size_type pos = 0) const;
    size_type find_last_not_of (basic_string_view<charT, traits> sv,
                                size_type pos = npos) const noexcept;
    size_type find_last_not_of (const basic_string& str,
                                size_type pos = npos) const noexcept;
    size_type find_last_not_of (const charT* s, size_type pos,
                                size_type n) const;
    size_type find_last_not_of (const charT* s,
                                size_type pos = npos) const;
    size_type find_last_not_of (charT c, size_type pos = npos) const;

    basic_string substr(size_type pos = 0, size_type n = npos) const;
    int compare(basic_string_view<charT, traits> sv) const noexcept;
    int compare(size_type pos1, size_type n1,
                basic_string_view<charT, traits> sv) const;
    template<class T>
      int compare(size_type pos1, size_type n1, const T& t,
                  size_type pos2, size_type n2 = npos) const;
    int compare(const basic_string& str) const noexcept;
    int compare(size_type pos1, size_type n1,
                const basic_string& str) const;
    int compare(size_type pos1, size_type n1,
                const basic_string& str,
                size_type pos2, size_type n2 = npos) const;
    int compare(const charT* s) const;
    int compare(size_type pos1, size_type n1,
                const charT* s) const;
    int compare(size_type pos1, size_type n1,
                const charT* s, size_type n2) const;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    basic_string(InputIterator, InputIterator, Allocator = Allocator())
      -> basic_string<typename iterator_traits<InputIterator>::value_type,
                      char_traits<typename iterator_traits<InputIterator>::value_type>,
                      Allocator>;
}
Allocator​::​value_­type must name the same type as charT ([string.require]).

24.3.2.1 basic_­string general requirements [string.require]

If any operation would cause size() to exceed max_­size(), that operation shall throw an exception object of type length_­error.
If any member function or operator of basic_­string throws an exception, that function or operator shall have no other effect.
In every specialization basic_­string<charT, traits, Allocator>, the type allocator_­traits<Allocator>​::​value_­type shall name the same type as charT.
Every object of type basic_­string<charT, traits, Allocator> shall use an object of type Allocator to allocate and free storage for the contained charT objects as needed.
The Allocator object used shall be obtained as described in [container.requirements.general].
In every specialization basic_­string<charT, traits, Allocator>, the type traits shall satisfy the character traits requirements ([char.traits]), and the type traits​::​char_­type shall name the same type as charT.
References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:
  • as an argument to any standard library function taking a reference to non-const basic_­string as an argument.226
  • Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
For example, as an argument to non-member functions swap() ([string.special]), operator>>() ([string.io]), and getline() ([string.io]), or as an argument to basic_­string​::​swap().

24.3.2.2 basic_­string constructors and assignment operators [string.cons]

explicit basic_string(const Allocator& a) noexcept;
Effects: Constructs an object of class basic_­string.
The postconditions of this function are indicated in Table 50.
Table 50basic_­string(const Allocator&) effects
Element
Value
data()
a non-null pointer that is copyable and can have 0 added to it
size()
0
capacity()
an unspecified value
basic_string(const basic_string& str); basic_string(basic_string&& str) noexcept;
Effects: Constructs an object of class basic_­string as indicated in Table 51.
In the second form, str is left in a valid state with an unspecified value.
Table 51basic_­string(const basic_­string&) effects
Element
Value
data()
points at the first element of an allocated copy of the array whose first element is pointed at by str.data()
size()
str.size()
capacity()
a value at least as large as size()
basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator());
Throws: out_­of_­range if pos > str.size().
Effects: Constructs an object of class basic_­string and determines the effective length rlen of the initial string value as str.size() - pos, as indicated in Table 52.
basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator());
Throws: out_­of_­range if pos > str.size().
Effects: Constructs an object of class basic_­string and determines the effective length rlen of the initial string value as the smaller of n and str.size() - pos, as indicated in Table 52.
Table 52basic_­string(const basic_­string&, size_­type, const Allocator&) and
basic_­string(const basic_­string&, size_­type, size_­type, const Allocator&) effects
Element
Value
data()
points at the first element of an allocated copy of rlen consecutive elements of the string controlled by str beginning at position pos
size()
rlen
capacity()
a value at least as large as size()
template<class T> basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t; and then behaves the same as:
basic_string(sv.substr(pos, n), a);
Remarks: This constructor shall not participate in overload resolution unless is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true.
explicit basic_string(basic_string_view<charT, traits> sv, const Allocator& a = Allocator());
Effects: Same as basic_­string(sv.data(), sv.size(), a).
basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
Requires: s points to an array of at least n elements of charT.
Effects: Constructs an object of class basic_­string and determines its initial string value from the array of charT of length n whose first element is designated by s, as indicated in Table 53.
Table 53basic_­string(const charT*, size_­type, const Allocator&) effects
Element
Value
data()
points at the first element of an allocated copy of the array whose first element is pointed at by s
size()
n
capacity()
a value at least as large as size()
basic_string(const charT* s, const Allocator& a = Allocator());
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Effects: Constructs an object of class basic_­string and determines its initial string value from the array of charT of length traits​::​length(s) whose first element is designated by s, as indicated in Table 54.
Table 54basic_­string(const charT*, const Allocator&) effects
Element
Value
data()
points at the first element of an allocated copy of the array whose first element is pointed at by s
size()
traits​::​length(s)
capacity()
a value at least as large as size()
basic_string(size_type n, charT c, const Allocator& a = Allocator());
Requires: n < npos.
Effects: Constructs an object of class basic_­string and determines its initial string value by repeating the char-like object c for all n elements, as indicated in Table 55.
Table 55basic_­string(size_­t, charT, const Allocator&) effects
Element
Value
data()
points at the first element of an allocated array of n elements, each storing the initial value c
size()
n
capacity()
a value at least as large as size()
template<class InputIterator> basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
Effects: If InputIterator is an integral type, equivalent to:
basic_string(static_cast<size_type>(begin), static_cast<value_type>(end), a);
Otherwise constructs a string from the values in the range [begin, end), as indicated in the Sequence Requirements table (see [sequence.reqmts]).
basic_string(initializer_list<charT> il, const Allocator& a = Allocator());
Effects: Same as basic_­string(il.begin(), il.end(), a).
basic_string(const basic_string& str, const Allocator& alloc); basic_string(basic_string&& str, const Allocator& alloc);
Effects: Constructs an object of class basic_­string as indicated in Table 56.
The stored allocator is constructed from alloc.
In the second form, str is left in a valid state with an unspecified value.
Table 56basic_­string(const basic_­string&, const Allocator&)
and basic_­string(basic_­string&&, const Allocator&) effects
Element
Value
data()
points at the first element of an allocated copy of the array whose first element is pointed at by the original value of str.data().
size()
the original value of str.size()
capacity()
a value at least as large as size()
get_­allocator()
alloc
Throws: The second form throws nothing if alloc == str.get_­allocator().
template<class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> basic_string(InputIterator, InputIterator, Allocator = Allocator()) -> basic_string<typename iterator_traits<InputIterator>::value_type, char_traits<typename iterator_traits<InputIterator>::value_type>, Allocator>;
Remarks: Shall not participate in overload resolution if InputIterator is a type that does not qualify as an input iterator, or if Allocator is a type that does not qualify as an allocator ([container.requirements.general]).
basic_string& operator=(const basic_string& str);
Effects: If *this and str are not the same object, modifies *this as shown in Table 57.
If *this and str are the same object, the member has no effect.
Returns: *this.
Table 57operator=(const basic_­string&) effects
Element
Value
data()
points at the first element of an allocated copy of the array whose first element is pointed at by str.data()
size()
str.size()
capacity()
a value at least as large as size()
basic_string& operator=(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Move assigns as a sequence container ([container.requirements]), except that iterators, pointers and references may be invalidated.
Returns: *this.
basic_string& operator=(basic_string_view<charT, traits> sv);
Effects: Equivalent to: return assign(sv);
basic_string& operator=(const charT* s);
Returns: *this = basic_­string(s).
Remarks: Uses traits​::​length().
basic_string& operator=(charT c);
Returns: *this = basic_­string(1, c).
basic_string& operator=(initializer_list<charT> il);
Effects: As if by: *this = basic_­string(il);
Returns: *this.

24.3.2.3 basic_­string iterator support [string.iterators]

iterator begin() noexcept; const_iterator begin() const noexcept; const_iterator cbegin() const noexcept;
Returns: An iterator referring to the first character in the string.
iterator end() noexcept; const_iterator end() const noexcept; const_iterator cend() const noexcept;
Returns: An iterator which is the past-the-end value.
reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator crbegin() const noexcept;
Returns: An iterator which is semantically equivalent to reverse_­iterator(end()).
reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crend() const noexcept;
Returns: An iterator which is semantically equivalent to reverse_­iterator(begin()).

24.3.2.4 basic_­string capacity [string.capacity]

size_type size() const noexcept;
Returns: A count of the number of char-like objects currently in the string.
Complexity: Constant time.
size_type length() const noexcept;
Returns: size().
size_type max_size() const noexcept;
Returns: The largest possible number of char-like objects that can be stored in a basic_­string.
Complexity: Constant time.
void resize(size_type n, charT c);
Throws: length_­error if n > max_­size().
Effects: Alters the length of the string designated by *this as follows:
  • If n <= size(), the function replaces the string designated by *this with a string of length n whose elements are a copy of the initial elements of the original string designated by *this.
  • If n > size(), the function replaces the string designated by *this with a string of length n whose first size() elements are a copy of the original string designated by *this, and whose remaining elements are all initialized to c.
void resize(size_type n);
Effects: As if by resize(n, charT()).
size_type capacity() const noexcept;
Returns: The size of the allocated storage in the string.
void reserve(size_type res_arg=0);
The member function reserve() is a directive that informs a basic_­string object of a planned change in size, so that it can manage the storage allocation accordingly.
Effects: After reserve(), capacity() is greater or equal to the argument of reserve.
[Note
:
Calling reserve() with a res_­arg argument less than capacity() is in effect a non-binding shrink request.
A call with res_­arg <= size() is in effect a non-binding shrink-to-fit request.
end note
]
Throws: length_­error if res_­arg > max_­size().227
void shrink_to_fit();
Effects: shrink_­to_­fit is a non-binding request to reduce capacity() to size().
[Note
:
The request is non-binding to allow latitude for implementation-specific optimizations.
end note
]
It does not increase capacity(), but may reduce capacity() by causing reallocation.
Complexity: Linear in the size of the sequence.
Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence as well as the past-the-end iterator.
If no reallocation happens, they remain valid.
void clear() noexcept;
Effects: Behaves as if the function calls:
erase(begin(), end());
bool empty() const noexcept;
Returns: size() == 0.
reserve() uses allocator_­traits<Allocator>​::​allocate() which may throw an appropriate exception.

24.3.2.5 basic_­string element access [string.access]

const_reference operator[](size_type pos) const; reference operator[](size_type pos);
Requires: pos <= size().
Returns: *(begin() + pos) if pos < size().
Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object to any value other than charT() leads to undefined behavior.
Throws: Nothing.
Complexity: Constant time.
const_reference at(size_type pos) const; reference at(size_type pos);
Throws: out_­of_­range if pos >= size().
Returns: operator[](pos).
const charT& front() const; charT& front();
Requires: !empty().
Effects: Equivalent to: return operator[](0);
const charT& back() const; charT& back();
Requires: !empty().
Effects: Equivalent to: return operator[](size() - 1);

24.3.2.6 basic_­string modifiers [string.modifiers]

24.3.2.6.1 basic_­string​::​operator+= [string.op+=]

basic_string& operator+=(const basic_string& str);
Effects: Calls append(str).
Returns: *this.
basic_string& operator+=(basic_string_view<charT, traits> sv);
Effects: Calls append(sv).
Returns: *this.
basic_string& operator+=(const charT* s);
Effects: Calls append(s).
Returns: *this.
basic_string& operator+=(charT c);
Effects: Calls push_­back(c);
Returns: *this.
basic_string& operator+=(initializer_list<charT> il);
Effects: Calls append(il).
Returns: *this.

24.3.2.6.2 basic_­string​::​append [string.append]

basic_string& append(const basic_string& str);
Effects: Calls append(str.data(), str.size()).
Returns: *this.
basic_string& append(const basic_string& str, size_type pos, size_type n = npos);
Throws: out_­of_­range if pos > str.size().
Effects: Determines the effective length rlen of the string to append as the smaller of n and str.size() - pos and calls append(str.data() + pos, rlen).
Returns: *this.
basic_string& append(basic_string_view<charT, traits> sv);
Effects: Equivalent to: return append(sv.data(), sv.size());
template<class T> basic_string& append(const T& t, size_type pos, size_type n = npos);
Throws: out_­of_­range if pos > sv.size().
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t.
Determines the effective length rlen of the string to append as the smaller of n and sv.size() - pos and calls append(sv.data() + pos, rlen).
Remarks: This function shall not participate in overload resolution unless is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and is_­convertible_­v<const T&, const charT*> is false.
Returns: *this.
basic_string& append(const charT* s, size_type n);
Requires: s points to an array of at least n elements of charT.
Throws: length_­error if size() + n > max_­size().
Effects: The function replaces the string controlled by *this with a string of length size() + n whose first size() elements are a copy of the original string controlled by *this and whose remaining elements are a copy of the initial n elements of s.
Returns: *this.
basic_string& append(const charT* s);
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Effects: Calls append(s, traits​::​length(s)).
Returns: *this.
basic_string& append(size_type n, charT c);
Effects: Equivalent to append(basic_­string(n, c)).
Returns: *this.
template<class InputIterator> basic_string& append(InputIterator first, InputIterator last);
Requires:[first, last) is a valid range.
Effects: Equivalent to append(basic_­string(first, last, get_­allocator())).
Returns: *this.
basic_string& append(initializer_list<charT> il);
Effects: Calls append(il.begin(), il.size()).
Returns: *this.
void push_back(charT c);
Effects: Equivalent to append(static_­cast<size_­type>(1), c).

24.3.2.6.3 basic_­string​::​assign [string.assign]

basic_string& assign(const basic_string& str);
Effects: Equivalent to *this = str.
Returns: *this.
basic_string& assign(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Equivalent to *this = std​::​move(str).
Returns: *this.
basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
Throws: out_­of_­range if pos > str.size().
Effects: Determines the effective length rlen of the string to assign as the smaller of n and str.size() - pos and calls assign(str.data() + pos, rlen).
Returns: *this.
basic_string& assign(basic_string_view<charT, traits> sv);
Effects: Equivalent to: return assign(sv.data(), sv.size());
template<class T> basic_string& assign(const T& t, size_type pos, size_type n = npos);
Throws: out_­of_­range if pos > sv.size().
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t.
Determines the effective length rlen of the string to assign as the smaller of n and sv.size() - pos and calls assign(sv.data() + pos, rlen).
Remarks: This function shall not participate in overload resolution unless is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and is_­convertible_­v<const T&, const charT*> is false.
Returns: *this.
basic_string& assign(const charT* s, size_type n);
Requires: s points to an array of at least n elements of charT.
Throws: length_­error if n > max_­size().
Effects: Replaces the string controlled by *this with a string of length n whose elements are a copy of those pointed to by s.
Returns: *this.
basic_string& assign(const charT* s);
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Effects: Calls assign(s, traits​::​length(s)).
Returns: *this.
basic_string& assign(initializer_list<charT> il);
Effects: Calls assign(il.begin(), il.size()).
*this.
basic_string& assign(size_type n, charT c);
Effects: Equivalent to assign(basic_­string(n, c)).
Returns: *this.
template<class InputIterator> basic_string& assign(InputIterator first, InputIterator last);
Effects: Equivalent to assign(basic_­string(first, last, get_­allocator())).
Returns: *this.

24.3.2.6.4 basic_­string​::​insert [string.insert]

basic_string& insert(size_type pos, const basic_string& str);
Effects: Equivalent to: return insert(pos, str.data(), str.size());
basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n = npos);
Throws: out_­of_­range if pos1 > size() or pos2 > str.size().
Effects: Determines the effective length rlen of the string to insert as the smaller of n and str.size() - pos2 and calls insert(pos1, str.data() + pos2, rlen).
Returns: *this.
basic_string& insert(size_type pos, basic_string_view<charT, traits> sv);
Effects: Equivalent to: return insert(pos, sv.data(), sv.size());
template<class T> basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n = npos);
Throws: out_­of_­range if pos1 > size() or pos2 > sv.size().
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t.
Determines the effective length rlen of the string to assign as the smaller of n and sv.size() - pos2 and calls insert(pos1, sv.data() + pos2, rlen).
Remarks: This function shall not participate in overload resolution unless is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and is_­convertible_­v<const T&, const charT*> is false.
Returns: *this.
basic_string& insert(size_type pos, const charT* s, size_type n);
Requires: s points to an array of at least n elements of charT.
Throws: out_­of_­range if pos > size() or length_­error if size() + n > max_­size().
Effects: Replaces the string controlled by *this with a string of length size() + n whose first pos elements are a copy of the initial elements of the original string controlled by *this and whose next n elements are a copy of the elements in s and whose remaining elements are a copy of the remaining elements of the original string controlled by *this.
Returns: *this.
basic_string& insert(size_type pos, const charT* s);
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Effects: Equivalent to: return insert(pos, s, traits​::​length(s));
basic_string& insert(size_type pos, size_type n, charT c);
Effects: Equivalent to insert(pos, basic_­string(n, c)).
Returns: *this.
iterator insert(const_iterator p, charT c);
Requires: p is a valid iterator on *this.
Effects: Inserts a copy of c before the character referred to by p.
Returns: An iterator which refers to the copy of the inserted character.
iterator insert(const_iterator p, size_type n, charT c);
Requires: p is a valid iterator on *this.
Effects: Inserts n copies of c before the character referred to by p.
Returns: An iterator which refers to the copy of the first inserted character, or p if n == 0.
template<class InputIterator> iterator insert(const_iterator p, InputIterator first, InputIterator last);
Requires: p is a valid iterator on *this.
[first, last) is a valid range.
Effects: Equivalent to insert(p - begin(), basic_­string(first, last, get_­allocator())).
Returns: An iterator which refers to the copy of the first inserted character, or p if first == last.
iterator insert(const_iterator p, initializer_list<charT> il);
Effects: As if by insert(p, il.begin(), il.end()).
Returns: An iterator which refers to the copy of the first inserted character, or p if i1 is empty.

24.3.2.6.5 basic_­string​::​erase [string.erase]

basic_string& erase(size_type pos = 0, size_type n = npos);
Throws: out_­of_­range if pos > size().
Effects: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
The function then replaces the string controlled by *this with a string of length size() - xlen whose first pos elements are a copy of the initial elements of the original string controlled by *this, and whose remaining elements are a copy of the elements of the original string controlled by *this beginning at position pos + xlen.
Returns: *this.
iterator erase(const_iterator p);
Throws: Nothing.
Effects: Removes the character referred to by p.
Returns: An iterator which points to the element immediately following p prior to the element being erased.
If no such element exists, end() is returned.
iterator erase(const_iterator first, const_iterator last);
Requires: first and last are valid iterators on *this, defining a range [first, last).
Throws: Nothing.
Effects: Removes the characters in the range [first, last).
Returns: An iterator which points to the element pointed to by last prior to the other elements being erased.
If no such element exists, end() is returned.
void pop_back();
Requires: !empty().
Throws: Nothing.
Effects: Equivalent to erase(size() - 1, 1).

24.3.2.6.6 basic_­string​::​replace [string.replace]

basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
Effects: Equivalent to: return replace(pos1, n1, str.data(), str.size());
basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos);
Throws: out_­of_­range if pos1 > size() or pos2 > str.size().
Effects: Determines the effective length rlen of the string to be inserted as the smaller of n2 and str.size() - pos2 and calls replace(pos1, n1, str.data() + pos2, rlen).
Returns: *this.
basic_string& replace(size_type pos1, size_type n1, basic_string_view<charT, traits> sv);
Effects: Equivalent to: return replace(pos1, n1, sv.data(), sv.size());
template<class T> basic_string& replace(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos);
Throws: out_­of_­range if pos1 > size() or pos2 > sv.size().
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t.
Determines the effective length rlen of the string to be inserted as the smaller of n2 and sv.size() - pos2 and calls replace(pos1, n1, sv.data() + pos2, rlen).
Remarks: This function shall not participate in overload resolution unless is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and is_­convertible_­v<const T&, const charT*> is false.
Returns: *this.
basic_string& replace(size_type pos1, size_type n1, const charT* s, size_type n2);
Requires: s points to an array of at least n2 elements of charT.
Throws: out_­of_­range if pos1 > size() or length_­error if the length of the resulting string would exceed max_­size() (see below).
Effects: Determines the effective length xlen of the string to be removed as the smaller of n1 and size() - pos1.
If size() - xlen >= max_­size() - n2 throws length_­error.
Otherwise, the function replaces the string controlled by *this with a string of length size() - xlen + n2 whose first pos1 elements are a copy of the initial elements of the original string controlled by *this, whose next n2 elements are a copy of the initial n2 elements of s, and whose remaining elements are a copy of the elements of the original string controlled by *this beginning at position pos + xlen.
Returns: *this.
basic_string& replace(size_type pos, size_type n, const charT* s);
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Effects: Equivalent to: return replace(pos, n, s, traits​::​length(s));
basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c);
Effects: Equivalent to replace(pos1, n1, basic_­string(n2, c)).
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
Requires: [begin(), i1) and [i1, i2) are valid ranges.
Effects: Calls replace(i1 - begin(), i2 - i1, str).
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, basic_string_view<charT, traits> sv);
Requires: [begin(), i1) and [i1, i2) are valid ranges.
Effects: Calls replace(i1 - begin(), i2 - i1, sv).
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
Requires:[begin(), i1) and [i1, i2) are valid ranges and s points to an array of at least n elements of charT.
Effects: Calls replace(i1 - begin(), i2 - i1, s, n).
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
Requires:[begin(), i1) and [i1, i2) are valid ranges and s points to an array of at least traits​::​​length(s) + 1 elements of charT.
Effects: Calls replace(i1 - begin(), i2 - i1, s, traits​::​length(s)).
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
Requires:[begin(), i1) and [i1, i2) are valid ranges.
Effects: Calls replace(i1 - begin(), i2 - i1, basic_­string(n, c)).
Returns: *this.
template<class InputIterator> basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
Requires:[begin(), i1), [i1, i2) and [j1, j2) are valid ranges.
Effects: Calls replace(i1 - begin(), i2 - i1, basic_­string(j1, j2, get_­allocator())).
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<charT> il);
Requires:[begin(), i1) and [i1, i2) are valid ranges.
Effects: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()).
Returns: *this.

24.3.2.6.7 basic_­string​::​copy [string.copy]

size_type copy(charT* s, size_type n, size_type pos = 0) const;
Let rlen be the smaller of n and size() - pos.
Throws: out_­of_­range if pos > size().
Requires: [s, s + rlen) is a valid range.
Effects: Equivalent to: traits​::​copy(s, data() + pos, rlen).
[Note
:
This does not terminate s with a null object.
end note
]
Returns: rlen.

24.3.2.6.8 basic_­string​::​swap [string.swap]

void swap(basic_string& s) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Postconditions: *this contains the same sequence of characters that was in s, s contains the same sequence of characters that was in *this.
Throws: Nothing.
Complexity: Constant time.

24.3.2.7 basic_­string string operations [string.ops]

24.3.2.7.1 basic_­string accessors [string.accessors]

const charT* c_str() const noexcept; const charT* data() const noexcept;
Returns: A pointer p such that p + i == &operator[](i) for each i in [0, size()].
Complexity: Constant time.
Requires: The program shall not alter any of the values stored in the character array.
charT* data() noexcept;
Returns: A pointer p such that p + i == &operator[](i) for each i in [0, size()].
Complexity: Constant time.
Requires: The program shall not alter the value stored at p + size().
operator basic_string_view<charT, traits>() const noexcept;
Effects: Equivalent to: return basic_­string_­view<charT, traits>(data(), size());
allocator_type get_allocator() const noexcept;
Returns: A copy of the Allocator object used to construct the string or, if that allocator has been replaced, a copy of the most recent replacement.

24.3.2.7.2 basic_­string​::​find [string.find]

size_type find(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
Effects: Determines the lowest position xpos, if possible, such that both of the following conditions hold:
  • pos <= xpos and xpos + sv.size() <= size();
  • traits​::​eq(at(xpos + I), sv.at(I)) for all elements I of the data referenced by sv.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
size_type find(const basic_string& str, size_type pos = 0) const noexcept;
Effects: Equivalent to: return find(basic_­string_­view<charT, traits>(str), pos);
size_type find(const charT* s, size_type pos, size_type n) const;
Returns: find(basic_­string_­view<charT, traits>(s, n), pos).
size_type find(const charT* s, size_type pos = 0) const;
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Returns: find(basic_­string_­view<charT, traits>(s), pos).
size_type find(charT c, size_type pos = 0) const;
Returns: find(basic_­string(1, c), pos).

24.3.2.7.3 basic_­string​::​rfind [string.rfind]

size_type rfind(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
Effects: Determines the highest position xpos, if possible, such that both of the following conditions hold:
  • xpos <= pos and xpos + sv.size() <= size();
  • traits​::​eq(at(xpos + I), sv.at(I)) for all elements I of the data referenced by sv.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
Effects: Equivalent to: return rfind(basic_­string_­view<charT, traits>(str), pos);
size_type rfind(const charT* s, size_type pos, size_type n) const;
Returns: rfind(basic_­string_­view<charT, traits>(s, n), pos).
size_type rfind(const charT* s, size_type pos = npos) const;
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Returns: rfind(basic_­string_­view<charT, traits>(s), pos).
size_type rfind(charT c, size_type pos = npos) const;
Returns: rfind(basic_­string(1, c), pos).

24.3.2.7.4 basic_­string​::​find_­first_­of [string.find.first.of]

size_type find_first_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
Effects: Determines the lowest position xpos, if possible, such that both of the following conditions hold:
  • pos <= xpos and xpos < size();
  • traits​::​eq(at(xpos), sv.at(I)) for some element I of the data referenced by sv.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
Effects: Equivalent to: return find_­first_­of(basic_­string_­view<charT, traits>(str), pos);
size_type find_first_of(const charT* s, size_type pos, size_type n) const;
Returns: find_­first_­of(basic_­string_­view<charT, traits>(s, n), pos).
size_type find_first_of(const charT* s, size_type pos = 0) const;
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Returns: find_­first_­of(basic_­string_­view<charT, traits>(s), pos).
size_type find_first_of(charT c, size_type pos = 0) const;
Returns: find_­first_­of(basic_­string(1, c), pos).

24.3.2.7.5 basic_­string​::​find_­last_­of [string.find.last.of]

size_type find_last_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
Effects: Determines the highest position xpos, if possible, such that both of the following conditions hold:
  • xpos <= pos and xpos < size();
  • traits​::​eq(at(xpos), sv.at(I)) for some element I of the data referenced by sv.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
Effects: Equivalent to: return find_­last_­of(basic_­string_­view<charT, traits>(str), pos);
size_type find_last_of(const charT* s, size_type pos, size_type n) const;
Returns: find_­last_­of(basic_­string_­view<charT, traits>(s, n), pos).
size_type find_last_of(const charT* s, size_type pos = npos) const;
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Returns: find_­last_­of(basic_­string_­view<charT, traits>(s), pos).
size_type find_last_of(charT c, size_type pos = npos) const;
Returns: find_­last_­of(basic_­string(1, c), pos).

24.3.2.7.6 basic_­string​::​find_­first_­not_­of [string.find.first.not.of]

size_type find_first_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept;
Effects: Determines the lowest position xpos, if possible, such that both of the following conditions hold:
  • pos <= xpos and xpos < size();
  • traits​::​eq(at(xpos), sv.at(I)) for no element I of the data referenced by sv.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
Effects: Equivalent to:
return find_first_not_of(basic_string_view<charT, traits>(str), pos);
size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
Returns: find_­first_­not_­of(basic_­string_­view<charT, traits>(s, n), pos).
size_type find_first_not_of(const charT* s, size_type pos = 0) const;
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Returns: find_­first_­not_­of(basic_­string_­view<charT, traits>(s), pos).
size_type find_first_not_of(charT c, size_type pos = 0) const;
Returns: find_­first_­not_­of(basic_­string(1, c), pos).

24.3.2.7.7 basic_­string​::​find_­last_­not_­of [string.find.last.not.of]

size_type find_last_not_of(basic_string_view<charT, traits> sv, size_type pos = npos) const noexcept;
Effects: Determines the highest position xpos, if possible, such that both of the following conditions hold:
  • xpos <= pos and xpos < size();
  • traits​::​eq(at(xpos), sv.at(I)) for no element I of the data referenced by sv.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
Effects: Equivalent to:
return find_last_not_of(basic_string_view<charT, traits>(str), pos);
size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
Returns: find_­last_­not_­of(basic_­string_­view<charT, traits>(s, n), pos).
size_type find_last_not_of(const charT* s, size_type pos = npos) const;
Requires: s points to an array of at least traits​::​length(s) + 1 elements of charT.
Returns: find_­last_­not_­of(basic_­string_­view<charT, traits>(s), pos).
size_type find_last_not_of(charT c, size_type pos = npos) const;
Returns: find_­last_­not_­of(basic_­string(1, c), pos).

24.3.2.7.8 basic_­string​::​substr [string.substr]

basic_string substr(size_type pos = 0, size_type n = npos) const;
Throws: out_­of_­range if pos > size().
Effects: Determines the effective length rlen of the string to copy as the smaller of n and size() - pos.
Returns: basic_­string(data()+pos, rlen).

24.3.2.7.9 basic_­string​::​compare [string.compare]

int compare(basic_string_view<charT, traits> sv) const noexcept;
Effects: Determines the effective length rlen of the strings to compare as the smaller of size() and sv.size().
The function then compares the two strings by calling traits​::​compare(data(), sv.data(), rlen).
Returns: The nonzero result if the result of the comparison is nonzero.
Otherwise, returns a value as indicated in Table 58.
Table 58compare() results
Condition
Return Value
size() <  sv.size()
< 0
size() == sv.size()
 0
size() >  sv.size()
> 0
int compare(size_type pos1, size_type n1, basic_string_view<charT, traits> sv) const;
Effects: Equivalent to:
return basic_string_view<charT, traits>(data(), size()).substr(pos1, n1).compare(sv);
template<class T> int compare(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos) const;
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return basic_string_view<charT, traits>(
    data(), size()).substr(pos1, n1).compare(sv.substr(pos2, n2));
Remarks: This function shall not participate in overload resolution unless is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and is_­convertible_­v<const T&, const charT*> is false.
int compare(const basic_string& str) const noexcept;
Effects: Equivalent to: return compare(basic_­string_­view<charT, traits>(str));
int compare(size_type pos1, size_type n1, const basic_string& str) const;
Effects: Equivalent to: return compare(pos1, n1, basic_­string_­view<charT, traits>(str));
int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const;
Effects: Equivalent to:
return compare(pos1, n1, basic_string_view<charT, traits>(str), pos2, n2);
int compare(const charT* s) const;
Returns: compare(basic_­string(s)).
int compare(size_type pos, size_type n1, const charT* s) const;
Returns: basic_­string(*this, pos, n1).compare(basic_­string(s)).
int compare(size_type pos, size_type n1, const charT* s, size_type n2) const;
Returns: basic_­string(*this, pos, n1).compare(basic_­string(s, n2)).

24.3.3 basic_­string non-member functions [string.nonmembers]

24.3.3.1 operator+ [string.op+]

template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: basic_­string<charT, traits, Allocator>(lhs).append(rhs).
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: std​::​move(lhs.append(rhs)).
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, basic_string<charT, traits, Allocator>&& rhs);
Returns: std​::​move(rhs.insert(0, lhs)).
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, basic_string<charT, traits, Allocator>&& rhs);
Returns: std​::​move(lhs.append(rhs)).
[Note
:
Or equivalently, std​::​move(rhs.insert(0, lhs)).
end note
]
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: basic_­string<charT, traits, Allocator>(lhs) + rhs.
Remarks: Uses traits​::​length().
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const charT* lhs, basic_string<charT, traits, Allocator>&& rhs);
Returns: std​::​move(rhs.insert(0, lhs)).
Remarks: Uses traits​::​length().
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(charT lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: basic_­string<charT, traits, Allocator>(1, lhs) + rhs.
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(charT lhs, basic_string<charT, traits, Allocator>&& rhs);
Returns: std​::​move(rhs.insert(0, 1, lhs)).
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Returns: lhs + basic_­string<charT, traits, Allocator>(rhs).
Remarks: Uses traits​::​length().
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, const charT* rhs);
Returns: std​::​move(lhs.append(rhs)).
Remarks: Uses traits​::​length().
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
Returns: lhs + basic_­string<charT, traits, Allocator>(1, rhs).
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, charT rhs);
Returns: std​::​move(lhs.append(1, rhs)).

24.3.3.2 operator== [string.operator==]

template<class charT, class traits, class Allocator> bool operator==(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
Returns: lhs.compare(rhs) == 0.
template<class charT, class traits, class Allocator> bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: rhs == lhs.
template<class charT, class traits, class Allocator> bool operator==(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Requires: rhs points to an array of at least traits​::​length(rhs) + 1 elements of charT.
Returns: lhs.compare(rhs) == 0.

24.3.3.3 operator!= [string.op!=]

template<class charT, class traits, class Allocator> bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
Returns: !(lhs == rhs).
template<class charT, class traits, class Allocator> bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: rhs != lhs.
template<class charT, class traits, class Allocator> bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Requires: rhs points to an array of at least traits​::​length(rhs) + 1 elements of charT.
Returns: lhs.compare(rhs) != 0.

24.3.3.4 operator< [string.op<]

template<class charT, class traits, class Allocator> bool operator< (const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
Returns: lhs.compare(rhs) < 0.
template<class charT, class traits, class Allocator> bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: rhs.compare(lhs) > 0.
template<class charT, class traits, class Allocator> bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Returns: lhs.compare(rhs) < 0.

24.3.3.5 operator> [string.op>]

template<class charT, class traits, class Allocator> bool operator> (const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
Returns: lhs.compare(rhs) > 0.
template<class charT, class traits, class Allocator> bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: rhs.compare(lhs) < 0.
template<class charT, class traits, class Allocator> bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Returns: lhs.compare(rhs) > 0.

24.3.3.6 operator<= [string.op<=]

template<class charT, class traits, class Allocator> bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
Returns: lhs.compare(rhs) <= 0.
template<class charT, class traits, class Allocator> bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: rhs.compare(lhs) >= 0.
template<class charT, class traits, class Allocator> bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Returns: lhs.compare(rhs) <= 0.

24.3.3.7 operator>= [string.op>=]

template<class charT, class traits, class Allocator> bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
Returns: lhs.compare(rhs) >= 0.
template<class charT, class traits, class Allocator> bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Returns: rhs.compare(lhs) <= 0.
template<class charT, class traits, class Allocator> bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Returns: lhs.compare(rhs) >= 0.

24.3.3.8 swap [string.special]

template<class charT, class traits, class Allocator> void swap(basic_string<charT, traits, Allocator>& lhs, basic_string<charT, traits, Allocator>& rhs) noexcept(noexcept(lhs.swap(rhs)));
Effects: Equivalent to: lhs.swap(rhs);

24.3.3.9 Inserters and extractors [string.io]

template<class charT, class traits, class Allocator> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
Effects: Behaves as a formatted input function ([istream.formatted.reqmts]).
After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1, c).
If is.width() is greater than zero, the maximum number n of characters appended is is.width(); otherwise n is str.max_­size().
Characters are extracted and appended until any of the following occurs:
  • n characters are stored;
  • end-of-file occurs on the input sequence;
  • isspace(c, is.getloc()) is true for the next available input character c.
After the last character (if any) is extracted, is.width(0) is called and the sentry object is destroyed.
If the function extracts no characters, it calls is.setstate(ios​::​failbit), which may throw ios_­base​::​failure ([iostate.flags]).
Returns: is.
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
Effects: Equivalent to: return os << basic_­string_­view<charT, traits>(str);
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str, charT delim); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>&& is, basic_string<charT, traits, Allocator>& str, charT delim);
Effects: Behaves as an unformatted input function ([istream.unformatted]), except that it does not affect the value returned by subsequent calls to basic_­istream<>​::​gcount().
After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1, c) until any of the following occurs:
  • end-of-file occurs on the input sequence (in which case, the getline function calls is.setstate(​ios_­base​::​eofbit)).
  • traits​::​eq(c, delim) for the next available input character c (in which case, c is extracted but not appended) ([iostate.flags])
  • str.max_­size() characters are stored (in which case, the function calls is.setstate(ios_­base​::​failbit)) ([iostate.flags])
The conditions are tested in the order shown.
In any case, after the last character is extracted, the sentry object is destroyed.
If the function extracts no characters, it calls is.setstate(ios_­base​::​failbit) which may throw ios_­base​::​failure ([iostate.flags]).
Returns: is.
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>&& is, basic_string<charT, traits, Allocator>& str);
Returns: getline(is, str, is.widen('\n')).

24.3.4 Numeric conversions [string.conversions]

int stoi(const string& str, size_t* idx = 0, int base = 10); long stol(const string& str, size_t* idx = 0, int base = 10); unsigned long stoul(const string& str, size_t* idx = 0, int base = 10); long long stoll(const string& str, size_t* idx = 0, int base = 10); unsigned long long stoull(const string& str, size_t* idx = 0, int base = 10);
Effects: the first two functions call strtol(str.c_­str(), ptr, base), and the last three functions call strtoul(str.c_­str(), ptr, base), strtoll(str.c_­str(), ptr, base), and strtoull(​str.c_­str(), ptr, base), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed.
Throws out_­of_­range if strtol, strtoul, strtoll or strtoull sets errno to ERANGE, or if the converted value is outside the range of representable values for the return type.
float stof(const string& str, size_t* idx = 0); double stod(const string& str, size_t* idx = 0); long double stold(const string& str, size_t* idx = 0);
Effects: These functions call strtof(str.c_­str(), ptr), strtod(str.c_­str(), ptr), and strtold(​str.c_­str(), ptr), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if strtof, strtod, or strtold reports that no conversion could be performed.
Throws out_­of_­range if strtof, strtod, or strtold sets errno to ERANGE or if the converted value is outside the range of representable values for the return type.
string to_string(int val); string to_string(unsigned val); string to_string(long val); string to_string(unsigned long val); string to_string(long long val); string to_string(unsigned long long val); string to_string(float val); string to_string(double val); string to_string(long double val);
Returns: Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of "%d", "%u", "%ld", "%lu", "%lld", "%llu", "%f", "%f", or "%Lf", respectively, where buf designates an internal character buffer of sufficient size.
int stoi(const wstring& str, size_t* idx = 0, int base = 10); long stol(const wstring& str, size_t* idx = 0, int base = 10); unsigned long stoul(const wstring& str, size_t* idx = 0, int base = 10); long long stoll(const wstring& str, size_t* idx = 0, int base = 10); unsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10);
Effects: the first two functions call wcstol(str.c_­str(), ptr, base), and the last three functions call wcstoul(str.c_­str(), ptr, base), wcstoll(str.c_­str(), ptr, base), and wcstoull(​str.c_­str(), ptr, base), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if wcstol, wcstoul, wcstoll, or wcstoull reports that no conversion could be performed.
Throws out_­of_­range if the converted value is outside the range of representable values for the return type.
float stof(const wstring& str, size_t* idx = 0); double stod(const wstring& str, size_t* idx = 0); long double stold(const wstring& str, size_t* idx = 0);
Effects: These functions call wcstof(str.c_­str(), ptr), wcstod(str.c_­str(), ptr), and wcstold(​str.c_­str(), ptr), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if wcstof, wcstod, or wcstold reports that no conversion could be performed.
Throws out_­of_­range if wcstof, wcstod, or wcstold sets errno to ERANGE.
wstring to_wstring(int val); wstring to_wstring(unsigned val); wstring to_wstring(long val); wstring to_wstring(unsigned long val); wstring to_wstring(long long val); wstring to_wstring(unsigned long long val); wstring to_wstring(float val); wstring to_wstring(double val); wstring to_wstring(long double val);
Returns: Each function returns a wstring object holding the character representation of the value of its argument that would be generated by calling swprintf(buf, buffsz, fmt, val) with a format specifier of L"%d", L"%u", L"%ld", L"%lu", L"%lld", L"%llu", L"%f", L"%f", or L"%Lf", respectively, where buf designates an internal character buffer of sufficient size buffsz.

24.3.5 Hash support [basic.string.hash]

template<> struct hash<string>; template<> struct hash<u16string>; template<> struct hash<u32string>; template<> struct hash<wstring>;
If S is one of these string types, SV is the corresponding string view type, and s is an object of type S, then hash<S>()(s) == hash<SV>()(SV(s)).

24.3.6 Suffix for basic_­string literals [basic.string.literals]

string operator""s(const char* str, size_t len);
Returns: string{str, len}.
u16string operator""s(const char16_t* str, size_t len);
Returns: u16string{str, len}.
u32string operator""s(const char32_t* str, size_t len);
Returns: u32string{str, len}.
wstring operator""s(const wchar_t* str, size_t len);
Returns: wstring{str, len}.
[Note
:
The same suffix s is used for chrono​::​duration literals denoting seconds but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals.
end note
]

24.4 String view classes [string.view]

The class template basic_­string_­view describes an object that can refer to a constant contiguous sequence of char-like ([strings.general]) objects with the first element of the sequence at position zero.
In the rest of this section, the type of the char-like objects held in a basic_­string_­view object is designated by charT.
[Note
:
The library provides implicit conversions from const charT* and std​::​basic_­string<charT, ...> to std​::​basic_­string_­view<charT, ...> so that user code can accept just std​::​basic_­string_­view<charT> as a non-templated parameter wherever a sequence of characters is expected.
User-defined types should define their own implicit conversions to std​::​basic_­string_­view in order to interoperate with these functions.
end note
]
The complexity of basic_­string_­view member functions is unless otherwise specified.

24.4.1 Header <string_­view> synopsis [string.view.synop]

namespace std {
  // [string.view.template], class template basic_­string_­view
  template<class charT, class traits = char_traits<charT>>
  class basic_string_view;

  // [string.view.comparison], non-member comparison functions
  template<class charT, class traits>
    constexpr bool operator==(basic_string_view<charT, traits> x,
                              basic_string_view<charT, traits> y) noexcept;
  template<class charT, class traits>
    constexpr bool operator!=(basic_string_view<charT, traits> x,
                              basic_string_view<charT, traits> y) noexcept;
  template<class charT, class traits>
    constexpr bool operator< (basic_string_view<charT, traits> x,
                              basic_string_view<charT, traits> y) noexcept;
  template<class charT, class traits>
    constexpr bool operator> (basic_string_view<charT, traits> x,
                              basic_string_view<charT, traits> y) noexcept;
  template<class charT, class traits>
    constexpr bool operator<=(basic_string_view<charT, traits> x,
                              basic_string_view<charT, traits> y) noexcept;
  template<class charT, class traits>
    constexpr bool operator>=(basic_string_view<charT, traits> x,
                              basic_string_view<charT, traits> y) noexcept;
  // see [string.view.comparison], sufficient additional overloads of comparison functions

  // [string.view.io], inserters and extractors
  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os,
                 basic_string_view<charT, traits> str);

  // basic_­string_­view typedef names
  using string_view    = basic_string_view<char>;
  using u16string_view = basic_string_view<char16_t>;
  using u32string_view = basic_string_view<char32_t>;
  using wstring_view   = basic_string_view<wchar_t>;

  // [string.view.hash], hash support
  template<class T> struct hash;
  template<> struct hash<string_view>;
  template<> struct hash<u16string_view>;
  template<> struct hash<u32string_view>;
  template<> struct hash<wstring_view>;

  inline namespace literals {
  inline namespace string_view_literals {
    // [string.view.literals], suffix for basic_­string_­view literals
    constexpr string_view    operator""sv(const char* str, size_t len) noexcept;
    constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept;
    constexpr u32string_view operator""sv(const char32_t* str, size_t len) noexcept;
    constexpr wstring_view   operator""sv(const wchar_t* str, size_t len) noexcept;
  }
  }
}
The function templates defined in [utility.swap] and [iterator.range] are available when <string_­view> is included.

24.4.2 Class template basic_­string_­view [string.view.template]

template<class charT, class traits = char_traits<charT>>
class basic_string_view {
public:
  // types
  using traits_type            = traits;
  using value_type             = charT;
  using pointer                = value_type*;
  using const_pointer          = const value_type*;
  using reference              = value_type&;
  using const_reference        = const value_type&;
  using const_iterator         = implementation-defined; // see [string.view.iterators]
  using iterator               = const_iterator;228
  using const_reverse_iterator = reverse_iterator<const_iterator>;
  using reverse_iterator       = const_reverse_iterator;
  using size_type              = size_t;
  using difference_type        = ptrdiff_t;
  static constexpr size_type npos = size_type(-1);

  // [string.view.cons], construction and assignment
  constexpr basic_string_view() noexcept;
  constexpr basic_string_view(const basic_string_view&) noexcept = default;
  constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default;
  constexpr basic_string_view(const charT* str);
  constexpr basic_string_view(const charT* str, size_type len);

  // [string.view.iterators], iterator support
  constexpr const_iterator begin() const noexcept;
  constexpr const_iterator end() const noexcept;
  constexpr const_iterator cbegin() const noexcept;
  constexpr const_iterator cend() const noexcept;
  constexpr const_reverse_iterator rbegin() const noexcept;
  constexpr const_reverse_iterator rend() const noexcept;
  constexpr const_reverse_iterator crbegin() const noexcept;
  constexpr const_reverse_iterator crend() const noexcept;

  // [string.view.capacity], capacity
  constexpr size_type size() const noexcept;
  constexpr size_type length() const noexcept;
  constexpr size_type max_size() const noexcept;
  constexpr bool empty() const noexcept;

  // [string.view.access], element access
  constexpr const_reference operator[](size_type pos) const;
  constexpr const_reference at(size_type pos) const;
  constexpr const_reference front() const;
  constexpr const_reference back() const;
  constexpr const_pointer data() const noexcept;

  // [string.view.modifiers], modifiers
  constexpr void remove_prefix(size_type n);
  constexpr void remove_suffix(size_type n);
  constexpr void swap(basic_string_view& s) noexcept;

  // [string.view.ops], string operations
  size_type copy(charT* s, size_type n, size_type pos = 0) const;

  constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
  constexpr int compare(basic_string_view s) const noexcept;
  constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
  constexpr int compare(size_type pos1, size_type n1, basic_string_view s,
                        size_type pos2, size_type n2) const;
  constexpr int compare(const charT* s) const;
  constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
  constexpr int compare(size_type pos1, size_type n1, const charT* s,
                        size_type n2) const;
  constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
  constexpr size_type find(charT c, size_type pos = 0) const noexcept;
  constexpr size_type find(const charT* s, size_type pos, size_type n) const;
  constexpr size_type find(const charT* s, size_type pos = 0) const;
  constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
  constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
  constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
  constexpr size_type rfind(const charT* s, size_type pos = npos) const;
  constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
  constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
  constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
  constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
  constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
  constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
  constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
  constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
  constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
  constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
  constexpr size_type find_first_not_of(const charT* s, size_type pos,
                                        size_type n) const;
  constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
  constexpr size_type find_last_not_of(basic_string_view s,
                                       size_type pos = npos) const noexcept;
  constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
  constexpr size_type find_last_not_of(const charT* s, size_type pos,
                                       size_type n) const;
  constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;

private:
  const_pointer data_; // exposition only
  size_type size_;     // exposition only
};
In every specialization basic_­string_­view<charT, traits>, the type traits shall satisfy the character traits requirements ([char.traits]), and the type traits​::​char_­type shall name the same type as charT.
Because basic_­string_­view refers to a constant sequence, iterator and const_­iterator are the same type.

24.4.2.1 Construction and assignment [string.view.cons]

constexpr basic_string_view() noexcept;
Effects: Constructs an empty basic_­string_­view.
Postconditions: size_­ == 0 and data_­ == nullptr.
constexpr basic_string_view(const charT* str);
Requires: [str, str + traits​::​length(str)) is a valid range.
Effects: Constructs a basic_­string_­view, with the postconditions in Table 59.
Table 59basic_­string_­view(const charT*) effects
Element
Value
data_­
str
size_­
traits​::​length(str)
Complexity: .
constexpr basic_string_view(const charT* str, size_type len);
Requires: [str, str + len) is a valid range.
Effects: Constructs a basic_­string_­view, with the postconditions in Table 60.
Table 60basic_­string_­view(const charT*, size_­type) effects
Element
Value
data_­
str
size_­
len

24.4.2.2 Iterator support [string.view.iterators]

using const_iterator = implementation-defined;
A type that meets the requirements of a constant random access iterator ([random.access.iterators]) and of a contiguous iterator ([iterator.requirements.general]) whose value_­type is the template parameter charT.
For a basic_­string_­view str, any operation that invalidates a pointer in the range [str.data(), str.data() + str.size()) invalidates pointers, iterators, and references returned from str's methods.
All requirements on container iterators ([container.requirements]) apply to basic_­string_­view​::​const_­iterator as well.
constexpr const_iterator begin() const noexcept; constexpr const_iterator cbegin() const noexcept;
Returns: An iterator such that
  • if !empty(), &*begin() == data_­,
  • otherwise, an unspecified value such that [begin(), end()) is a valid range.
constexpr const_iterator end() const noexcept; constexpr const_iterator cend() const noexcept;
Returns: begin() + size().
constexpr const_reverse_iterator rbegin() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept;
Returns: const_­reverse_­iterator(end()).
constexpr const_reverse_iterator rend() const noexcept; constexpr const_reverse_iterator crend() const noexcept;
Returns: const_­reverse_­iterator(begin()).

24.4.2.3 Capacity [string.view.capacity]

constexpr size_type size() const noexcept;
Returns: size_­.
constexpr size_type length() const noexcept;
Returns: size_­.
constexpr size_type max_size() const noexcept;
Returns: The largest possible number of char-like objects that can be referred to by a basic_­string_­view.
constexpr bool empty() const noexcept;
Returns: size_­ == 0.

24.4.2.4 Element access [string.view.access]

constexpr const_reference operator[](size_type pos) const;
Requires: pos < size().
Returns: data_­[pos].
Throws: Nothing.
[Note
:
Unlike basic_­string​::​operator[], basic_­string_­view​::​operator[](size()) has undefined behavior instead of returning charT().
end note
]
constexpr const_reference at(size_type pos) const;
Throws: out_­of_­range if pos >= size().
Returns: data_­[pos].
constexpr const_reference front() const;
Requires: !empty().
Returns: data_­[0].
Throws: Nothing.
constexpr const_reference back() const;
Requires: !empty().
Returns: data_­[size() - 1].
Throws: Nothing.
constexpr const_pointer data() const noexcept;
Returns: data_­.
[Note
:
Unlike basic_­string​::​data() and string literals, data() may return a pointer to a buffer that is not null-terminated.
Therefore it is typically a mistake to pass data() to a function that takes just a const charT* and expects a null-terminated string.
end note
]

24.4.2.5 Modifiers [string.view.modifiers]

constexpr void remove_prefix(size_type n);
Requires: n <= size().
Effects: Equivalent to: data_­ += n; size_­ -= n;
constexpr void remove_suffix(size_type n);
Requires: n <= size().
Effects: Equivalent to: size_­ -= n;
constexpr void swap(basic_string_view& s) noexcept;
Effects: Exchanges the values of *this and s.

24.4.2.6 String operations [string.view.ops]

size_type copy(charT* s, size_type n, size_type pos = 0) const;
Let rlen be the smaller of n and size() - pos.
Throws: out_­of_­range if pos > size().
Requires: [s, s + rlen) is a valid range.
Effects: Equivalent to traits​::​copy(s, data() + pos, rlen).
Returns: rlen.
Complexity: .
constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
Let rlen be the smaller of n and size() - pos.
Throws: out_­of_­range if pos > size().
Effects: Determines rlen, the effective length of the string to reference.
Returns: basic_­string_­view(data() + pos, rlen).
constexpr int compare(basic_string_view str) const noexcept;
Let rlen be the smaller of size() and str.size().
Effects: Determines rlen, the effective length of the strings to compare.
The function then compares the two strings by calling traits​::​compare(data(), str.data(), rlen).
Complexity: .
Returns: The nonzero result if the result of the comparison is nonzero.
Otherwise, returns a value as indicated in Table 61.
Table 61compare() results
Condition
Return Value
size() < str.size()
< 0
size() == str.size()
 0
size() > str.size()
> 0
constexpr int compare(size_type pos1, size_type n1, basic_string_view str) const;
Effects: Equivalent to: return substr(pos1, n1).compare(str);
constexpr int compare(size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2) const;
Effects: Equivalent to: return substr(pos1, n1).compare(str.substr(pos2, n2));
constexpr int compare(const charT* s) const;
Effects: Equivalent to: return compare(basic_­string_­view(s));
constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
Effects: Equivalent to: return substr(pos1, n1).compare(basic_­string_­view(s));
constexpr int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const;
Effects: Equivalent to: return substr(pos1, n1).compare(basic_­string_­view(s, n2));

24.4.2.7 Searching [string.view.find]

This section specifies the basic_­string_­view member functions named find, rfind, find_­first_­of, find_­last_­of, find_­first_­not_­of, and find_­last_­not_­of.
Member functions in this section have complexity at worst, although implementations are encouraged to do better.
Each member function of the form
constexpr return-type F(const charT* s, size_type pos);
is equivalent to return F(basic_­string_­view(s), pos);
Each member function of the form
constexpr return-type F(const charT* s, size_type pos, size_type n);
is equivalent to return F(basic_­string_­view(s, n), pos);
Each member function of the form
constexpr return-type F(charT c, size_type pos);
is equivalent to return F(basic_­string_­view(&c, 1), pos);
constexpr size_type find(basic_string_view str, size_type pos = 0) const noexcept;
Let xpos be the lowest position, if possible, such that the following conditions hold:
  • pos <= xpos
  • xpos + str.size() <= size()
  • traits​::​eq(at(xpos + I), str.at(I)) for all elements I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type rfind(basic_string_view str, size_type pos = npos) const noexcept;
Let xpos be the highest position, if possible, such that the following conditions hold:
  • xpos <= pos
  • xpos + str.size() <= size()
  • traits​::​eq(at(xpos + I), str.at(I)) for all elements I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_first_of(basic_string_view str, size_type pos = 0) const noexcept;
Let xpos be the lowest position, if possible, such that the following conditions hold:
  • pos <= xpos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for some element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_last_of(basic_string_view str, size_type pos = npos) const noexcept;
Let xpos be the highest position, if possible, such that the following conditions hold:
  • xpos <= pos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for some element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_first_not_of(basic_string_view str, size_type pos = 0) const noexcept;
Let xpos be the lowest position, if possible, such that the following conditions hold:
  • pos <= xpos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for no element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.
constexpr size_type find_last_not_of(basic_string_view str, size_type pos = npos) const noexcept;
Let xpos be the highest position, if possible, such that the following conditions hold:
  • xpos <= pos
  • xpos < size()
  • traits​::​eq(at(xpos), str.at(I)) for no element I of the string referenced by str.
Effects: Determines xpos.
Returns: xpos if the function can determine such a value for xpos.
Otherwise, returns npos.

24.4.3 Non-member comparison functions [string.view.comparison]

Let S be basic_­string_­view<charT, traits>, and sv be an instance of S.
Implementations shall provide sufficient additional overloads marked constexpr and noexcept so that an object t with an implicit conversion to S can be compared according to Table 62.
Table 62 — Additional basic_­string_­view comparison overloads
Expression
Equivalent to
t == sv
S(t) == sv
sv == t
sv == S(t)
t != sv
S(t) != sv
sv != t
sv != S(t)
t < sv
S(t) < sv
sv < t
sv < S(t)
t > sv
S(t) > sv
sv > t
sv > S(t)
t <= sv
S(t) <= sv
sv <= t
sv <= S(t)
t >= sv
S(t) >= sv
sv >= t
sv >= S(t)
[Example
:
A sample conforming implementation for operator== would be:
template<class T> using __identity = decay_t<T>;
template<class charT, class traits>
  constexpr bool operator==(basic_string_view<charT, traits> lhs,
                            basic_string_view<charT, traits> rhs) noexcept {
    return lhs.compare(rhs) == 0;
  }
template<class charT, class traits>
  constexpr bool operator==(basic_string_view<charT, traits> lhs,
                            __identity<basic_string_view<charT, traits>> rhs) noexcept {
    return lhs.compare(rhs) == 0;
  }
template<class charT, class traits>
  constexpr bool operator==(__identity<basic_string_view<charT, traits>> lhs,
                            basic_string_view<charT, traits> rhs) noexcept {
    return lhs.compare(rhs) == 0;
  }
end example
]
template<class charT, class traits> constexpr bool operator==(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
Returns: lhs.compare(rhs) == 0.
template<class charT, class traits> constexpr bool operator!=(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
Returns: lhs.compare(rhs) != 0.
template<class charT, class traits> constexpr bool operator< (basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
Returns: lhs.compare(rhs) < 0.
template<class charT, class traits> constexpr bool operator> (basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
Returns: lhs.compare(rhs) > 0.
template<class charT, class traits> constexpr bool operator<=(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
Returns: lhs.compare(rhs) <= 0.
template<class charT, class traits> constexpr bool operator>=(basic_string_view<charT, traits> lhs, basic_string_view<charT, traits> rhs) noexcept;
Returns: lhs.compare(rhs) >= 0.

24.4.4 Inserters and extractors [string.view.io]

template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, basic_string_view<charT, traits> str);
Effects: Behaves as a formatted output function ([ostream.formatted.reqmts]) of os.
Forms a character sequence seq, initially consisting of the elements defined by the range [str.begin(), str.end()).
Determines padding for seq as described in [ostream.formatted.reqmts].
Then inserts seq as if by calling os.rdbuf()->sputn(​seq, n), where n is the larger of os.width() and str.size(); then calls os.​width(0).
Returns: os

24.4.5 Hash support [string.view.hash]

template<> struct hash<string_view>; template<> struct hash<u16string_view>; template<> struct hash<u32string_view>; template<> struct hash<wstring_view>;
The specialization is enabled ([unord.hash]).
[Note
:
The hash value of a string view object is equal to the hash value of the corresponding string object ([basic.string.hash]).
end note
]

24.4.6 Suffix for basic_­string_­view literals [string.view.literals]

constexpr string_view operator""sv(const char* str, size_t len) noexcept;
Returns: string_­view{str, len}.
constexpr u16string_view operator""sv(const char16_t* str, size_t len) noexcept;
Returns: u16string_­view{str, len}.
constexpr u32string_view operator""sv(const char32_t* str, size_t len) noexcept;
Returns: u32string_­view{str, len}.
constexpr wstring_view operator""sv(const wchar_t* str, size_t len) noexcept;
Returns: wstring_­view{str, len}.

24.5 Null-terminated sequence utilities [c.strings]

24.5.1 Header <cctype> synopsis [cctype.syn]

namespace std {
  int isalnum(int c);
  int isalpha(int c);
  int isblank(int c);
  int iscntrl(int c);
  int isdigit(int c);
  int isgraph(int c);
  int islower(int c);
  int isprint(int c);
  int ispunct(int c);
  int isspace(int c);
  int isupper(int c);
  int isxdigit(int c);
  int tolower(int c);
  int toupper(int c);
}
The contents and meaning of the header <cctype> are the same as the C standard library header <ctype.h>.
See also: ISO C 7.
4

24.5.2 Header <cwctype> synopsis [cwctype.syn]

namespace std {
  using wint_t = see below;
  using wctrans_t = see below;
  using wctype_t = see below;

  int iswalnum(wint_t wc);
  int iswalpha(wint_t wc);
  int iswblank(wint_t wc);
  int iswcntrl(wint_t wc);
  int iswdigit(wint_t wc);
  int iswgraph(wint_t wc);
  int iswlower(wint_t wc);
  int iswprint(wint_t wc);
  int iswpunct(wint_t wc);
  int iswspace(wint_t wc);
  int iswupper(wint_t wc);
  int iswxdigit(wint_t wc);
  int iswctype(wint_t wc, wctype_t desc);
  wctype_t wctype(const char* property);
  wint_t towlower(wint_t wc);
  wint_t towupper(wint_t wc);
  wint_t towctrans(wint_t wc, wctrans_t desc);
  wctrans_t wctrans(const char* property);
}

#define WEOF see below
The contents and meaning of the header <cwctype> are the same as the C standard library header <wctype.h>.
See also: ISO C 7.
30

24.5.3 Header <cstring> synopsis [cstring.syn]

namespace std {
  using size_t = see [support.types.layout];

  void* memcpy(void* s1, const void* s2, size_t n);
  void* memmove(void* s1, const void* s2, size_t n);
  char* strcpy(char* s1, const char* s2);
  char* strncpy(char* s1, const char* s2, size_t n);
  char* strcat(char* s1, const char* s2);
  char* strncat(char* s1, const char* s2, size_t n);
  int memcmp(const void* s1, const void* s2, size_t n);
  int strcmp(const char* s1, const char* s2);
  int strcoll(const char* s1, const char* s2);
  int strncmp(const char* s1, const char* s2, size_t n);
  size_t strxfrm(char* s1, const char* s2, size_t n);
  const void* memchr(const void* s, int c, size_t n);  // see [library.c]
  void* memchr(void* s, int c, size_t n)  // see [library.c]
  const char* strchr(const char* s, int c)  // see [library.c]
  char* strchr(char* s, int c)  // see [library.c]
  size_t strcspn(const char* s1, const char* s2);
  const char* strpbrk(const char* s1, const char* s2)  // see [library.c]
  char* strpbrk(char* s1, const char* s2)  // see [library.c]
  const char* strrchr(const char* s, int c)  // see [library.c]
  char* strrchr(char* s, int c)  // see [library.c]
  size_t strspn(const char* s1, const char* s2);
  const char* strstr(const char* s1, const char* s2)  // see [library.c]
  char* strstr(char* s1, const char* s2)  // see [library.c]
  char* strtok(char* s1, const char* s2);
  void* memset(void* s, int c, size_t n);
  char* strerror(int errnum);
  size_t strlen(const char* s);
}

#define NULL see [support.types.nullptr]
The contents and meaning of the header <cstring> are the same as the C standard library header <string.h>.
The functions strerror and strtok are not required to avoid data races ([res.on.data.races]).
The functions memcpy and memmove are signal-safe ([csignal.syn]).
[Note
:
The functions strchr, strpbrk, strrchr, strstr, and memchr, have different signatures in this International Standard, but they have the same behavior as in the C standard library ([library.c]).
end note
]
See also: ISO C 7.
24.

24.5.4 Header <cwchar> synopsis [cwchar.syn]

namespace std {
  using size_t = see [support.types.layout];
  using mbstate_t = see below;
  using wint_t = see below;

  struct tm;

  int fwprintf(FILE* stream, const wchar_t* format, ...);
  int fwscanf(FILE* stream, const wchar_t* format, ...);
  int swprintf(wchar_t* s, size_t n, const wchar_t* format, ...);
  int swscanf(const wchar_t* s, const wchar_t* format, ...);
  int vfwprintf(FILE* stream, const wchar_t* format, va_list arg);
  int vfwscanf(FILE* stream, const wchar_t* format, va_list arg);
  int vswprintf(wchar_t* s, size_t n, const wchar_t* format, va_list arg);
  int vswscanf(const wchar_t* s, const wchar_t* format, va_list arg);
  int vwprintf(const wchar_t* format, va_list arg);
  int vwscanf(const wchar_t* format, va_list arg);
  int wprintf(const wchar_t* format, ...);
  int wscanf(const wchar_t* format, ...);
  wint_t fgetwc(FILE* stream);
  wchar_t* fgetws(wchar_t* s, int n, FILE* stream);
  wint_t fputwc(wchar_t c, FILE* stream);
  int fputws(const wchar_t* s, FILE* stream);
  int fwide(FILE* stream, int mode);
  wint_t getwc(FILE* stream);
  wint_t getwchar();
  wint_t putwc(wchar_t c, FILE* stream);
  wint_t putwchar(wchar_t c);
  wint_t ungetwc(wint_t c, FILE* stream);
  double wcstod(const wchar_t* nptr, wchar_t** endptr);
  float wcstof(const wchar_t* nptr, wchar_t** endptr);
  long double wcstold(const wchar_t* nptr, wchar_t** endptr);
  long int wcstol(const wchar_t* nptr, wchar_t** endptr, int base);
  long long int wcstoll(const wchar_t* nptr, wchar_t** endptr, int base);
  unsigned long int wcstoul(const wchar_t* nptr, wchar_t** endptr, int base);
  unsigned long long int wcstoull(const wchar_t* nptr, wchar_t** endptr, int base);
  wchar_t* wcscpy(wchar_t* s1, const wchar_t* s2);
  wchar_t* wcsncpy(wchar_t* s1, const wchar_t* s2, size_t n);
  wchar_t* wmemcpy(wchar_t* s1, const wchar_t* s2, size_t n);
  wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n);
  wchar_t* wcscat(wchar_t* s1, const wchar_t* s2);
  wchar_t* wcsncat(wchar_t* s1, const wchar_t* s2, size_t n);
  int wcscmp(const wchar_t* s1, const wchar_t* s2);
  int wcscoll(const wchar_t* s1, const wchar_t* s2);
  int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n);
  size_t wcsxfrm(wchar_t* s1, const wchar_t* s2, size_t n);
  int wmemcmp(const wchar_t* s1, const wchar_t* s2, size_t n);
  const wchar_t* wcschr(const wchar_t* s, wchar_t c)  // see [library.c]
  wchar_t* wcschr(wchar_t* s, wchar_t c)  // see [library.c]
  size_t wcscspn(const wchar_t* s1, const wchar_t* s2);
  const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2)  // see [library.c]
  wchar_t* wcspbrk(wchar_t* s1, const wchar_t* s2)  // see [library.c]
  const wchar_t* wcsrchr(const wchar_t* s, wchar_t c)  // see [library.c]
  wchar_t* wcsrchr(wchar_t* s, wchar_t c)  // see [library.c]
  size_t wcsspn(const wchar_t* s1, const wchar_t* s2);
  const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2)  // see [library.c]
  wchar_t* wcsstr(wchar_t* s1, const wchar_t* s2)  // see [library.c]
  wchar_t* wcstok(wchar_t* s1, const wchar_t* s2, wchar_t** ptr);
  const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n)  // see [library.c]
  wchar_t* wmemchr(wchar_t* s, wchar_t c, size_t n)  // see [library.c]
  size_t wcslen(const wchar_t* s);
  wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n);
  size_t wcsftime(wchar_t* s, size_t maxsize, const wchar_t* format, const struct tm* timeptr);
  wint_t btowc(int c);
  int wctob(wint_t c);

  // [c.mb.wcs], multibyte / wide string and character conversion functions
  int mbsinit(const mbstate_t* ps);
  size_t mbrlen(const char* s, size_t n, mbstate_t* ps);
  size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps);
  size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps);
  size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps);
  size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps);
}

#define NULL see [support.types.nullptr]
#define WCHAR_MAX see below
#define WCHAR_MIN see below
#define WEOF see below
The contents and meaning of the header <cwchar> are the same as the C standard library header <wchar.h>, except that it does not declare a type wchar_­t.
[Note
:
The functions wcschr, wcspbrk, wcsrchr, wcsstr, and wmemchr have different signatures in this International Standard, but they have the same behavior as in the C standard library ([library.c]).
end note
]
See also: ISO C 7.
29

24.5.5 Header <cuchar> synopsis [cuchar.syn]

namespace std {
  using mbstate_t = see below;
  using size_t = see [support.types.layout];

  size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
  size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
  size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
  size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
}
The contents and meaning of the header <cuchar> are the same as the C standard library header <uchar.h>, except that it does not declare types char16_­t nor char32_­t.
See also: ISO C 7.
28

24.5.6 Multibyte / wide string and character conversion functions [c.mb.wcs]

[Note
:
The headers <cstdlib> ([cstdlib.syn]) and <cwchar> ([cwchar.syn]) declare the functions described in this subclause.
end note
]
int mbsinit(const mbstate_t* ps); int mblen(const char* s, size_t n); size_t mbstowcs(wchar_t* pwcs, const char* s, size_t n); size_t wcstombs(char* s, const wchar_t* pwcs, size_t n);
Effects: These functions have the semantics specified in the C standard library.
See also: ISO C 7.
22.
7.
1, 7.
22.
8, 7.
29.
6.
2.
1
int mbtowc(wchar_t* pwc, const char* s, size_t n); int wctomb(char* s, wchar_t wchar);
Effects: These functions have the semantics specified in the C standard library.
Remarks: Calls to these functions may introduce a data race ([res.on.data.races]) with other calls to the same function.
See also: ISO C 7.
22.
7
size_t mbrlen(const char* s, size_t n, mbstate_t* ps); size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps); size_t wcrtomb(char* s, wchar_t wc, mbstate_t* ps); size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps); size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps);
Effects: These functions have the semantics specified in the C standard library.
Remarks: Calling these functions with an mbstate_­t* argument that is a null pointer value may introduce a data race ([res.on.data.races]) with other calls to the same function with an mbstate_­t* argument that is a null pointer value.
See also: ISO C 7.
29.
6.
3

25 Localization library [localization]

25.1 General [localization.general]

This Clause describes components that C++ programs may use to encapsulate (and therefore be more portable when confronting) cultural differences.
The locale facility includes internationalization support for character classification and string collation, numeric, monetary, and date/time formatting and parsing, and message retrieval.
The following subclauses describe components for locales themselves, the standard facets, and facilities from the ISO C library, as summarized in Table 63.
Table 63 — Localization library summary
Subclause
Header(s)
Locales
<locale>
Standard locale Categories
C library locales
<clocale>

25.2 Header <locale> synopsis [locale.syn]

namespace std {
  // [locale], locale
  class locale;
  template <class Facet> const Facet& use_facet(const locale&);
  template <class Facet> bool         has_facet(const locale&) noexcept;

  // [locale.convenience], convenience interfaces
  template <class charT> bool isspace (charT c, const locale& loc);
  template <class charT> bool isprint (charT c, const locale& loc);
  template <class charT> bool iscntrl (charT c, const locale& loc);
  template <class charT> bool isupper (charT c, const locale& loc);
  template <class charT> bool islower (charT c, const locale& loc);
  template <class charT> bool isalpha (charT c, const locale& loc);
  template <class charT> bool isdigit (charT c, const locale& loc);
  template <class charT> bool ispunct (charT c, const locale& loc);
  template <class charT> bool isxdigit(charT c, const locale& loc);
  template <class charT> bool isalnum (charT c, const locale& loc);
  template <class charT> bool isgraph (charT c, const locale& loc);
  template <class charT> bool isblank (charT c, const locale& loc);
  template <class charT> charT toupper(charT c, const locale& loc);
  template <class charT> charT tolower(charT c, const locale& loc);

  // [category.ctype], ctype
  class ctype_base;
  template <class charT> class ctype;
  template <>            class ctype<char>;     // specialization
  template <class charT> class ctype_byname;
  class codecvt_base;
  template <class internT, class externT, class stateT> class codecvt;
  template <class internT, class externT, class stateT> class codecvt_byname;

  // [category.numeric], numeric
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class num_get;
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class num_put;
  template <class charT>
    class numpunct;
  template <class charT>
    class numpunct_byname;

  // [category.collate], collation
  template <class charT> class collate;
  template <class charT> class collate_byname;

  // [category.time], date and time
  class time_base;
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class time_get;
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class time_get_byname;
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class time_put;
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class time_put_byname;

  // [category.monetary], money
  class money_base;
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class money_get;
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class money_put;
  template <class charT, bool Intl = false>
    class moneypunct;
  template <class charT, bool Intl = false>
    class moneypunct_byname;

  // [category.messages], message retrieval
  class messages_base;
  template <class charT> class messages;
  template <class charT> class messages_byname;
}
The header <locale> defines classes and declares functions that encapsulate and manipulate the information peculiar to a locale.229
In this subclause, the type name struct tm is an incomplete type that is defined in <ctime>.

25.3 Locales [locales]

25.3.1 Class locale [locale]

namespace std {
  class locale {
  public:
    // types:
    class facet;
    class id;
    using category = int;
    static const category   // values assigned here are for exposition only
      none     = 0,
      collate  = 0x010, ctype    = 0x020,
      monetary = 0x040, numeric  = 0x080,
      time     = 0x100, messages = 0x200,
      all = collate | ctype | monetary | numeric | time  | messages;

    // construct/copy/destroy:
    locale() noexcept;
    locale(const locale& other) noexcept;
    explicit locale(const char* std_name);
    explicit locale(const string& std_name);
    locale(const locale& other, const char* std_name, category);
    locale(const locale& other, const string& std_name, category);
    template <class Facet> locale(const locale& other, Facet* f);
    locale(const locale& other, const locale& one, category);
    ~locale();                  // not virtual
    const locale& operator=(const locale& other) noexcept;
    template <class Facet> locale combine(const locale& other) const;

    // locale operations:
    basic_string<char>                  name() const;

    bool operator==(const locale& other) const;
    bool operator!=(const locale& other) const;

    template <class charT, class traits, class Allocator>
      bool operator()(const basic_string<charT, traits, Allocator>& s1,
                      const basic_string<charT, traits, Allocator>& s2) const;

    // global locale objects:
    static       locale  global(const locale&);
    static const locale& classic();
  };
}
Class locale implements a type-safe polymorphic set of facets, indexed by facet type.
In other words, a facet has a dual role: in one sense, it's just a class interface; at the same time, it's an index into a locale's set of facets.
Access to the facets of a locale is via two function templates, use_­facet<> and has_­facet<>.
[Example
:
An iostream operator<< might be implemented as:230
template <class charT, class traits>
basic_ostream<charT, traits>&
operator<< (basic_ostream<charT, traits>& s, Date d) {
  typename basic_ostream<charT, traits>::sentry cerberos(s);
  if (cerberos) {
    ios_base::iostate err = ios_base::iostate::goodbit;
    tm tmbuf; d.extract(tmbuf);
    use_facet<time_put<charT, ostreambuf_iterator<charT, traits>> >(
      s.getloc()).put(s, s, s.fill(), err, &tmbuf, 'x');
    s.setstate(err);            // might throw
  }
  return s;
}
end example
]
In the call to use_­facet<Facet>(loc), the type argument chooses a facet, making available all members of the named type.
If Facet is not present in a locale, it throws the standard exception bad_­cast.
A C++ program can check if a locale implements a particular facet with the function template has_­facet<Facet>().
User-defined facets may be installed in a locale, and used identically as may standard facets ([facets.examples]).
[Note
:
All locale semantics are accessed via use_­facet<> and has_­facet<>, except that:
  • A member operator template operator()(const basic_­string<C, T, A>&, const basic_­string<​C, T, A>&) is provided so that a locale may be used as a predicate argument to the standard collections, to collate strings.
  • Convenient global interfaces are provided for traditional ctype functions such as isdigit() and isspace(), so that given a locale object loc a C++ program can call isspace(c, loc).
    (This eases upgrading existing extractors ([istream.formatted]).)
end note
]
Once a facet reference is obtained from a locale object by calling use_­facet<>, that reference remains usable, and the results from member functions of it may be cached and re-used, as long as some locale object refers to that facet.
In successive calls to a locale facet member function on a facet object installed in the same locale, the returned result shall be identical.
A locale constructed from a name string (such as "POSIX"), or from parts of two named locales, has a name; all others do not.
Named locales may be compared for equality; an unnamed locale is equal only to (copies of) itself.
For an unnamed locale, locale​::​name() returns the string "*".
Whether there is one global locale object for the entire program or one global locale object per thread is implementation-defined.
Implementations should provide one global locale object per thread.
If there is a single global locale object for the entire program, implementations are not required to avoid data races on it ([res.on.data.races]).
Note that in the call to put the stream is implicitly converted to an ostreambuf_­iterator<charT, traits>.

25.3.1.1 locale types [locale.types]

25.3.1.1.1 Type locale​::​category [locale.category]

using category = int;
Valid category values include the locale member bitmask elements collate, ctype, monetary, numeric, time, and messages, each of which represents a single locale category.
In addition, locale member bitmask constant none is defined as zero and represents no category.
And locale member bitmask constant all is defined such that the expression
(collate | ctype | monetary | numeric | time | messages | all) == all
is true, and represents the union of all categories.
Further, the expression (X | Y), where X and Y each represent a single category, represents the union of the two categories.
locale member functions expecting a category argument require one of the category values defined above, or the union of two or more such values.
Such a category value identifies a set of locale categories.
Each locale category, in turn, identifies a set of locale facets, including at least those shown in Table 64.
Table 64 — Locale category facets
Category
Includes facets
collate
collate<char>, collate<wchar_­t>
ctype
ctype<char>, ctype<wchar_­t>
codecvt<char, char, mbstate_­t>
codecvt<char16_­t, char, mbstate_­t>
codecvt<char32_­t, char, mbstate_­t>
codecvt<wchar_­t, char, mbstate_­t>
monetary
moneypunct<char>, moneypunct<wchar_­t>
moneypunct<char, true>, moneypunct<wchar_­t, true>
money_­get<char>, money_­get<wchar_­t>
money_­put<char>, money_­put<wchar_­t>
numeric
numpunct<char>, numpunct<wchar_­t>
num_­get<char>, num_­get<wchar_­t>
num_­put<char>, num_­put<wchar_­t>
time
time_­get<char>, time_­get<wchar_­t>
time_­put<char>, time_­put<wchar_­t>
messages
messages<char>, messages<wchar_­t>
For any locale loc either constructed, or returned by locale​::​classic(), and any facet Facet shown in Table 64, has_­facet<Facet>(loc) is true.
Each locale member function which takes a locale​::​category argument operates on the corresponding set of facets.
An implementation is required to provide those specializations for facet templates identified as members of a category, and for those shown in Table 65.
Table 65 — Required specializations
Category
Includes facets
collate
collate_­byname<char>, collate_­byname<wchar_­t>
ctype
ctype_­byname<char>, ctype_­byname<wchar_­t>
codecvt_­byname<char, char, mbstate_­t>
codecvt_­byname<char16_­t, char, mbstate_­t>
codecvt_­byname<char32_­t, char, mbstate_­t>
codecvt_­byname<wchar_­t, char, mbstate_­t>
monetary
moneypunct_­byname<char, International>
moneypunct_­byname<wchar_­t, International>
money_­get<C, InputIterator>
money_­put<C, OutputIterator>
numeric
numpunct_­byname<char>, numpunct_­byname<wchar_­t>
num_­get<C, InputIterator>, num_­put<C, OutputIterator>
time
time_­get<char, InputIterator>
time_­get_­byname<char, InputIterator>
time_­get<wchar_­t, InputIterator>
time_­get_­byname<wchar_­t, InputIterator>
time_­put<char, OutputIterator>
time_­put_­byname<char, OutputIterator>
time_­put<wchar_­t, OutputIterator>
time_­put_­byname<wchar_­t, OutputIterator>
messages
messages_­byname<char>, messages_­byname<wchar_­t>
The provided implementation of members of facets num_­get<charT> and num_­put<charT> calls use_­facet<F>(l) only for facet F of types numpunct<charT> and ctype<charT>, and for locale l the value obtained by calling member getloc() on the ios_­base& argument to these functions.
In declarations of facets, a template parameter with name InputIterator or OutputIterator indicates the set of all possible specializations on parameters that satisfy the requirements of an Input Iterator or an Output Iterator, respectively ([iterator.requirements]).
A template parameter with name C represents the set of types containing char, wchar_­t, and any other implementation-defined character types that satisfy the requirements for a character on which any of the iostream components can be instantiated.
A template parameter with name International represents the set of all possible specializations on a bool parameter.

25.3.1.1.2 Class locale​::​facet [locale.facet]

namespace std {
  class locale::facet {
  protected:
    explicit facet(size_t refs = 0);
    virtual ~facet();
    facet(const facet&) = delete;
    void operator=(const facet&) = delete;
  };
}
Class facet is the base class for locale feature sets.
A class is a facet if it is publicly derived from another facet, or if it is a class derived from locale​::​facet and contains a publicly accessible declaration as follows:231
static ::std::locale::id id;
Template parameters in this Clause which are required to be facets are those named Facet in declarations.
A program that passes a type that is not a facet, or a type that refers to a volatile-qualified facet, as an (explicit or deduced) template parameter to a locale function expecting a facet, is ill-formed.
A const-qualified facet is a valid template argument to any locale function that expects a Facet template parameter.
The refs argument to the constructor is used for lifetime management.
For refs == 0, the implementation performs delete static_­cast<locale​::​facet*>(f) (where f is a pointer to the facet) when the last locale object containing the facet is destroyed; for refs == 1, the implementation never destroys the facet.
Constructors of all facets defined in this Clause take such an argument and pass it along to their facet base class constructor.
All one-argument constructors defined in this Clause are explicit, preventing their participation in automatic conversions.
For some standard facets a standard “_­byname” class, derived from it, implements the virtual function semantics equivalent to that facet of the locale constructed by locale(const char*) with the same name.
Each such facet provides a constructor that takes a const char* argument, which names the locale, and a refs argument, which is passed to the base class constructor.
Each such facet also provides a constructor that takes a string argument str and a refs argument, which has the same effect as calling the first constructor with the two arguments str.c_­str() and refs.
If there is no “_­byname” version of a facet, the base class implements named locale semantics itself by reference to other facets.
This is a complete list of requirements; there are no other requirements.
Thus, a facet class need not have a public copy constructor, assignment, default constructor, destructor, etc.

25.3.1.1.3 Class locale​::​id [locale.id]

namespace std {
  class locale::id {
  public:
    id();
    void operator=(const id&) = delete;
    id(const id&) = delete;
  };
}
The class locale​::​id provides identification of a locale facet interface, used as an index for lookup and to encapsulate initialization.
[Note
:
Because facets are used by iostreams, potentially while static constructors are running, their initialization cannot depend on programmed static initialization.
One initialization strategy is for locale to initialize each facet's id member the first time an instance of the facet is installed into a locale.
This depends only on static storage being zero before constructors run ([basic.start.static]).
end note
]

25.3.1.2 locale constructors and destructor [locale.cons]

locale() noexcept;
Default constructor: a snapshot of the current global locale.
Effects: Constructs a copy of the argument last passed to locale​::​global(locale&), if it has been called; else, the resulting facets have virtual function semantics identical to those of locale​::​classic().
[Note
:
This constructor is commonly used as the default value for arguments of functions that take a const locale& argument.
end note
]
locale(const locale& other) noexcept;
Effects: Constructs a locale which is a copy of other.
explicit locale(const char* std_name);
Effects: Constructs a locale using standard C locale names, e.g., "POSIX".
The resulting locale implements semantics defined to be associated with that name.
Throws: runtime_­error if the argument is not valid, or is null.
Remarks: The set of valid string argument values is "C", "", and any implementation-defined values.
explicit locale(const string& std_name);
Effects: The same as locale(std_­name.c_­str()).
locale(const locale& other, const char* std_name, category);
Effects: Constructs a locale as a copy of other except for the facets identified by the category argument, which instead implement the same semantics as locale(std_­name).
Throws: runtime_­error if the argument is not valid, or is null.
Remarks: The locale has a name if and only if other has a name.
locale(const locale& other, const string& std_name, category cat);
Effects: The same as locale(other, std_­name.c_­str(), cat).
template <class Facet> locale(const locale& other, Facet* f);
Effects: Constructs a locale incorporating all facets from the first argument except that of type Facet, and installs the second argument as the remaining facet.
If f is null, the resulting object is a copy of other.
Remarks: The resulting locale has no name.
locale(const locale& other, const locale& one, category cats);
Effects: Constructs a locale incorporating all facets from the first argument except those that implement cats, which are instead incorporated from the second argument.
Remarks: The resulting locale has a name if and only if the first two arguments have names.
const locale& operator=(const locale& other) noexcept;
Effects: Creates a copy of other, replacing the current value.
Returns: *this.
~locale();
A non-virtual destructor that throws no exceptions.

25.3.1.3 locale members [locale.members]

template <class Facet> locale combine(const locale& other) const;
Effects: Constructs a locale incorporating all facets from *this except for that one facet of other that is identified by Facet.
Returns: The newly created locale.
Throws: runtime_­error if has_­facet<Facet>(other) is false.
Remarks: The resulting locale has no name.
basic_string<char> name() const;
Returns: The name of *this, if it has one; otherwise, the string "*".

25.3.1.4 locale operators [locale.operators]

bool operator==(const locale& other) const;
Returns: true if both arguments are the same locale, or one is a copy of the other, or each has a name and the names are identical; false otherwise.
bool operator!=(const locale& other) const;
Returns: !(*this == other).
template <class charT, class traits, class Allocator> bool operator()(const basic_string<charT, traits, Allocator>& s1, const basic_string<charT, traits, Allocator>& s2) const;
Effects: Compares two strings according to the collate<charT> facet.
Remarks: This member operator template (and therefore locale itself) satisfies requirements for a comparator predicate template argument (Clause [algorithms]) applied to strings.
Returns:
use_facet<collate<charT>>(*this).compare(s1.data(), s1.data() + s1.size(),
                                         s2.data(), s2.data() + s2.size()) < 0
[Example
:
A vector of strings v can be collated according to collation rules in locale loc simply by ([alg.sort], [vector]):
std::sort(v.begin(), v.end(), loc);
end example
]

25.3.1.5 locale static members [locale.statics]

static locale global(const locale& loc);
Sets the global locale to its argument.
Effects: Causes future calls to the constructor locale() to return a copy of the argument.
If the argument has a name, does
setlocale(LC_ALL, loc.name().c_str());
otherwise, the effect on the C locale, if any, is implementation-defined.
No library function other than locale​::​global() shall affect the value returned by locale().
[Note
:
See [c.locales] for data race considerations when setlocale is invoked.
end note
]
Returns: The previous value of locale().
static const locale& classic();
The "C" locale.
Returns: A locale that implements the classic "C" locale semantics, equivalent to the value locale("C").
Remarks: This locale, its facets, and their member functions, do not change with time.

25.3.2 locale globals [locale.global.templates]

template <class Facet> const Facet& use_facet(const locale& loc);
Requires: Facet is a facet class whose definition contains the public static member id as defined in [locale.facet].
Returns: A reference to the corresponding facet of loc, if present.
Throws: bad_­cast if has_­facet<Facet>(loc) is false.
Remarks: The reference returned remains valid at least as long as any copy of loc exists.
template <class Facet> bool has_facet(const locale& loc) noexcept;
Returns: true if the facet requested is present in loc; otherwise false.

25.3.3 Convenience interfaces [locale.convenience]

25.3.3.1 Character classification [classification]

template <class charT> bool isspace (charT c, const locale& loc); template <class charT> bool isprint (charT c, const locale& loc); template <class charT> bool iscntrl (charT c, const locale& loc); template <class charT> bool isupper (charT c, const locale& loc); template <class charT> bool islower (charT c, const locale& loc); template <class charT> bool isalpha (charT c, const locale& loc); template <class charT> bool isdigit (charT c, const locale& loc); template <class charT> bool ispunct (charT c, const locale& loc); template <class charT> bool isxdigit(charT c, const locale& loc); template <class charT> bool isalnum (charT c, const locale& loc); template <class charT> bool isgraph (charT c, const locale& loc); template <class charT> bool isblank (charT c, const locale& loc);
Each of these functions isF returns the result of the expression:
use_facet<ctype<charT>>(loc).is(ctype_base::F, c)
where F is the ctype_­base​::​mask value corresponding to that function ([category.ctype]).232
When used in a loop, it is faster to cache the ctype<> facet and use it directly, or use the vector form of ctype<>​::​is.

25.3.3.2 Conversions [conversions]

25.3.3.2.1 Character conversions [conversions.character]

template <class charT> charT toupper(charT c, const locale& loc);
Returns: use_­facet<ctype<charT>>(loc).toupper(c).
template <class charT> charT tolower(charT c, const locale& loc);
Returns: use_­facet<ctype<charT>>(loc).tolower(c).

25.4 Standard locale categories [locale.categories]

Each of the standard categories includes a family of facets.
Some of these implement formatting or parsing of a datum, for use by standard or users' iostream operators << and >>, as members put() and get(), respectively.
Each such member function takes an ios_­base& argument whose members flags(), precision(), and width(), specify the format of the corresponding datum ([ios.base]).
Those functions which need to use other facets call its member getloc() to retrieve the locale imbued there.
Formatting facets use the character argument fill to fill out the specified width where necessary.
The put() members make no provision for error reporting.
(Any failures of the OutputIterator argument must be extracted from the returned iterator.)
The get() members take an ios_­base​::​iostate& argument whose value they ignore, but set to ios_­base​::​failbit in case of a parse error.
Within this clause it is unspecified whether one virtual function calls another virtual function.

25.4.1 The ctype category [category.ctype]

namespace std {
  class ctype_base {
  public:
    using mask = T;

    // numeric values are for exposition only.
    static const mask space = 1 << 0;
    static const mask print = 1 << 1;
    static const mask cntrl = 1 << 2;
    static const mask upper = 1 << 3;
    static const mask lower = 1 << 4;
    static const mask alpha = 1 << 5;
    static const mask digit = 1 << 6;
    static const mask punct = 1 << 7;
    static const mask xdigit = 1 << 8;
    static const mask blank = 1 << 9;
    static const mask alnum = alpha | digit;
    static const mask graph = alnum | punct;
  };
}
The type mask is a bitmask type ([bitmask.types]).

25.4.1.1 Class template ctype [locale.ctype]

namespace std {
  template <class charT>
    class ctype : public locale::facet, public ctype_base {
    public:
      using char_type = charT;

      explicit ctype(size_t refs = 0);

      bool         is(mask m, charT c) const;
      const charT* is(const charT* low, const charT* high, mask* vec) const;
      const charT* scan_is(mask m, const charT* low, const charT* high) const;
      const charT* scan_not(mask m, const charT* low, const charT* high) const;
      charT        toupper(charT c) const;
      const charT* toupper(charT* low, const charT* high) const;
      charT        tolower(charT c) const;
      const charT* tolower(charT* low, const charT* high) const;

      charT        widen(char c) const;
      const char*  widen(const char* low, const char* high, charT* to) const;
      char         narrow(charT c, char dfault) const;
      const charT* narrow(const charT* low, const charT* high, char dfault, char* to) const;

      static locale::id id;

    protected:
      ~ctype();
      virtual bool         do_is(mask m, charT c) const;
      virtual const charT* do_is(const charT* low, const charT* high, mask* vec) const;
      virtual const charT* do_scan_is(mask m, const charT* low, const charT* high) const;
      virtual const charT* do_scan_not(mask m, const charT* low, const charT* high) const;
      virtual charT        do_toupper(charT) const;
      virtual const charT* do_toupper(charT* low, const charT* high) const;
      virtual charT        do_tolower(charT) const;
      virtual const charT* do_tolower(charT* low, const charT* high) const;
      virtual charT        do_widen(char) const;
      virtual const char*  do_widen(const char* low, const char* high, charT* dest) const;
      virtual char         do_narrow(charT, char dfault) const;
      virtual const charT* do_narrow(const charT* low, const charT* high,
                                     char dfault, char* dest) const;
    };
}
Class ctype encapsulates the C library <cctype> features.
istream members are required to use ctype<> for character classing during input parsing.
The specializations required in Table 64 ([locale.category]), namely ctype<char> and ctype<wchar_­t>, implement character classing appropriate to the implementation's native character set.

25.4.1.1.1 ctype members [locale.ctype.members]

bool is(mask m, charT c) const; const charT* is(const charT* low, const charT* high, mask* vec) const;
Returns: do_­is(m, c) or do_­is(low, high, vec).
const charT* scan_is(mask m, const charT* low, const charT* high) const;
Returns: do_­scan_­is(m, low, high).
const charT* scan_not(mask m, const charT* low, const charT* high) const;
Returns: do_­scan_­not(m, low, high).
charT toupper(charT) const; const charT* toupper(charT* low, const charT* high) const;
Returns: do_­toupper(c) or do_­toupper(low, high).
charT tolower(charT c) const; const charT* tolower(charT* low, const charT* high) const;
Returns: do_­tolower(c) or do_­tolower(low, high).
charT widen(char c) const; const char* widen(const char* low, const char* high, charT* to) const;
Returns: do_­widen(c) or do_­widen(low, high, to).
char narrow(charT c, char dfault) const; const charT* narrow(const charT* low, const charT* high, char dfault, char* to) const;
Returns: do_­narrow(c, dfault) or do_­narrow(low, high, dfault, to).

25.4.1.1.2 ctype virtual functions [locale.ctype.virtuals]

bool do_is(mask m, charT c) const; const charT* do_is(const charT* low, const charT* high, mask* vec) const;
Effects: Classifies a character or sequence of characters.
For each argument character, identifies a value M of type ctype_­base​::​mask.
The second form identifies a value M of type ctype_­base​::​mask for each *p where (low <= p && p < high), and places it into vec[p - low].
Returns: The first form returns the result of the expression (M & m) != 0; i.e., true if the character has the characteristics specified.
The second form returns high.
const charT* do_scan_is(mask m, const charT* low, const charT* high) const;
Effects: Locates a character in a buffer that conforms to a classification m.
Returns: The smallest pointer p in the range [low, high) such that is(m, *p) would return true; otherwise, returns high.
const charT* do_scan_not(mask m, const charT* low, const charT* high) const;
Effects: Locates a character in a buffer that fails to conform to a classification m.
Returns: The smallest pointer p, if any, in the range [low, high) such that is(m, *p) would return false; otherwise, returns high.
charT do_toupper(charT c) const; const charT* do_toupper(charT* low, const charT* high) const;
Effects: Converts a character or characters to upper case.
The second form replaces each character *p in the range [low, high) for which a corresponding upper-case character exists, with that character.
Returns: The first form returns the corresponding upper-case character if it is known to exist, or its argument if not.
The second form returns high.
charT do_tolower(charT c) const; const charT* do_tolower(charT* low, const charT* high) const;
Effects: Converts a character or characters to lower case.
The second form replaces each character *p in the range [low, high) and for which a corresponding lower-case character exists, with that character.
Returns: The first form returns the corresponding lower-case character if it is known to exist, or its argument if not.
The second form returns high.
charT do_widen(char c) const; const char* do_widen(const char* low, const char* high, charT* dest) const;
Effects: Applies the simplest reasonable transformation from a char value or sequence of char values to the corresponding charT value or values.233
The only characters for which unique transformations are required are those in the basic source character set ([lex.charset]).
For any named ctype category with a ctype <charT> facet ctc and valid ctype_­base​::​mask value M, (ctc.​is(M, c) || !is(M, do_­widen(c)) ) is true.234
The second form transforms each character *p in the range [low, high), placing the result in dest[p - low].
Returns: The first form returns the transformed value.
The second form returns high.
char do_narrow(charT c, char dfault) const; const charT* do_narrow(const charT* low, const charT* high, char dfault, char* dest) const;
Effects: Applies the simplest reasonable transformation from a charT value or sequence of charT values to the corresponding char value or values.
For any character c in the basic source character set ([lex.charset]) the transformation is such that
do_widen(do_narrow(c, 0)) == c
For any named ctype category with a ctype<char> facet ctc however, and ctype_­base​::​mask value M,
(is(M, c) || !ctc.is(M, do_narrow(c, dfault)) )
is true (unless do_­narrow returns dfault).
In addition, for any digit character c, the expression (do_­narrow(c, dfault) - '0') evaluates to the digit value of the character.
The second form transforms each character *p in the range [low, high), placing the result (or dfault if no simple transformation is readily available) in dest[p - low].
Returns: The first form returns the transformed value; or dfault if no mapping is readily available.
The second form returns high.
The char argument of do_­widen is intended to accept values derived from character literals for conversion to the locale's encoding.
In other words, the transformed character is not a member of any character classification that c is not also a member of.

25.4.1.2 Class template ctype_­byname [locale.ctype.byname]

namespace std {
  template <class charT>
    class ctype_byname : public ctype<charT> {
    public:
      using mask = typename ctype<charT>::mask;
      explicit ctype_byname(const char*, size_t refs = 0);
      explicit ctype_byname(const string&, size_t refs = 0);
    protected:
      ~ctype_byname();
    };
}

25.4.1.3 ctype specializations [facet.ctype.special]

namespace std {
  template <>
    class ctype<char> : public locale::facet, public ctype_base {
    public:
      using char_type = char;

      explicit ctype(const mask* tab = 0, bool del = false,
                     size_t refs = 0);

      bool is(mask m, char c) const;
      const char* is(const char* low, const char* high, mask* vec) const;
      const char* scan_is (mask m,
                           const char* low, const char* high) const;
      const char* scan_not(mask m,
                           const char* low, const char* high) const;

      char        toupper(char c) const;
      const char* toupper(char* low, const char* high) const;
      char        tolower(char c) const;
      const char* tolower(char* low, const char* high) const;

      char  widen(char c) const;
      const char* widen(const char* low, const char* high, char* to) const;
      char  narrow(char c, char dfault) const;
      const char* narrow(const char* low, const char* high, char dfault,
                         char* to) const;

      static locale::id id;
      static const size_t table_size = implementation-defined;

      const mask* table() const noexcept;
      static const mask* classic_table() noexcept;

    protected:
      ~ctype();
      virtual char        do_toupper(char c) const;
      virtual const char* do_toupper(char* low, const char* high) const;
      virtual char        do_tolower(char c) const;
      virtual const char* do_tolower(char* low, const char* high) const;

      virtual char        do_widen(char c) const;
      virtual const char* do_widen(const char* low,
                                   const char* high,
                                   char* to) const;
      virtual char        do_narrow(char c, char dfault) const;
      virtual const char* do_narrow(const char* low,
                                    const char* high,
                                    char dfault, char* to) const;
    };
}
A specialization ctype<char> is provided so that the member functions on type char can be implemented inline.235
The implementation-defined value of member table_­size is at least 256.
Only the char (not unsigned char and signed char) form is provided.
The specialization is specified in the standard, and not left as an implementation detail, because it affects the derivation interface for ctype<char>.

25.4.1.3.1 ctype<char> destructor [facet.ctype.char.dtor]

~ctype();
Effects: If the constructor's first argument was nonzero, and its second argument was true, does delete [] table().

25.4.1.3.2 ctype<char> members [facet.ctype.char.members]

In the following member descriptions, for unsigned char values v where v >= table_­size, table()[v] is assumed to have an implementation-specific value (possibly different for each such value v) without performing the array lookup.
explicit ctype(const mask* tbl = 0, bool del = false, size_t refs = 0);
Requires: tbl either 0 or an array of at least table_­size elements.
Effects: Passes its refs argument to its base class constructor.
bool is(mask m, char c) const; const char* is(const char* low, const char* high, mask* vec) const;
Effects: The second form, for all *p in the range [low, high), assigns into vec[p - low] the value table()[(unsigned char)*p].
Returns: The first form returns table()[(unsigned char)c] & m; the second form returns high.
const char* scan_is(mask m, const char* low, const char* high) const;
Returns: The smallest p in the range [low, high) such that
table()[(unsigned char) *p] & m
is true.
const char* scan_not(mask m, const char* low, const char* high) const;
Returns: The smallest p in the range [low, high) such that
table()[(unsigned char) *p] & m
is false.
char toupper(char c) const; const char* toupper(char* low, const char* high) const;
Returns: do_­toupper(c) or do_­toupper(low, high), respectively.
char tolower(char c) const; const char* tolower(char* low, const char* high) const;
Returns: do_­tolower(c) or do_­tolower(low, high), respectively.
char widen(char c) const; const char* widen(const char* low, const char* high, char* to) const;
Returns: do_­widen(c) or do_­widen(low, high, to), respectively.
char narrow(char c, char dfault) const; const char* narrow(const char* low, const char* high, char dfault, char* to) const;
Returns: do_­narrow(c, dfault) or do_­narrow(low, high, dfault, to), respectively.
const mask* table() const noexcept;
Returns: The first constructor argument, if it was nonzero, otherwise classic_­table().

25.4.1.3.3 ctype<char> static members [facet.ctype.char.statics]

static const mask* classic_table() noexcept;
Returns: A pointer to the initial element of an array of size table_­size which represents the classifications of characters in the "C" locale.

25.4.1.3.4 ctype<char> virtual functions [facet.ctype.char.virtuals]

char        do_toupper(char) const;
const char* do_toupper(char* low, const char* high) const;
char        do_tolower(char) const;
const char* do_tolower(char* low, const char* high) const;

virtual char        do_widen(char c) const;
virtual const char* do_widen(const char* low,
                             const char* high,
                             char* to) const;
virtual char        do_narrow(char c, char dfault) const;
virtual const char* do_narrow(const char* low,
                              const char* high,
                              char dfault, char* to) const;
These functions are described identically as those members of the same name in the ctype class template ([locale.ctype.members]).

25.4.1.4 Class template codecvt [locale.codecvt]

namespace std {
  class codecvt_base {
  public:
    enum result { ok, partial, error, noconv };
  };

  template <class internT, class externT, class stateT>
    class codecvt : public locale::facet, public codecvt_base {
    public:
      using intern_type = internT;
      using extern_type = externT;
      using state_type  = stateT;

      explicit codecvt(size_t refs = 0);

      result out(
          stateT& state,
          const internT* from, const internT* from_end, const internT*& from_next,
                externT*   to,       externT*   to_end,       externT*&   to_next) const;

      result unshift(
          stateT& state,
                externT*    to,      externT*   to_end,       externT*&   to_next) const;

      result in(
          stateT& state,
          const externT* from, const externT* from_end, const externT*& from_next,
                internT*   to,       internT*   to_end,       internT*&   to_next) const;

      int encoding() const noexcept;
      bool always_noconv() const noexcept;
      int length(stateT&, const externT* from, const externT* end, size_t max) const;
      int max_length() const noexcept;

      static locale::id id;

    protected:
      ~codecvt();
      virtual result do_out(
          stateT& state,
          const internT* from, const internT* from_end, const internT*& from_next,
                externT* to,         externT*   to_end,       externT*&   to_next) const;
      virtual result do_in(
          stateT& state,
          const externT* from, const externT* from_end, const externT*& from_next,
                internT* to,         internT*   to_end,       internT*&   to_next) const;
      virtual result do_unshift(
          stateT& state,
                externT* to,         externT*   to_end,       externT*&   to_next) const;

      virtual int do_encoding() const noexcept;
      virtual bool do_always_noconv() const noexcept;
      virtual int do_length(stateT&, const externT* from, const externT* end, size_t max) const;
      virtual int do_max_length() const noexcept;
    };
}
The class codecvt<internT, externT, stateT> is for use when converting from one character encoding to another, such as from wide characters to multibyte characters or between wide character encodings such as Unicode and EUC.
The stateT argument selects the pair of character encodings being mapped between.
The specializations required in Table 64 ([locale.category]) convert the implementation-defined native character set.
codecvt<char, char, mbstate_­t> implements a degenerate conversion; it does not convert at all.
The specialization codecvt<char16_­t, char, mbstate_­t> converts between the UTF-16 and UTF-8 encoding forms, and the specialization codecvt <char32_­t, char, mbstate_­t> converts between the UTF-32 and UTF-8 encoding forms.
codecvt<wchar_­t, char, mbstate_­t> converts between the native character sets for narrow and wide characters.
Specializations on mbstate_­t perform conversion between encodings known to the library implementer.
Other encodings can be converted by specializing on a user-defined stateT type.
Objects of type stateT can contain any state that is useful to communicate to or from the specialized do_­in or do_­out members.

25.4.1.4.1 codecvt members [locale.codecvt.members]

result out( stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_end, externT*& to_next) const;
Returns: do_­out(state, from, from_­end, from_­next, to, to_­end, to_­next).
result unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const;
Returns: do_­unshift(state, to, to_­end, to_­next).
result in( stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_end, internT*& to_next) const;
Returns: do_­in(state, from, from_­end, from_­next, to, to_­end, to_­next).
int encoding() const noexcept;
Returns: do_­encoding().
bool always_noconv() const noexcept;
Returns: do_­always_­noconv().
int length(stateT& state, const externT* from, const externT* from_end, size_t max) const;
Returns: do_­length(state, from, from_­end, max).
int max_length() const noexcept;
Returns: do_­max_­length().

25.4.1.4.2 codecvt virtual functions [locale.codecvt.virtuals]

result do_out( stateT& state, const internT* from, const internT* from_end, const internT*& from_next, externT* to, externT* to_end, externT*& to_next) const; result do_in( stateT& state, const externT* from, const externT* from_end, const externT*& from_next, internT* to, internT* to_end, internT*& to_next) const;
Requires: (from <= from_­end && to <= to_­end) well-defined and true; state initialized, if at the beginning of a sequence, or else equal to the result of converting the preceding characters in the sequence.
Effects: Translates characters in the source range [from, from_­end), placing the results in sequential positions starting at destination to.
Converts no more than (from_­end - from) source elements, and stores no more than (to_­end - to) destination elements.
Stops if it encounters a character it cannot convert.
It always leaves the from_­next and to_­next pointers pointing one beyond the last element successfully converted.
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from, from_next).
to_­next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_­end).
A codecvt facet that is used by basic_­filebuf ([file.streams]) shall have the property that if
do_out(state, from, from_end, from_next, to, to_end, to_next)
would return ok, where from != from_­end, then
do_out(state, from, from + 1, from_next, to, to_end, to_next)
shall also return ok, and that if
do_in(state, from, from_end, from_next, to, to_end, to_next)
would return ok, where to != to_­end, then
do_in(state, from, from_end, from_next, to, to + 1, to_next)
shall also return ok.236
[Note
:
As a result of operations on state, it can return ok or partial and set from_­next == from and to_­next != to.
end note
]
Remarks: Its operations on state are unspecified.
[Note
:
This argument can be used, for example, to maintain shift state, to specify conversion options (such as count only), or to identify a cache of seek offsets.
end note
]
Returns: An enumeration value, as summarized in Table 66.
Table 66do_­in/do_­out result values
Value
Meaning
ok
completed the conversion
partial
not all source characters converted
error
encountered a character in [from, from_­end) that it could not convert
noconv
internT and externT are the same type, and input sequence is identical to converted sequence
A return value of partial, if (from_­next == from_­end), indicates that either the destination sequence has not absorbed all the available destination elements, or that additional source elements are needed before another destination element can be produced.
result do_unshift(stateT& state, externT* to, externT* to_end, externT*& to_next) const;
Requires: (to <= to_­end) well defined and true; state initialized, if at the beginning of a sequence, or else equal to the result of converting the preceding characters in the sequence.
Effects: Places characters starting at to that should be appended to terminate a sequence when the current stateT is given by state.237
Stores no more than (to_­end - to) destination elements, and leaves the to_­next pointer pointing one beyond the last element successfully stored.
Returns: An enumeration value, as summarized in Table 67.
Table 67do_­unshift result values
Value
Meaning
ok
completed the sequence
partial
space for more than to_­end - to destination elements was needed to terminate a sequence given the value of state
error
an unspecified error has occurred
noconv
no termination is needed for this state_­type
int do_encoding() const noexcept;
Returns: -1 if the encoding of the externT sequence is state-dependent; else the constant number of externT characters needed to produce an internal character; or 0 if this number is not a constant.238
bool do_always_noconv() const noexcept;
Returns: true if do_­in() and do_­out() return noconv for all valid argument values.
codecvt<char, char, mbstate_­t> returns true.
int do_length(stateT& state, const externT* from, const externT* from_end, size_t max) const;
Requires: (from <= from_­end) well-defined and true; state initialized, if at the beginning of a sequence, or else equal to the result of converting the preceding characters in the sequence.
Effects: The effect on the state argument is “as if” it called do_­in(state, from, from_­end, from, to, to+max, to) for to pointing to a buffer of at least max elements.
Returns: (from_­next-from) where from_­next is the largest value in the range [from, from_­end] such that the sequence of values in the range [from, from_­next) represents max or fewer valid complete characters of type internT.
The specialization codecvt<char, char, mbstate_­t>, returns the lesser of max and (from_­end-from).
int do_max_length() const noexcept;
Returns: The maximum value that do_­length(state, from, from_­end, 1) can return for any valid range [from, from_­end) and stateT value state.
The specialization codecvt<char, char, mbstate_­t>​::​do_­max_­length() returns 1.
Informally, this means that basic_­filebuf assumes that the mappings from internal to external characters is 1 to N: a codecvt facet that is used by basic_­filebuf must be able to translate characters one internal character at a time.
Typically these will be characters to return the state to stateT().
If encoding() yields -1, then more than max_­length() externT elements may be consumed when producing a single internT character, and additional externT elements may appear at the end of a sequence after those that yield the final internT character.

25.4.1.5 Class template codecvt_­byname [locale.codecvt.byname]

namespace std {
  template <class internT, class externT, class stateT>
    class codecvt_byname : public codecvt<internT, externT, stateT> {
    public:
      explicit codecvt_byname(const char*, size_t refs = 0);
      explicit codecvt_byname(const string&, size_t refs = 0);
    protected:
      ~codecvt_byname();
    };
}

25.4.2 The numeric category [category.numeric]

The classes num_­get<> and num_­put<> handle numeric formatting and parsing.
Virtual functions are provided for several numeric types.
Implementations may (but are not required to) delegate extraction of smaller types to extractors for larger types.239
All specifications of member functions for num_­put and num_­get in the subclauses of [category.numeric] only apply to the specializations required in Tables 64 and 65 ([locale.category]), namely num_­get<char>, num_­get<wchar_­t>, num_­get<C, InputIterator>, num_­put<char>, num_­put<wchar_­t>, and num_­put<C, OutputIterator>.
These specializations refer to the ios_­base& argument for formatting specifications ([locale.categories]), and to its imbued locale for the numpunct<> facet to identify all numeric punctuation preferences, and also for the ctype<> facet to perform character classification.
Extractor and inserter members of the standard iostreams use num_­get<> and num_­put<> member functions for formatting and parsing numeric values ([istream.formatted.reqmts], [ostream.formatted.reqmts]).
Parsing "-1" correctly into, e.g., an unsigned short requires that the corresponding member get() at least extract the sign before delegating.

25.4.2.1 Class template num_­get [locale.num.get]

namespace std {
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class num_get : public locale::facet {
    public:
      using char_type = charT;
      using iter_type = InputIterator;

      explicit num_get(size_t refs = 0);

      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, bool& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, long long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned short& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned int& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, unsigned long long& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, float& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, double& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, long double& v) const;
      iter_type get(iter_type in, iter_type end, ios_base&,
                    ios_base::iostate& err, void*& v) const;

      static locale::id id;

    protected:
      ~num_get();
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, bool& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, long long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned short& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned int& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, unsigned long long& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, float& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, double& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, long double& v) const;
      virtual iter_type do_get(iter_type, iter_type, ios_base&,
                               ios_base::iostate& err, void*& v) const;
    };
}
The facet num_­get is used to parse numeric values from an input sequence such as an istream.

25.4.2.1.1 num_­get members [facet.num.get.members]

iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, bool& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned short& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned int& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long long& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, float& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, double& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long double& val) const; iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, void*& val) const;
Returns: do_­get(in, end, str, err, val).

25.4.2.1.2 num_­get virtual functions [facet.num.get.virtuals]

iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned short& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned int& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, unsigned long long& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, float& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, double& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long double& val) const; iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, void*& val) const;
Effects: Reads characters from in, interpreting them according to str.flags(), use_­facet<ctype<​charT>>(loc), and use_­facet<numpunct<charT>>(loc), where loc is str.getloc().
The details of this operation occur in three stages
  • Stage 1: Determine a conversion specifier
  • Stage 2: Extract characters from in and determine a corresponding char value for the format expected by the conversion specification determined in stage 1.
  • Stage 3: Store results
The details of the stages are presented below.
  • Stage 1: The function initializes local variables via
    fmtflags flags = str.flags();
    fmtflags basefield = (flags & ios_base::basefield);
    fmtflags uppercase = (flags & ios_base::uppercase);
    fmtflags boolalpha = (flags & ios_base::boolalpha);
    For conversion to an integral type, the function determines the integral conversion specifier as indicated in Table 68.
    The table is ordered.
    That is, the first line whose condition is true applies.
    Table 68 — Integer conversions
    State
    stdio equivalent
    basefield == oct
    %o
    basefield == hex
    %X
    basefield == 0
    %i
    signed integral type
    %d
    unsigned integral type
    %u
    For conversions to a floating type the specifier is %g.
    For conversions to void* the specifier is %p.
    A length modifier is added to the conversion specification, if needed, as indicated in Table 69.
    Table 69 — Length modifier
    Type
    Length modifier
    short
    h
    unsigned short
    h
    long
    l
    unsigned long
    l
    long long
    ll
    unsigned long long
    ll
    double
    l
    long double
    L
  • Stage 2: If in == end then stage 2 terminates.
    Otherwise a charT is taken from in and local variables are initialized as if by
    char_type ct = *in;
    char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms];
    if (ct == use_facet<numpunct<charT>>(loc).decimal_point())
    c = '.';
    bool discard =
      ct == use_facet<numpunct<charT>>(loc).thousands_sep()
      && use_facet<numpunct<charT>>(loc).grouping().length() != 0;
    where the values src and atoms are defined as if by:
    static const char src[] = "0123456789abcdefxABCDEFX+-";
    char_type atoms[sizeof(src)];
    use_facet<ctype<charT>>(loc).widen(src, src + sizeof(src), atoms);
    for this value of loc.
    If discard is true, then if '.' has not yet been accumulated, then the position of the character is remembered, but the character is otherwise ignored.
    Otherwise, if '.' has already been accumulated, the character is discarded and Stage 2 terminates.
    If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by Stage 1.
    If so, it is accumulated.
    If the character is either discarded or accumulated then in is advanced by ++in and processing returns to the beginning of stage 2.
  • Stage 3: The sequence of chars accumulated in stage 2 (the field) is converted to a numeric value by the rules of one of the functions declared in the header <cstdlib>:
    • For a signed integer value, the function strtoll.
    • For an unsigned integer value, the function strtoull.
    • For a float value, the function strtof.
    • For a double value, the function strtod.
    • For a long double value, the function strtold.
    The numeric value to be stored can be one of:
    • zero, if the conversion function does not convert the entire field.
    • the most positive (or negative) representable value, if the field to be converted to a signed integer type represents a value too large positive (or negative) to be represented in val.
    • the most positive representable value, if the field to be converted to an unsigned integer type represents a value that cannot be represented in val.
    • the converted value, otherwise.
    The resultant numeric value is stored in val.
    If the conversion function does not convert the entire field, or if the field represents a value outside the range of representable values, ios_­base​::​failbit is assigned to err.
Digit grouping is checked.
That is, the positions of discarded separators is examined for consistency with use_­facet<numpunct<charT>>(loc).grouping().
If they are not consistent then ios_­base​::​failbit is assigned to err.
In any case, if stage 2 processing was terminated by the test for in == end then err |= ios_­base​::​eofbit is performed.
iter_type do_get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, bool& val) const;
Effects: If (str.flags()&ios_­base​::​boolalpha) == 0 then input proceeds as it would for a long except that if a value is being stored into val, the value is determined according to the following: If the value to be stored is 0 then false is stored.
If the value is 1 then true is stored.
Otherwise true is stored and ios_­base​::​failbit is assigned to err.
Otherwise target sequences are determined “as if” by calling the members falsename() and truename() of the facet obtained by use_­facet<numpunct<charT>>(str.getloc()).
Successive characters in the range [in, end) (see [sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match.
The input iterator in is compared to end only when necessary to obtain a character.
If a target sequence is uniquely matched, val is set to the corresponding value.
Otherwise false is stored and ios_­base​::​failbit is assigned to err.
The in iterator is always left pointing one position beyond the last character successfully matched.
If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in == end).
If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit) if the reason for the failure was that (in == end).
[Example
:
For targets true: "a" and false: "abb", the input sequence "a" yields val == true and err == str.eofbit; the input sequence "abc" yields err = str.failbit, with in ending at the 'c' element.
For targets true: "1" and false: "0", the input sequence "1" yields val == true and err == str.goodbit.
For empty targets (""), any input sequence yields err == str.failbit.
end example
]
Returns: in.

25.4.2.2 Class template num_­put [locale.nm.put]

namespace std {
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class num_put : public locale::facet {
    public:
      using char_type = charT;
      using iter_type = OutputIterator;

      explicit num_put(size_t refs = 0);

      iter_type put(iter_type s, ios_base& f, char_type fill, bool v) const;
      iter_type put(iter_type s, ios_base& f, char_type fill, long v) const;
      iter_type put(iter_type s, ios_base& f, char_type fill, long long v) const;
      iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long v) const;
      iter_type put(iter_type s, ios_base& f, char_type fill, unsigned long long v) const;
      iter_type put(iter_type s, ios_base& f, char_type fill, double v) const;
      iter_type put(iter_type s, ios_base& f, char_type fill, long double v) const;
      iter_type put(iter_type s, ios_base& f, char_type fill, const void* v) const;

      static locale::id id;

    protected:
      ~num_put();
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, bool v) const;
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, long v) const;
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, long long v) const;
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long) const;
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, unsigned long long) const;
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, double v) const;
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, long double v) const;
      virtual iter_type do_put(iter_type, ios_base&, char_type fill, const void* v) const;
    };
}
The facet num_­put is used to format numeric values to a character sequence such as an ostream.

25.4.2.2.1 num_­put members [facet.num.put.members]

iter_type put(iter_type out, ios_base& str, char_type fill, bool val) const; iter_type put(iter_type out, ios_base& str, char_type fill, long val) const; iter_type put(iter_type out, ios_base& str, char_type fill, long long val) const; iter_type put(iter_type out, ios_base& str, char_type fill, unsigned long val) const; iter_type put(iter_type out, ios_base& str, char_type fill, unsigned long long val) const; iter_type put(iter_type out, ios_base& str, char_type fill, double val) const; iter_type put(iter_type out, ios_base& str, char_type fill, long double val) const; iter_type put(iter_type out, ios_base& str, char_type fill, const void* val) const;
Returns: do_­put(out, str, fill, val).

25.4.2.2.2 num_­put virtual functions [facet.num.put.virtuals]

iter_type do_put(iter_type out, ios_base& str, char_type fill, long val) const; iter_type do_put(iter_type out, ios_base& str, char_type fill, long long val) const; iter_type do_put(iter_type out, ios_base& str, char_type fill, unsigned long val) const; iter_type do_put(iter_type out, ios_base& str, char_type fill, unsigned long long val) const; iter_type do_put(iter_type out, ios_base& str, char_type fill, double val) const; iter_type do_put(iter_type out, ios_base& str, char_type fill, long double val) const; iter_type do_put(iter_type out, ios_base& str, char_type fill, const void* val) const;
Effects: Writes characters to the sequence out, formatting val as desired.
In the following description, a local variable initialized with:
locale loc = str.getloc();
The details of this operation occur in several stages:
  • Stage 1: Determine a printf conversion specifier spec and determine the characters that would be printed by printf ([c.files]) given this conversion specifier for
    printf(spec, val)
    assuming that the current locale is the "C" locale.
  • Stage 2: Adjust the representation by converting each char determined by stage 1 to a charT using a conversion and values returned by members of use_­facet<numpunct<charT>>(str.getloc())
  • Stage 3: Determine where padding is required.
  • Stage 4: Insert the sequence into the out.
Detailed descriptions of each stage follow.
Returns: out.
  • Stage 1: The first action of stage 1 is to determine a conversion specifier.
    The tables that describe this determination use the following local variables
    fmtflags flags = str.flags();
    fmtflags basefield =  (flags & (ios_base::basefield));
    fmtflags uppercase =  (flags & (ios_base::uppercase));
    fmtflags floatfield = (flags & (ios_base::floatfield));
    fmtflags showpos =    (flags & (ios_base::showpos));
    fmtflags showbase =   (flags & (ios_base::showbase));
    fmtflags showpoint =  (flags & (ios_base::showpoint));
    All tables used in describing stage 1 are ordered.
    That is, the first line whose condition is true applies.
    A line without a condition is the default behavior when none of the earlier lines apply.
    For conversion from an integral type other than a character type, the function determines the integral conversion specifier as indicated in Table 70.
    Table 70 — Integer conversions
    State
    stdio equivalent
    basefield == ios_­base​::​oct
    %o
    (basefield == ios_­base​::​hex) && !uppercase
    %x
    (basefield == ios_­base​::​hex)
    %X
    for a signed integral type
    %d
    for an unsigned integral type
    %u
    For conversion from a floating-point type, the function determines the floating-point conversion specifier as indicated in Table 71.
    Table 71 — Floating-point conversions
    State
    stdio equivalent
    floatfield == ios_­base​::​fixed
    %f
    floatfield == ios_­base​::​scientific && !uppercase
    %e
    floatfield == ios_­base​::​scientific
    %E
    floatfield == (ios_­base​::​fixed | ios_­base​::​scientific) && !uppercase
    %a
    floatfield == (ios_­base​::​fixed | ios_­base​::​scientific)
    %A
    !uppercase
    %g
    otherwise
    %G
    For conversions from an integral or floating-point type a length modifier is added to the conversion specifier as indicated in Table 72.
    Table 72 — Length modifier
    Type
    Length modifier
    long
    l
    long long
    ll
    unsigned long
    l
    unsigned long long
    ll
    long double
    L
    otherwise
    none
    The conversion specifier has the following optional additional qualifiers prepended as indicated in Table 73.
    Table 73 — Numeric conversions
    Type(s)
    State
    stdio equivalent
    an integral type
    showpos
    +
    showbase
    #
    a floating-point type
    showpos
    +
    showpoint
    #
    For conversion from a floating-point type, if floatfield != (ios_­base​::​fixed | ios_­base​::​​scientific), str.precision() is specified as precision in the conversion specification.
    Otherwise, no precision is specified.
    For conversion from void* the specifier is %p.
    The representations at the end of stage 1 consists of the char's that would be printed by a call of printf(s, val) where s is the conversion specifier determined above.
  • Stage 2: Any character c other than a decimal point(.)
    is converted to a charT via use_­facet<ctype<charT>>(loc).widen( c )A local variable punct is initialized via
    const numpunct<charT>& punct = use_facet<numpunct<charT>>(str.getloc());
    For arithmetic types, punct.thousands_­sep() characters are inserted into the sequence as determined by the value returned by punct.do_­grouping() using the method described in [facet.numpunct.virtuals]Decimal point characters(.)
    are replaced by punct.decimal_­point()
  • Stage 3: A local variable is initialized as
    fmtflags adjustfield = (flags & (ios_base::adjustfield));
    The location of any padding240 is determined according to Table 74.
    Table 74 — Fill padding
    State
    Location
    adjustfield == ios_­base​::​left
    pad after
    adjustfield == ios_­base​::​right
    pad before
    adjustfield == internal and a sign occurs in the representation
    pad after the sign
    adjustfield == internal and representation after stage 1 began with 0x or 0X
    pad after x or X
    otherwise
    pad before
    If str.width() is nonzero and the number of charT's in the sequence after stage 2 is less than str.​width(), then enough fill characters are added to the sequence at the position indicated for padding to bring the length of the sequence to str.width().
    str.width(0) is called.
  • Stage 4: The sequence of charT's at the end of stage 3 are output via
    *out++ = c
iter_type do_put(iter_type out, ios_base& str, char_type fill, bool val) const;
Returns: If (str.flags() & ios_­base​::​boolalpha) == 0 returns do_­put(out, str, fill,
(int)val)
, otherwise obtains a string s as if by
string_type s =
  val ? use_facet<numpunct<charT>>(loc).truename()
      : use_facet<numpunct<charT>>(loc).falsename();
and then inserts each character c of s into out via *out++ = c and returns out.
The conversion specification #o generates a leading 0 which is not a padding character.

25.4.3 The numeric punctuation facet [facet.numpunct]

25.4.3.1 Class template numpunct [locale.numpunct]

namespace std {
  template <class charT>
    class numpunct : public locale::facet {
    public:
      using char_type   = charT;
      using string_type = basic_string<charT>;

      explicit numpunct(size_t refs = 0);

      char_type    decimal_point()   const;
      char_type    thousands_sep()   const;
      string       grouping()        const;
      string_type  truename()        const;
      string_type  falsename()       const;

      static locale::id id;

    protected:
      ~numpunct();                // virtual
      virtual char_type    do_decimal_point() const;
      virtual char_type    do_thousands_sep() const;
      virtual string       do_grouping()      const;
      virtual string_type  do_truename()      const;      // for bool
      virtual string_type  do_falsename()     const;      // for bool
    };
}
numpunct<> specifies numeric punctuation.
The specializations required in Table 64 ([locale.category]), namely numpunct<​wchar_­t> and numpunct<char>, provide classic "C" numeric formats, i.e., they contain information equivalent to that contained in the "C" locale or their wide character counterparts as if obtained by a call to widen.
The syntax for number formats is as follows, where digit represents the radix set specified by the fmtflags argument value, and thousands-sep and decimal-point are the results of corresponding numpunct<charT> members.
Integer values have the format:
integer   ::= [sign] units
sign      ::= plusminus
plusminus ::= '+' | '-'
units     ::= digits [thousands-sep units]
digits    ::= digit [digits]
and floating-point values have:
floatval ::= [sign] units [decimal-point [digits]] [e [sign] digits] |
             [sign]        decimal-point  digits   [e [sign] digits]
e        ::= 'e' | 'E'
where the number of digits between thousands-seps is as specified by do_­grouping().
For parsing, if the digits portion contains no thousands-separators, no grouping constraint is applied.

25.4.3.1.1 numpunct members [facet.numpunct.members]

char_type decimal_point() const;
Returns: do_­decimal_­point().
char_type thousands_sep() const;
Returns: do_­thousands_­sep().
string grouping() const;
Returns: do_­grouping().
string_type truename() const; string_type falsename() const;
Returns: do_­truename() or do_­falsename(), respectively.

25.4.3.1.2 numpunct virtual functions [facet.numpunct.virtuals]

char_type do_decimal_point() const;
Returns: A character for use as the decimal radix separator.
The required specializations return '.' or L'.'.
char_type do_thousands_sep() const;
Returns: A character for use as the digit group separator.
The required specializations return ',' or L','.
string do_grouping() const;
Returns: A basic_string<char> vec used as a vector of integer values, in which each element vec[i] represents the number of digits241 in the group at position i, starting with position 0 as the rightmost group.
If vec.size() <= i, the number is the same as group (i - 1); if (i < 0 || vec[i] <= 0 || vec[i] == CHAR_­MAX), the size of the digit group is unlimited.
The required specializations return the empty string, indicating no grouping.
string_type do_truename() const; string_type do_falsename() const;
Returns: A string representing the name of the boolean value true or false, respectively.
In the base class implementation these names are "true" and "false", or L"true" and L"false".
Thus, the string "\003" specifies groups of 3 digits each, and "3" probably indicates groups of 51 (!) digits each, because 51 is the ASCII value of "3".

25.4.3.2 Class template numpunct_­byname [locale.numpunct.byname]

namespace std {
  template <class charT>
  class numpunct_byname : public numpunct<charT> {
  // this class is specialized for char and wchar_­t.
  public:
    using char_type   = charT;
    using string_type = basic_string<charT>;

    explicit numpunct_byname(const char*, size_t refs = 0);
    explicit numpunct_byname(const string&, size_t refs = 0);
  protected:
    ~numpunct_byname();
  };
}

25.4.4 The collate category [category.collate]

25.4.4.1 Class template collate [locale.collate]

namespace std {
  template <class charT>
    class collate : public locale::facet {
    public:
      using char_type   = charT;
      using string_type = basic_string<charT>;

      explicit collate(size_t refs = 0);

      int compare(const charT* low1, const charT* high1,
                  const charT* low2, const charT* high2) const;
      string_type transform(const charT* low, const charT* high) const;
      long hash(const charT* low, const charT* high) const;

      static locale::id id;

    protected:
      ~collate();
      virtual int do_compare(const charT* low1, const charT* high1,
                             const charT* low2, const charT* high2) const;
      virtual string_type do_transform(const charT* low, const charT* high) const;
      virtual long do_hash (const charT* low, const charT* high) const;
    };
}
The class collate<charT> provides features for use in the collation (comparison) and hashing of strings.
A locale member function template, operator(), uses the collate facet to allow a locale to act directly as the predicate argument for standard algorithms (Clause [algorithms]) and containers operating on strings.
The specializations required in Table 64 ([locale.category]), namely collate<char> and collate<wchar_­t>, apply lexicographic ordering ([alg.lex.comparison]).
Each function compares a string of characters *p in the range [low, high).

25.4.4.1.1 collate members [locale.collate.members]

int compare(const charT* low1, const charT* high1, const charT* low2, const charT* high2) const;
Returns: do_­compare(low1, high1, low2, high2).
string_type transform(const charT* low, const charT* high) const;
Returns: do_­transform(low, high).
long hash(const charT* low, const charT* high) const;
Returns: do_­hash(low, high).

25.4.4.1.2 collate virtual functions [locale.collate.virtuals]

int do_compare(const charT* low1, const charT* high1, const charT* low2, const charT* high2) const;
Returns: 1 if the first string is greater than the second, -1 if less, zero otherwise.
The specializations required in Table 64 ([locale.category]), namely collate<char> and collate<wchar_­t>, implement a lexicographical comparison ([alg.lex.comparison]).
string_type do_transform(const charT* low, const charT* high) const;
Returns: A basic_­string<charT> value that, compared lexicographically with the result of calling transform() on another string, yields the same result as calling do_­compare() on the same two strings.242
long do_hash(const charT* low, const charT* high) const;
Returns: An integer value equal to the result of calling hash() on any other string for which do_­compare() returns 0 (equal) when passed the two strings.
[Note
:
The probability that the result equals that for another string which does not compare equal should be very small, approaching (1.0/numeric_­limits<unsigned long>​::​max()).
end note
]
This function is useful when one string is being compared to many other strings.

25.4.4.2 Class template collate_­byname [locale.collate.byname]

namespace std {
  template <class charT>
    class collate_byname : public collate<charT> {
    public:
      using string_type = basic_string<charT>;

      explicit collate_byname(const char*, size_t refs = 0);
      explicit collate_byname(const string&, size_t refs = 0);
    protected:
      ~collate_byname();
    };
}

25.4.5 The time category [category.time]

Templates time_­get<charT, InputIterator> and time_­put<charT, OutputIterator> provide date and time formatting and parsing.
All specifications of member functions for time_­put and time_­get in the subclauses of [category.time] only apply to the specializations required in Tables 64 and 65 ([locale.category]).
Their members use their ios_­base&, ios_­base​::​iostate&, and fill arguments as described in [locale.categories], and the ctype<> facet, to determine formatting details.

25.4.5.1 Class template time_­get [locale.time.get]

namespace std {
  class time_base {
  public:
    enum dateorder { no_order, dmy, mdy, ymd, ydm };
  };

  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class time_get : public locale::facet, public time_base {
    public:
      using char_type = charT;
      using iter_type = InputIterator;

      explicit time_get(size_t refs = 0);

      dateorder date_order()  const { return do_date_order(); }
      iter_type get_time(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t)  const;
      iter_type get_date(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t)  const;
      iter_type get_weekday(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t) const;
      iter_type get_monthname(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t) const;
      iter_type get_year(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t) const;
      iter_type get(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t, char format, char modifier = 0) const;
      iter_type get(iter_type s, iter_type end, ios_base& f,
                         ios_base::iostate& err, tm* t, const char_type* fmt,
                         const char_type* fmtend) const;

      static locale::id id;

    protected:
      ~time_get();
      virtual dateorder do_date_order()  const;
      virtual iter_type do_get_time(iter_type s, iter_type end, ios_base&,
                                    ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_date(iter_type s, iter_type end, ios_base&,
                                    ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_weekday(iter_type s, iter_type end, ios_base&,
                                       ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_monthname(iter_type s, iter_type end, ios_base&,
                                         ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get_year(iter_type s, iter_type end, ios_base&,
                                    ios_base::iostate& err, tm* t) const;
      virtual iter_type do_get(iter_type s, iter_type end, ios_base& f,
                               ios_base::iostate& err, tm* t, char format, char modifier) const;
    };
}
time_­get is used to parse a character sequence, extracting components of a time or date into a struct tm object.
Each get member parses a format as produced by a corresponding format specifier to time_­put<>​::​put.
If the sequence being parsed matches the correct format, the corresponding members of the struct tm argument are set to the values used to produce the sequence; otherwise either an error is reported or unspecified values are assigned.243
If the end iterator is reached during parsing by any of the get() member functions, the member sets ios_­base​::​eofbit in err.
In other words, user confirmation is required for reliable parsing of user-entered dates and times, but machine-generated formats can be parsed reliably.
This allows parsers to be aggressive about interpreting user variations on standard formats.

25.4.5.1.1 time_­get members [locale.time.get.members]

dateorder date_order() const;
Returns: do_­date_­order().
iter_type get_time(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Returns: do_­get_­time(s, end, str, err, t).
iter_type get_date(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Returns: do_­get_­date(s, end, str, err, t).
iter_type get_weekday(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const; iter_type get_monthname(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Returns: do_­get_­weekday(s, end, str, err, t) or do_­get_­monthname(s, end, str, err, t).
iter_type get_year(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Returns: do_­get_­year(s, end, str, err, t).
iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t, char format, char modifier = 0) const;
Returns: do_­get(s, end, f, err, t, format, modifier).
iter_type get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t, const char_type* fmt, const char_type* fmtend) const;
Requires:[fmt, fmtend) shall be a valid range.
Effects: The function starts by evaluating err = ios_­base​::​goodbit.
It then enters a loop, reading zero or more characters from s at each iteration.
Unless otherwise specified below, the loop terminates when the first of the following conditions holds:
  • The expression fmt == fmtend evaluates to true.
  • The expression err == ios_­base​::​goodbit evaluates to false.
  • The expression s == end evaluates to true, in which case the function evaluates err = ios_­base​::​eofbit | ios_­base​::​failbit.
  • The next element of fmt is equal to '%', optionally followed by a modifier character, followed by a conversion specifier character, format, together forming a conversion specification valid for the ISO/IEC 9945 function strptime.
    If the number of elements in the range [fmt, fmtend) is not sufficient to unambiguously determine whether the conversion specification is complete and valid, the function evaluates err = ios_­base​::​failbit.
    Otherwise, the function evaluates s = do_­get(s, end, f, err, t, format, modifier), where the value of modifier is '\0' when the optional modifier is absent from the conversion specification.
    If err == ios_­base​::​goodbit holds after the evaluation of the expression, the function increments fmt to point just past the end of the conversion specification and continues looping.
  • The expression isspace(*fmt, f.getloc()) evaluates to true, in which case the function first increments fmt until fmt == fmtend || !isspace(*fmt, f.getloc()) evaluates to true, then advances s until s == end || !isspace(*s, f.getloc()) is true, and finally resumes looping.
  • The next character read from s matches the element pointed to by fmt in a case-insensitive comparison, in which case the function evaluates ++fmt, ++s and continues looping.
    Otherwise, the function evaluates err = ios_­base​::​failbit.
[Note
:
The function uses the ctype<charT> facet installed in f's locale to determine valid whitespace characters.
It is unspecified by what means the function performs case-insensitive comparison or whether multi-character sequences are considered while doing so.
end note
]
Returns: s.

25.4.5.1.2 time_­get virtual functions [locale.time.get.virtuals]

dateorder do_date_order() const;
Returns: An enumeration value indicating the preferred order of components for those date formats that are composed of day, month, and year.244
Returns no_­order if the date format specified by 'x' contains other variable components (e.g., Julian day, week number, week day).
iter_type do_get_time(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Effects: Reads characters starting at s until it has extracted those struct tm members, and remaining format characters, used by time_­put<>​::​put to produce the format specified by "%H:%M:%S", or until it encounters an error or end of sequence.
Returns: An iterator pointing immediately beyond the last character recognized as possibly part of a valid time.
iter_type do_get_date(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Effects: Reads characters starting at s until it has extracted those struct tm members and remaining format characters used by time_­put<>​::​put to produce one of the following formats, or until it encounters an error.
The format depends on the value returned by date_­order() as shown in Table 75.
Table 75do_­get_­date effects
date_­order()
Format
no_­order
"%m%d%y"
dmy
"%d%m%y"
mdy
"%m%d%y"
ymd
"%y%m%d"
ydm
"%y%d%m"
An implementation may also accept additional implementation-defined formats.
Returns: An iterator pointing immediately beyond the last character recognized as possibly part of a valid date.
iter_type do_get_weekday(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const; iter_type do_get_monthname(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Effects: Reads characters starting at s until it has extracted the (perhaps abbreviated) name of a weekday or month.
If it finds an abbreviation that is followed by characters that could match a full name, it continues reading until it matches the full name or fails.
It sets the appropriate struct tm member accordingly.
Returns: An iterator pointing immediately beyond the last character recognized as part of a valid name.
iter_type do_get_year(iter_type s, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) const;
Effects: Reads characters starting at s until it has extracted an unambiguous year identifier.
It is implementation-defined whether two-digit year numbers are accepted, and (if so) what century they are assumed to lie in.
Sets the t->tm_­year member accordingly.
Returns: An iterator pointing immediately beyond the last character recognized as part of a valid year identifier.
iter_type do_get(iter_type s, iter_type end, ios_base& f, ios_base::iostate& err, tm* t, char format, char modifier) const;
Requires: t shall point to an object.
Effects: The function starts by evaluating err = ios_­base​::​goodbit.
It then reads characters starting at s until it encounters an error, or until it has extracted and assigned those struct tm members, and any remaining format characters, corresponding to a conversion directive appropriate for the ISO/IEC 9945 function strptime, formed by concatenating '%', the modifier character, when non-NUL, and the format character.
When the concatenation fails to yield a complete valid directive the function leaves the object pointed to by t unchanged and evaluates err |= ios_­base​::​failbit.
When s == end evaluates to true after reading a character the function evaluates err |= ios_­base​::​eofbit.
For complex conversion directives such as %c, %x, or %X, or directives that involve the optional modifiers E or O, when the function is unable to unambiguously determine some or all struct tm members from the input sequence [s, end), it evaluates err |= ios_­base​::​eofbit.
In such cases the values of those struct tm members are unspecified and may be outside their valid range.
Remarks: It is unspecified whether multiple calls to do_­get() with the address of the same struct tm object will update the current contents of the object or simply overwrite its members.
Portable programs must zero out the object before invoking the function.
Returns: An iterator pointing immediately beyond the last character recognized as possibly part of a valid input sequence for the given format and modifier.
This function is intended as a convenience only, for common formats, and may return no_­order in valid locales.

25.4.5.2 Class template time_­get_­byname [locale.time.get.byname]

namespace std {
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
  class time_get_byname : public time_get<charT, InputIterator> {
  public:
    using dateorder = time_base::dateorder;
    using iter_type = InputIterator;

    explicit time_get_byname(const char*, size_t refs = 0);
    explicit time_get_byname(const string&, size_t refs = 0);
  protected:
    ~time_get_byname();
  };
}

25.4.5.3 Class template time_­put [locale.time.put]

namespace std {
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class time_put : public locale::facet {
    public:
      using char_type = charT;
      using iter_type = OutputIterator;

      explicit time_put(size_t refs = 0);

      // the following is implemented in terms of other member functions.
      iter_type put(iter_type s, ios_base& f, char_type fill, const tm* tmb,
                    const charT* pattern, const charT* pat_end) const;
      iter_type put(iter_type s, ios_base& f, char_type fill,
                    const tm* tmb, char format, char modifier = 0) const;

      static locale::id id;

    protected:
      ~time_put();
      virtual iter_type do_put(iter_type s, ios_base&, char_type, const tm* t,
                               char format, char modifier) const;
    };
}

25.4.5.3.1 time_­put members [locale.time.put.members]

iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t, const charT* pattern, const charT* pat_end) const; iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t, char format, char modifier = 0) const;
Effects: The first form steps through the sequence from pattern to pat_­end, identifying characters that are part of a format sequence.
Each character that is not part of a format sequence is written to s immediately, and each format sequence, as it is identified, results in a call to do_­put; thus, format elements and other characters are interleaved in the output in the order in which they appear in the pattern.
Format sequences are identified by converting each character c to a char value as if by ct.narrow(c, 0), where ct is a reference to ctype<charT> obtained from str.getloc().
The first character of each sequence is equal to '%', followed by an optional modifier character mod245 and a format specifier character spec as defined for the function strftime.
If no modifier character is present, mod is zero.
For each valid format sequence identified, calls do_­put(s, str, fill, t, spec, mod).
The second form calls do_­put(s, str, fill, t, format, modifier).
[Note
:
The fill argument may be used in the implementation-defined formats or by derivations.
A space character is a reasonable default for this argument.
end note
]
Returns: An iterator pointing immediately after the last character produced.
Although the C programming language defines no modifiers, most vendors do.

25.4.5.3.2 time_­put virtual functions [locale.time.put.virtuals]

iter_type do_put(iter_type s, ios_base&, char_type fill, const tm* t, char format, char modifier) const;
Effects: Formats the contents of the parameter t into characters placed on the output sequence s.
Formatting is controlled by the parameters format and modifier, interpreted identically as the format specifiers in the string argument to the standard library function strftime()246, except that the sequence of characters produced for those specifiers that are described as depending on the C locale are instead implementation-defined.247
Returns: An iterator pointing immediately after the last character produced.
[Note
:
The fill argument may be used in the implementation-defined formats or by derivations.
A space character is a reasonable default for this argument.
end note
]
Interpretation of the modifier argument is implementation-defined, but should follow POSIX conventions.
Implementations are encouraged to refer to other standards such as POSIX for these definitions.

25.4.5.4 Class template time_­put_­byname [locale.time.put.byname]

namespace std {
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
  class time_put_byname : public time_put<charT, OutputIterator>
  {
  public:
    using char_type = charT;
    using iter_type = OutputIterator;

    explicit time_put_byname(const char*, size_t refs = 0);
    explicit time_put_byname(const string&, size_t refs = 0);
  protected:
    ~time_put_byname();
  };
}

25.4.6 The monetary category [category.monetary]

These templates handle monetary formats.
A template parameter indicates whether local or international monetary formats are to be used.
All specifications of member functions for money_­put and money_­get in the subclauses of [category.monetary] only apply to the specializations required in Tables 64 and 65 ([locale.category]).
Their members use their ios_­base&, ios_­base​::​iostate&, and fill arguments as described in [locale.categories], and the moneypunct<> and ctype<> facets, to determine formatting details.

25.4.6.1 Class template money_­get [locale.money.get]

namespace std {
  template <class charT, class InputIterator = istreambuf_iterator<charT>>
    class money_get : public locale::facet {
    public:
      using char_type   = charT;
      using iter_type   = InputIterator;
      using string_type = basic_string<charT>;

      explicit money_get(size_t refs = 0);

      iter_type get(iter_type s, iter_type end, bool intl,
                    ios_base& f, ios_base::iostate& err,
                    long double& units) const;
      iter_type get(iter_type s, iter_type end, bool intl,
                    ios_base& f, ios_base::iostate& err,
                    string_type& digits) const;

      static locale::id id;

    protected:
      ~money_get();
      virtual iter_type do_get(iter_type, iter_type, bool, ios_base&,
                               ios_base::iostate& err, long double& units) const;
      virtual iter_type do_get(iter_type, iter_type, bool, ios_base&,
                               ios_base::iostate& err, string_type& digits) const;
    };
}

25.4.6.1.1 money_­get members [locale.money.get.members]

iter_type get(iter_type s, iter_type end, bool intl, ios_base& f, ios_base::iostate& err, long double& quant) const; iter_type get(s, iter_type end, bool intl, ios_base&f, ios_base::iostate& err, string_type& quant) const;
Returns: do_­get(s, end, intl, f, err, quant).

25.4.6.1.2 money_­get virtual functions [locale.money.get.virtuals]

iter_type do_get(iter_type s, iter_type end, bool intl, ios_base& str, ios_base::iostate& err, long double& units) const; iter_type do_get(iter_type s, iter_type end, bool intl, ios_base& str, ios_base::iostate& err, string_type& digits) const;
Effects: Reads characters from s to parse and construct a monetary value according to the format specified by a moneypunct<charT, Intl> facet reference mp and the character mapping specified by a ctype<charT> facet reference ct obtained from the locale returned by str.getloc(), and str.flags().
If a valid sequence is recognized, does not change err; otherwise, sets err to (err|str.failbit), or (err|str.failbit|str.eofbit) if no more characters are available, and does not change units or digits.
Uses the pattern returned by mp.neg_­format() to parse all values.
The result is returned as an integral value stored in units or as a sequence of digits possibly preceded by a minus sign (as produced by ct.widen(c) where c is '-' or in the range from '0' through '9', inclusive) stored in digits.
[Example
:
The sequence $1,056.23 in a common United States locale would yield, for units, 105623, or, for digits, "105623".
end example
]
If mp.grouping() indicates that no thousands separators are permitted, any such characters are not read, and parsing is terminated at the point where they first appear.
Otherwise, thousands separators are optional; if present, they are checked for correct placement only after all format components have been read.
Where money_­base​::​space or money_­base​::​none appears as the last element in the format pattern, no white space is consumed.
Otherwise, where money_­base​::​space appears in any of the initial elements of the format pattern, at least one white space character is required.
Where money_­base​::​none appears in any of the initial elements of the format pattern, white space is allowed but not required.
If (str.flags() & str.showbase) is false, the currency symbol is optional and is consumed only if other characters are needed to complete the format; otherwise, the currency symbol is required.
If the first character (if any) in the string pos returned by mp.positive_­sign() or the string neg returned by mp.negative_­sign() is recognized in the position indicated by sign in the format pattern, it is consumed and any remaining characters in the string are required after all the other format components.
[Example
:
If showbase is off, then for a neg value of "()" and a currency symbol of "L", in "(100 L)" the "L" is consumed; but if neg is "-", the "L" in "-100 L" is not consumed.
end example
]
If pos or neg is empty, the sign component is optional, and if no sign is detected, the result is given the sign that corresponds to the source of the empty string.
Otherwise, the character in the indicated position must match the first character of pos or neg, and the result is given the corresponding sign.
If the first character of pos is equal to the first character of neg, or if both strings are empty, the result is given a positive sign.
Digits in the numeric monetary component are extracted and placed in digits, or into a character buffer buf1 for conversion to produce a value for units, in the order in which they appear, preceded by a minus sign if and only if the result is negative.
The value units is produced as if by248
for (int i = 0; i < n; ++i)
  buf2[i] = src[find(atoms, atoms+sizeof(src), buf1[i]) - atoms];
buf2[n] = 0;
sscanf(buf2, "%Lf", &units);
where n is the number of characters placed in buf1, buf2 is a character buffer, and the values src and atoms are defined as if by
static const char src[] = "0123456789-";
charT atoms[sizeof(src)];
ct.widen(src, src + sizeof(src) - 1, atoms);
Returns: An iterator pointing immediately beyond the last character recognized as part of a valid monetary quantity.
The semantics here are different from ct.narrow.

25.4.6.2 Class template money_­put [locale.money.put]

namespace std {
  template <class charT, class OutputIterator = ostreambuf_iterator<charT>>
    class money_put : public locale::facet {
    public:
      using char_type   = charT;
      using iter_type   = OutputIterator;
      using string_type = basic_string<charT>;

      explicit money_put(size_t refs = 0);

      iter_type put(iter_type s, bool intl, ios_base& f,
                    char_type fill, long double units) const;
      iter_type put(iter_type s, bool intl, ios_base& f,
                    char_type fill, const string_type& digits) const;

      static locale::id id;

    protected:
      ~money_put();
      virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill,
                               long double units) const;
      virtual iter_type do_put(iter_type, bool, ios_base&, char_type fill,
                               const string_type& digits) const;
    };
}

25.4.6.2.1 money_­put members [locale.money.put.members]

iter_type put(iter_type s, bool intl, ios_base& f, char_type fill, long double quant) const; iter_type put(iter_type s, bool intl, ios_base& f, char_type fill, const string_type& quant) const;
Returns: do_­put(s, intl, f, loc, quant).

25.4.6.2.2 money_­put virtual functions [locale.money.put.virtuals]

iter_type do_put(iter_type s, bool intl, ios_base& str, char_type fill, long double units) const; iter_type do_put(iter_type s, bool intl, ios_base& str, char_type fill, const string_type& digits) const;
Effects: Writes characters to s according to the format specified by a moneypunct<charT, Intl> facet reference mp and the character mapping specified by a ctype<charT> facet reference ct obtained from the locale returned by str.getloc(), and str.flags().
The argument units is transformed into a sequence of wide characters as if by
ct.widen(buf1, buf1 + sprintf(buf1, "%.0Lf", units), buf2)
for character buffers buf1 and buf2.
If the first character in digits or buf2 is equal to ct.widen('-'), then the pattern used for formatting is the result of mp.neg_­format(); otherwise the pattern is the result of mp.pos_­format().
Digit characters are written, interspersed with any thousands separators and decimal point specified by the format, in the order they appear (after the optional leading minus sign) in digits or buf2.
In digits, only the optional leading minus sign and the immediately subsequent digit characters (as classified according to ct) are used; any trailing characters (including digits appearing after a non-digit character) are ignored.
Calls str.width(0).
Remarks: The currency symbol is generated if and only if (str.flags() & str.showbase) is nonzero.
If the number of characters generated for the specified format is less than the value returned by str.width() on entry to the function, then copies of fill are inserted as necessary to pad to the specified width.
For the value af equal to (str.flags() & str.adjustfield), if (af == str.internal) is true, the fill characters are placed where none or space appears in the formatting pattern; otherwise if (af == str.left) is true, they are placed after the other characters; otherwise, they are placed before the other characters.
[Note
:
It is possible, with some combinations of format patterns and flag values, to produce output that cannot be parsed using num_­get<>​::​get.
end note
]
Returns: An iterator pointing immediately after the last character produced.

25.4.6.3 Class template moneypunct [locale.moneypunct]

namespace std {
  class money_base {
  public:
    enum part { none, space, symbol, sign, value };
    struct pattern { char field[4]; };
  };

  template <class charT, bool International = false>
    class moneypunct : public locale::facet, public money_base {
    public:
      using char_type   = charT;
      using string_type = basic_string<charT>;

      explicit moneypunct(size_t refs = 0);

      charT        decimal_point() const;
      charT        thousands_sep() const;
      string       grouping()      const;
      string_type  curr_symbol()   const;
      string_type  positive_sign() const;
      string_type  negative_sign() const;
      int          frac_digits()   const;
      pattern      pos_format()    const;
      pattern      neg_format()    const;

      static locale::id id;
      static const bool intl = International;

    protected:
      ~moneypunct();
      virtual charT        do_decimal_point() const;
      virtual charT        do_thousands_sep() const;
      virtual string       do_grouping()      const;
      virtual string_type  do_curr_symbol()   const;
      virtual string_type  do_positive_sign() const;
      virtual string_type  do_negative_sign() const;
      virtual int          do_frac_digits()   const;
      virtual pattern      do_pos_format()    const;
      virtual pattern      do_neg_format()    const;
    };
}
The moneypunct<> facet defines monetary formatting parameters used by money_­get<> and money_­put<>.
A monetary format is a sequence of four components, specified by a pattern value p, such that the part value static_­cast<part>(p.field[i]) determines the ith component of the format249 In the field member of a pattern object, each value symbol, sign, value, and either space or none appears exactly once.
The value none, if present, is not first; the value space, if present, is neither first nor last.
Where none or space appears, white space is permitted in the format, except where none appears at the end, in which case no white space is permitted.
The value space indicates that at least one space is required at that position.
Where symbol appears, the sequence of characters returned by curr_­symbol() is permitted, and can be required.
Where sign appears, the first (if any) of the sequence of characters returned by positive_­sign() or negative_­sign() (respectively as the monetary value is non-negative or negative) is required.
Any remaining characters of the sign sequence are required after all other format components.
Where value appears, the absolute numeric monetary value is required.
The format of the numeric monetary value is a decimal number:
value ::= units [ decimal-point [ digits ]] |
  decimal-point digits
if frac_­digits() returns a positive value, or
value ::= units
otherwise.
The symbol decimal-point indicates the character returned by decimal_­point().
The other symbols are defined as follows:
units ::= digits [ thousands-sep units ]
digits ::= adigit [ digits ]
In the syntax specification, the symbol adigit is any of the values ct.widen(c) for c in the range '0' through '9', inclusive, and ct is a reference of type const ctype<charT>& obtained as described in the definitions of money_­get<> and money_­put<>.
The symbol thousands-sep is the character returned by thousands_­sep().
The space character used is the value ct.widen(' ').
White space characters are those characters c for which ci.is(space, c) returns true.
The number of digits required after the decimal point (if any) is exactly the value returned by frac_­digits().
The placement of thousands-separator characters (if any) is determined by the value returned by grouping(), defined identically as the member numpunct<>​::​do_­grouping().
An array of char, rather than an array of part, is specified for pattern​::​field purely for efficiency.

25.4.6.3.1 moneypunct members [locale.moneypunct.members]

charT        decimal_point() const;
charT        thousands_sep() const;
string       grouping()      const;
string_type  curr_symbol()   const;
string_type  positive_sign() const;
string_type  negative_sign() const;
int          frac_digits()   const;
pattern      pos_format()    const;
pattern      neg_format()    const;
Each of these functions F returns the result of calling the corresponding virtual member function do_­F().

25.4.6.3.2 moneypunct virtual functions [locale.moneypunct.virtuals]

charT do_decimal_point() const;
Returns: The radix separator to use in case do_­frac_­digits() is greater than zero.250
charT do_thousands_sep() const;
Returns: The digit group separator to use in case do_­grouping() specifies a digit grouping pattern.251
string do_grouping() const;
Returns: A pattern defined identically as, but not necessarily equal to, the result of numpunct<charT>​::​​do_­grouping().252
string_type do_curr_symbol() const;
Returns: A string to use as the currency identifier symbol.253
string_type do_positive_sign() const; string_type do_negative_sign() const;
Returns: do_­positive_­sign() returns the string to use to indicate a positive monetary value;254 do_­negative_­sign() returns the string to use to indicate a negative value.
int do_frac_digits() const;
Returns: The number of digits after the decimal radix separator, if any.255
pattern do_pos_format() const; pattern do_neg_format() const;
Returns: The specializations required in Table 65 ([locale.category]), namely moneypunct<char>, moneypunct<​wchar_­t>, moneypunct<char, true>, and moneypunct<wchar_­t, true>, return an object of type pattern initialized to { symbol, sign, none, value }.256
In common U.
S.
locales this is '.'.
In common U.
S.
locales this is ','.
To specify grouping by 3s, the value is "\003" not "3".
For international specializations (second template parameter true) this is typically four characters long, usually three letters and a space.
This is usually the empty string.
In common U.
S.
 locales, this is 2.
Note that the international symbol returned by do_­curr_­sym() usually contains a space, itself; for example, "USD ".

25.4.6.4 Class template moneypunct_­byname [locale.moneypunct.byname]

namespace std {
  template <class charT, bool Intl = false>
  class moneypunct_byname : public moneypunct<charT, Intl> {
  public:
    using pattern     = money_base::pattern;
    using string_type = basic_string<charT>;

    explicit moneypunct_byname(const char*, size_t refs = 0);
    explicit moneypunct_byname(const string&, size_t refs = 0);
  protected:
    ~moneypunct_byname();
  };
}

25.4.7 The message retrieval category [category.messages]

Class messages<charT> implements retrieval of strings from message catalogs.

25.4.7.1 Class template messages [locale.messages]

namespace std {
  class messages_base {
  public:
    using catalog = unspecified signed integer type;
  };

  template <class charT>
    class messages : public locale::facet, public messages_base {
    public:
      using char_type   = charT;
      using string_type = basic_string<charT>;

      explicit messages(size_t refs = 0);

      catalog open(const basic_string<char>& fn, const locale&) const;
      string_type get(catalog c, int set, int msgid,
                       const string_type& dfault) const;
      void close(catalog c) const;

      static locale::id id;

    protected:
      ~messages();
      virtual catalog do_open(const basic_string<char>&, const locale&) const;
      virtual string_type do_get(catalog, int set, int msgid,
                                 const string_type& dfault) const;
      virtual void do_close(catalog) const;
    };
}
Values of type messages_­base​::​catalog usable as arguments to members get and close can be obtained only by calling member open.

25.4.7.1.1 messages members [locale.messages.members]

catalog open(const basic_string<char>& name, const locale& loc) const;
Returns: do_­open(name, loc).
string_type get(catalog cat, int set, int msgid, const string_type& dfault) const;
Returns: do_­get(cat, set, msgid, dfault).
void close(catalog cat) const;
Effects: Calls do_­close(cat).

25.4.7.1.2 messages virtual functions [locale.messages.virtuals]

catalog do_open(const basic_string<char>& name, const locale& loc) const;
Returns: A value that may be passed to get() to retrieve a message from the message catalog identified by the string name according to an implementation-defined mapping.
The result can be used until it is passed to close().
Returns a value less than 0 if no such catalog can be opened.
Remarks: The locale argument loc is used for character set code conversion when retrieving messages, if needed.
string_type do_get(catalog cat, int set, int msgid, const string_type& dfault) const;
Requires: cat shall be a catalog obtained from open() and not yet closed.
Returns: A message identified by arguments set, msgid, and dfault, according to an implementation-defined mapping.
If no such message can be found, returns dfault.
void do_close(catalog cat) const;
Requires: cat shall be a catalog obtained from open() and not yet closed.
Effects: Releases unspecified resources associated with cat.
Remarks: The limit on such resources, if any, is implementation-defined.

25.4.7.2 Class template messages_­byname [locale.messages.byname]

namespace std {
  template <class charT>
  class messages_byname : public messages<charT> {
  public:
    using catalog     = messages_base::catalog;
    using string_type = basic_string<charT>;

    explicit messages_byname(const char*, size_t refs = 0);
    explicit messages_byname(const string&, size_t refs = 0);
  protected:
    ~messages_byname();
  };
}

25.4.8 Program-defined facets [facets.examples]

A C++ program may define facets to be added to a locale and used identically as the built-in facets.
To create a new facet interface, C++ programs simply derive from locale​::​facet a class containing a static member: static locale​::​id id.
[Note
:
The locale member function templates verify its type and storage class.
end note
]
[Example
:
Traditional global localization is still easy:
#include <iostream>
#include <locale>
int main(int argc, char** argv) {
  using namespace std;
  locale::global(locale(""));           // set the global locale
                                        // imbue it on all the std streams
  cin.imbue(locale());
  cout.imbue(locale());
  cerr.imbue(locale());
  wcin.imbue(locale());
  wcout.imbue(locale());
  wcerr.imbue(locale());

  return MyObject(argc, argv).doit();
}
end example
]
[Example
:
Greater flexibility is possible:
#include <iostream>
#include <locale>
int main() {
  using namespace std;
  cin.imbue(locale(""));        // the user's preferred locale
  cout.imbue(locale::classic());
  double f;
  while (cin >> f) cout << f << endl;
  return (cin.fail() != 0);
}
In a European locale, with input 3.456,78, output is 3456.78.
end example
]
This can be important even for simple programs, which may need to write a data file in a fixed format, regardless of a user's preference.
[Example
:
Here is an example of the use of locales in a library interface.
// file: Date.h
#include <iosfwd>
#include <string>
#include <locale>

class Date {
public:
  Date(unsigned day, unsigned month, unsigned year);
  std::string asString(const std::locale& = std::locale());
};

std::istream& operator>>(std::istream& s, Date& d);
std::ostream& operator<<(std::ostream& s, Date d);
locales.tex5146This example illustrates two architectural uses of class locale.
locales.tex5150The first is as a default argument in Date​::​asString(), where the default is the global (presumably user-preferred) locale.
locales.tex5156The second is in the operators << and >>, where a locale “hitchhikes” on another object, in this case a stream, to the point where it is needed.
// file: Date.C
#include "Date"                 // includes <ctime>
#include <sstream>
std::string Date::asString(const std::locale& l) {
  using namespace std;
  ostringstream s; s.imbue(l);
  s << *this; return s.str();
}

std::istream& operator>>(std::istream& s, Date& d) {
  using namespace std;
  istream::sentry cerberos(s);
  if (cerberos) {
    ios_base::iostate err = goodbit;
    struct tm t;
    use_facet<time_get<char>>(s.getloc()).get_date(s, 0, s, err, &t);
    if (!err) d = Date(t.tm_day, t.tm_mon + 1, t.tm_year + 1900);
    s.setstate(err);
  }
  return s;
}
end example
]
A locale object may be extended with a new facet simply by constructing it with an instance of a class derived from locale​::​facet.
The only member a C++ program must define is the static member id, which identifies your class interface as a new facet.
[Example
:
Classifying Japanese characters:
// file: <jctype>
#include <locale>
namespace My {
  using namespace std;
  class JCtype : public locale::facet {
  public:
    static locale::id id;       // required for use as a new locale facet
    bool is_kanji (wchar_t c) const;
    JCtype() { }
  protected:
    ~JCtype() { }
  };
}

// file: filt.C
#include <iostream>
#include <locale>
#include "jctype"               // above
std::locale::id My::JCtype::id; // the static JCtype member declared above.

int main() {
  using namespace std;
  using wctype = ctype<wchar_t>;
  locale loc(locale(""),        // the user's preferred locale ...
         new My::JCtype);       // and a new feature ...
  wchar_t c = use_facet<wctype>(loc).widen('!');
  if (!use_facet<My::JCtype>(loc).is_kanji(c))
    cout << "no it isn't!" << endl;
}
locales.tex5232The new facet is used exactly like the built-in facets.
end example
]
[Example
:
Replacing an existing facet is even easier.
The code does not define a member id because it is reusing the numpunct<charT> facet interface:
// file: my_­bool.C
#include <iostream>
#include <locale>
#include <string>
namespace My {
  using namespace std;
  using cnumpunct = numpunct_byname<char>;
  class BoolNames : public cnumpunct {
  protected:
    string do_truename()  const { return "Oui Oui!"; }
    string do_falsename() const { return "Mais Non!"; }
    ~BoolNames() { }
  public:
    BoolNames(const char* name) : cnumpunct(name) { }
  };
}

int main(int argc, char** argv) {
  using namespace std;
  // make the user's preferred locale, except for...
  locale loc(locale(""), new My::BoolNames(""));
  cout.imbue(loc);
  cout << boolalpha << "Any arguments today? " << (argc > 1) << endl;
}
end example
]

25.5 C library locales [c.locales]

25.5.1 Header <clocale> synopsis [clocale.syn]

namespace std {
  struct lconv;

  char* setlocale(int category, const char* locale);
  lconv* localeconv();
}

#define NULL see [support.types.nullptr]
#define LC_ALL see below
#define LC_COLLATE see below
#define LC_CTYPE see below
#define LC_MONETARY see below
#define LC_NUMERIC see below
#define LC_TIME see below
The contents and meaning of the header <clocale> are the same as the C standard library header <locale.h>.
Calls to the function setlocale may introduce a data race ([res.on.data.races]) with other calls to setlocale or with calls to the functions listed in Table 76.
See also: ISO C 7.
11.
Table 76 — Potential setlocale data races
fprintf
isprint
iswdigit
localeconv
tolower
fscanf
ispunct
iswgraph
mblen
toupper
isalnum
isspace
iswlower
mbstowcs
towlower
isalpha
isupper
iswprint
mbtowc
towupper
isblank
iswalnum
iswpunct
setlocale
wcscoll
iscntrl
iswalpha
iswspace
strcoll
wcstod
isdigit
iswblank
iswupper
strerror
wcstombs
isgraph
iswcntrl
iswxdigit
strtod
wcsxfrm
islower
iswctype
isxdigit
strxfrm
wctomb

26 Containers library [containers]

26.1 General [containers.general]

This Clause describes components that C++ programs may use to organize collections of information.
The following subclauses describe container requirements, and components for sequence containers and associative containers, as summarized in Table 77.
Table 77 — Containers library summary
Subclause
Header(s)
Requirements
Sequence containers
<array>
<deque>
<forward_­list>
<list>
<vector>
Associative containers
<map>
<set>
Unordered associative containers
<unordered_­map>
<unordered_­set>
Container adaptors
<queue>
<stack>

26.2 Container requirements [container.requirements]

26.2.1 General container requirements [container.requirements.general]

Containers are objects that store other objects.
They control allocation and deallocation of these objects through constructors, destructors, insert and erase operations.
All of the complexity requirements in this Clause are stated solely in terms of the number of operations on the contained objects.
[Example
:
The copy constructor of type vector<vector<int>> has linear complexity, even though the complexity of copying each contained vector<int> is itself linear.
end example
]
For the components affected by this subclause that declare an allocator_­type, objects stored in these components shall be constructed using the function allocator_­traits<allocator_­type>​::​rebind_­traits<U>​::​​construct and destroyed using the function allocator_­traits<allocator_­type>​::​rebind_­traits<U>​::​​destroy ([allocator.traits.members]), where U is either allocator_­type​::​value_­type or an internal type used by the container.
These functions are called only for the container's element type, not for internal types used by the container.
[Note
:
This means, for example, that a node-based container might need to construct nodes containing aligned buffers and call construct to place the element into the buffer.
end note
]
In Tables 78, 79, and 80 X denotes a container class containing objects of type T, a and b denote values of type X, u denotes an identifier, r denotes a non-const value of type X, and rv denotes a non-const rvalue of type X.
Table 78 — Container requirements
Expression
Return type
Operational
Assertion/note
Complexity
semantics
pre-/post-condition
X​::​value_­type
T
Requires: T is Erasable from X (see [container.requirements.general], below)
compile time
X​::​reference
T&
compile time
X​::​const_­reference
const T&
compile time
X​::​iterator
iterator type whose value type is T
any iterator category that meets the forward iterator requirements.
convertible to X​::​const_­iterator.
compile time
X​::​const_­iterator
constant iterator type whose value type is T
any iterator category that meets the forward iterator requirements.
compile time
X​::​difference_­type
signed integer type
is identical to the difference type of X​::​iterator and X​::​const_­iterator
compile time
X​::​size_­type
unsigned integer type
size_­type can represent any non-negative value of difference_­type
compile time
X u;
Postconditions: u.empty()
constant
X()
Postconditions: X().empty()
constant
X(a)
Requires: T is CopyInsertable into X (see below).

Postconditions: a == X(a).
linear
X u(a);
X u = a;
Requires: T is CopyInsertable into X (see below).

Postconditions: u == a
linear
X u(rv);
X u = rv;
Postconditions: u shall be equal to the value that rv had before this construction
(Note B)
a = rv
X&
All existing elements of a are either move assigned to or destroyed
a shall be equal to the value that rv had before this assignment
linear
(&a)->~X()
void
the destructor is applied to every element of a; any memory obtained is deallocated.
linear
a.begin()
iterator; const_­iterator for constant a
constant
a.end()
iterator; const_­iterator for constant a
constant
a.cbegin()
const_­iterator
const_­cast<​X const&​>(a)​.begin();
constant
a.cend()
const_­iterator
const_­cast<​X const&​>(a)​.end();
constant
a == b
convertible to bool
== is an equivalence relation.
equal(​a.begin(), a.end(), b.begin(), b.end())
Requires: T is EqualityComparable
Constant if a.size() != b.size(), linear otherwise
a != b
convertible to bool
Equivalent to !(a == b)
linear
a.swap(b)
void
exchanges the contents of a and b
(Note A)
swap(a, b)
void
a.swap(b)
(Note A)
r = a
X&
Postconditions: r == a.
linear
a.size()
size_­type
distance(​a.begin(), a.end())
constant
a.max_­size()
size_­type
distance(​begin(), end()) for the largest possible container
constant
a.empty()
convertible to bool
a.begin() == a.end()
constant
Those entries marked “(Note A)” or “(Note B)” have linear complexity for array and have constant complexity for all other standard containers.
[Note
:
The algorithm equal() is defined in Clause [algorithms].
end note
]
The member function size() returns the number of elements in the container.
The number of elements is defined by the rules of constructors, inserts, and erases.
begin() returns an iterator referring to the first element in the container.
end() returns an iterator which is the past-the-end value for the container.
If the container is empty, then begin() == end().
In the expressions
i == j
i != j
i < j
i <= j
i >= j
i > j
i - j
where i and j denote objects of a container's iterator type, either or both may be replaced by an object of the container's const_­iterator type referring to the same element with no change in semantics.
Unless otherwise specified, all containers defined in this clause obtain memory using an allocator (see [allocator.requirements]).
[Note
:
In particular, containers and iterators do not store references to allocated elements other than through the allocator's pointer type, i.e., as objects of type P or pointer_­traits<P>​::​template rebind<unspecified>, where P is allocator_­traits<allocator_­type>​::​pointer.
end note
]
Copy constructors for these container types obtain an allocator by calling allocator_­traits<allocator_­type>​::​select_­on_­container_­copy_­construction on the allocator belonging to the container being copied.
Move constructors obtain an allocator by move construction from the allocator belonging to the container being moved.
Such move construction of the allocator shall not exit via an exception.
All other constructors for these container types take a const allocator_­type& argument.
[Note
:
If an invocation of a constructor uses the default value of an optional allocator argument, then the Allocator type must support value-initialization.
end note
]
A copy of this allocator is used for any memory allocation and element construction performed, by these constructors and by all member functions, during the lifetime of each container object or until the allocator is replaced.
The allocator may be replaced only via assignment or swap().
Allocator replacement is performed by copy assignment, move assignment, or swapping of the allocator only if allocator_­traits<allocator_­type>​::​propagate_­on_­container_­copy_­assignment​::​value, allocator_­traits<allocator_­type>​::​propagate_­on_­container_­move_­assignment​::​value, or allocator_­traits<allocator_­type>​::​propagate_­on_­container_­swap​::​value is true within the implementation of the corresponding container operation.
In all container types defined in this Clause, the member get_­allocator() returns a copy of the allocator used to construct the container or, if that allocator has been replaced, a copy of the most recent replacement.
The expression a.swap(b), for containers a and b of a standard container type other than array, shall exchange the values of a and b without invoking any move, copy, or swap operations on the individual container elements.
Lvalues of any Compare, Pred, or Hash types belonging to a and b shall be swappable and shall be exchanged by calling swap as described in [swappable.requirements].
If allocator_­traits<allocator_­type>​::​propagate_­on_­container_­swap​::​value is true, then lvalues of type allocator_­type shall be swappable and the allocators of a and b shall also be exchanged by calling swap as described in [swappable.requirements].
Otherwise, the allocators shall not be swapped, and the behavior is undefined unless a.get_­allocator() == b.get_­allocator().
Every iterator referring to an element in one container before the swap shall refer to the same element in the other container after the swap.
It is unspecified whether an iterator with value a.end() before the swap will have value b.end() after the swap.
If the iterator type of a container belongs to the bidirectional or random access iterator categories ([iterator.requirements]), the container is called reversible and satisfies the additional requirements in Table 79.
Table 79 — Reversible container requirements
Expression
Return type
Assertion/note
Complexity
pre-/post-condition
X​::​reverse_­iterator
iterator type whose value type is T
reverse_­iterator<iterator>
compile time
X​::​const_­reverse_­iterator
constant iterator type whose value type is T
reverse_­iterator<const_­iterator>
compile time
a.rbegin()
reverse_­iterator; const_­reverse_­iterator for constant a
reverse_­iterator(end())
constant
a.rend()
reverse_­iterator; const_­reverse_­iterator for constant a
reverse_­iterator(begin())
constant
a.crbegin()
const_­reverse_­iterator
const_­cast<X const&>(a).rbegin()
constant
a.crend()
const_­reverse_­iterator
const_­cast<X const&>(a).rend()
constant
Unless otherwise specified (see [associative.reqmts.except], [unord.req.except], [deque.modifiers], and [vector.modifiers]) all container types defined in this Clause meet the following additional requirements:
  • if an exception is thrown by an insert() or emplace() function while inserting a single element, that function has no effects.
  • if an exception is thrown by a push_­back(), push_­front(), emplace_­back(), or emplace_­front() function, that function has no effects.
  • no erase(), clear(), pop_­back() or pop_­front() function throws an exception.
  • no copy constructor or assignment operator of a returned iterator throws an exception.
  • no swap() function throws an exception.
  • no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped.
    [Note
    :
    The end() iterator does not refer to any element, so it may be invalidated.
    end note
    ]
Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.
A contiguous container is a container that supports random access iterators ([random.access.iterators]) and whose member types iterator and const_­iterator are contiguous iterators ([iterator.requirements.general]).
Table 80 lists operations that are provided for some types of containers but not others.
Those containers for which the listed operations are provided shall implement the semantics described in Table 80 unless otherwise stated.
Table 80 — Optional container operations
Expression
Return type
Operational
Assertion/note
Complexity
semantics
pre-/post-condition
a < b
convertible to bool
lexicographical_­compare( a.begin(), a.end(), b.begin(), b.end())
Requires:< is defined for values of T.
< is a total ordering relationship.
linear
a > b
convertible to bool
b < a
linear
a <= b
convertible to bool
!(a > b)
linear
a >= b
convertible to bool
!(a < b)
linear
[Note
:
The algorithm lexicographical_­compare() is defined in Clause [algorithms].
end note
]
All of the containers defined in this Clause and in [basic.string] except array meet the additional requirements of an allocator-aware container, as described in Table 81.
Given an allocator type A and given a container type X having a value_­type identical to T and an allocator_­type identical to allocator_­traits<A>​::​rebind_­alloc<T> and given an lvalue m of type A, a pointer p of type T*, an expression v of type (possibly const) T, and an rvalue rv of type T, the following terms are defined.
If X is not allocator-aware, the terms below are defined as if A were allocator<T> — no allocator object needs to be created and user specializations of allocator<T> are not instantiated:
  • T is DefaultInsertable into X means that the following expression is well-formed:
    allocator_traits<A>::construct(m, p)
  • An element of X is default-inserted if it is initialized by evaluation of the expression
    allocator_traits<A>::construct(m, p)
    where p is the address of the uninitialized storage for the element allocated within X.
  • T is MoveInsertable into X means that the following expression is well-formed:
    allocator_traits<A>::construct(m, p, rv)
    and its evaluation causes the following postcondition to hold: The value of *p is equivalent to the value of rv before the evaluation.
    [Note
    :
    rv remains a valid object.
    Its state is unspecified
    end note
    ]
  • T is CopyInsertable into X means that, in addition to T being MoveInsertable into X, the following expression is well-formed:
    allocator_traits<A>::construct(m, p, v)
    and its evaluation causes the following postcondition to hold: The value of v is unchanged and is equivalent to *p.
  • T is EmplaceConstructible into X from args, for zero or more arguments args, means that the following expression is well-formed:
    allocator_traits<A>::construct(m, p, args)
  • T is Erasable from X means that the following expression is well-formed:
    allocator_traits<A>::destroy(m, p)
[Note
:
A container calls allocator_­traits<A>​::​construct(m, p, args) to construct an element at p using args, with m == get_­allocator().
The default construct in allocator will call ​::​new((void*)p) T(args), but specialized allocators may choose a different definition.
end note
]
In Table 81, X denotes an allocator-aware container class with a value_­type of T using allocator of type A, u denotes a variable, a and b denote non-const lvalues of type X, t denotes an lvalue or a const rvalue of type X, rv denotes a non-const rvalue of type X, and m is a value of type A.
Table 81 — Allocator-aware container requirements
Expression
Return type
Assertion/note
Complexity
pre-/post-condition
allocator_­type
A
Requires: allocator_­type​::​value_­type is the same as X​::​value_­type.
compile time
get_­- allocator()
A
constant
X()
X u;
Requires: A is DefaultConstructible.

Postconditions: u.empty() returns true, u.get_­allocator() == A()
constant
X(m)
Postconditions: u.empty() returns true,
constant
X u(m);
u.get_­allocator() == m
X(t, m)
X u(t, m);
Requires: T is CopyInsertable into X.

Postconditions: u == t, u.get_­allocator() == m
linear
X(rv)
X u(rv);
Postconditions: u shall have the same elements as rv had before this construction; the value of u.get_­allocator() shall be the same as the value of rv.get_­allocator() before this construction.
constant
X(rv, m)
X u(rv, m);
Requires: T is MoveInsertable into X.

Postconditions: u shall have the same elements, or copies of the elements, that rv had before this construction, u.get_­allocator() == m
constant if m == rv.get_­allocator(), otherwise linear
a = t
X&
Requires: T is CopyInsertable into X and CopyAssignable.

Postconditions: a == t
linear
a = rv
X&
Requires: If allocator_­-
traits<allocator_­type>
​::​propagate_­on_­container_­-
move_­assignment​::​value is
false, T is MoveInsertable into X and MoveAssignable.
All existing elements of a are either move assigned to or destroyed.

Postconditions: a shall be equal to the value that rv had before this assignment.
linear
a.swap(b)
void
exchanges the contents of a and b
constant
The behavior of certain container member functions and deduction guides depends on whether types qualify as input iterators or allocators.
The extent to which an implementation determines that a type cannot be an input iterator is unspecified, except that as a minimum integral types shall not qualify as input iterators.
Likewise, the extent to which an implementation determines that a type cannot be an allocator is unspecified, except that as a minimum a type A shall not qualify as an allocator unless it satisfies both of the following conditions:
  • The qualified-id A​::​value_­type is valid and denotes a type ([temp.deduct]).
  • The expression declval<A&>().allocate(size_­t{}) is well-formed when treated as an unevaluated operand.

26.2.2 Container data races [container.requirements.dataraces]

For purposes of avoiding data races ([res.on.data.races]), implementations shall consider the following functions to be const: begin, end, rbegin, rend, front, back, data, find, lower_­bound, upper_­bound, equal_­range, at and, except in associative or unordered associative containers, operator[].
Notwithstanding [res.on.data.races], implementations are required to avoid data races when the contents of the contained object in different elements in the same container, excepting vector<bool>, are modified concurrently.
[Note
:
For a vector<int> x with a size greater than one, x[1] = 5 and *x.begin() = 10 can be executed concurrently without a data race, but x[0] = 5 and *x.begin() = 10 executed concurrently may result in a data race.
As an exception to the general rule, for a vector<bool> y, y[0] = true may race with y[1] = true.
end note
]

26.2.3 Sequence containers [sequence.reqmts]

A sequence container organizes a finite set of objects, all of the same type, into a strictly linear arrangement.
The library provides four basic kinds of sequence containers: vector, forward_­list, list, and deque.
In addition, array is provided as a sequence container which provides limited sequence operations because it has a fixed number of elements.
The library also provides container adaptors that make it easy to construct abstract data types, such as stacks or queues, out of the basic sequence container kinds (or out of other kinds of sequence containers that the user might define).
The sequence containers offer the programmer different complexity trade-offs and should be used accordingly.
vector or array is the type of sequence container that should be used by default.
list or forward_­list should be used when there are frequent insertions and deletions from the middle of the sequence.
deque is the data structure of choice when most insertions and deletions take place at the beginning or at the end of the sequence.
In Tables 82 and 83, X denotes a sequence container class, a denotes a value of type X containing elements of type T, u denotes the name of a variable being declared, A denotes X​::​allocator_­type if the qualified-id X​::​allocator_­type is valid and denotes a type ([temp.deduct]) and allocator<T> if it doesn't, i and j denote iterators satisfying input iterator requirements and refer to elements implicitly convertible to value_­type, [i, j) denotes a valid range, il designates an object of type initializer_­list<value_­type>, n denotes a value of type X​::​size_­type, p denotes a valid constant iterator to a, q denotes a valid dereferenceable constant iterator to a, [q1, q2) denotes a valid range of constant iterators in a, t denotes an lvalue or a const rvalue of X​::​value_­type, and rv denotes a non-const rvalue of X​::​value_­type.
Args denotes a template parameter pack; args denotes a function parameter pack with the pattern Args&&.
The complexities of the expressions are sequence dependent.
Table 82 — Sequence container requirements (in addition to container)
Expression
Return type
Assertion/note
pre-/post-condition
X(n, t)
X u(n, t);
Requires: T shall be CopyInsertable into X.

Postconditions: distance(begin(), end()) == n
Constructs a sequence container with n copies of t
X(i, j)
X u(i, j);
Requires: T shall be EmplaceConstructible into X from *i.
For vector, if the iterator does not meet the forward iterator requirements ([forward.iterators]), T shall also be MoveInsertable into X.
Each iterator in the range [i, j) shall be dereferenced exactly once.

Postconditions: distance(begin(), end()) == distance(i, j)
Constructs a sequence container equal to the range [i, j)
X(il)
Equivalent to X(il.begin(), il.end())
a = il
X&
Requires: T is CopyInsertable into X and CopyAssignable.
Assigns the range [il.begin(), il.end()) into a.
All existing elements of a are either assigned to or destroyed.

Returns: *this.
a.emplace(p, args)
iterator
Requires: T is EmplaceConstructible into X from args.
For vector and deque, T is also MoveInsertable into X and MoveAssignable.
Effects: Inserts an object of type T constructed with std​::​forward<​Args​>(​args)... before p.
a.insert(p,t)
iterator
Requires: T shall be CopyInsertable into X.
For vector and deque, T shall also be CopyAssignable.

Effects: Inserts a copy of t before p.
a.insert(p,rv)
iterator
Requires: T shall be MoveInsertable into X.
For vector and deque, T shall also be MoveAssignable.

Effects: Inserts a copy of rv before p.
a.insert(p,n,t)
iterator
Requires: T shall be CopyInsertable into X and CopyAssignable.

Inserts n copies of t before p.
a.insert(p,i,j)
iterator
Requires: T shall be EmplaceConstructible into X from *i.
For vector and deque, T shall also be MoveInsertable into X, MoveConstructible, MoveAssignable, and swappable ([swappable.requirements]).
Each iterator in the range [i, j) shall be dereferenced exactly once.

Requires: i and j are not iterators into a.

Inserts copies of elements in [i, j) before p
a.insert(p, il)
iterator
a.insert(p, il.begin(), il.end()).
a.erase(q)
iterator
Requires: For vector and deque, T shall be MoveAssignable.

Effects: Erases the element pointed to by q.
a.erase(q1,q2)
iterator
Requires: For vector and deque, T shall be MoveAssignable.

Effects: Erases the elements in the range [q1, q2).
a.clear()
void
Destroys all elements in a.
Invalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator.

Postconditions: a.empty() returns true.

Complexity: Linear.
a.assign(i,j)
void
Requires: T shall be EmplaceConstructible into X from *i and assignable from *i.
For vector, if the iterator does not meet the forward iterator requirements ([forward.iterators]), T shall also be MoveInsertable into X.

Each iterator in the range [i, j) shall be dereferenced exactly once.

Requires: i, j are not iterators into a.

Replaces elements in a with a copy of [i, j).

Invalidates all references, pointers and iterators referring to the elements of a.
For vector and deque, also invalidates the past-the-end iterator.
a.assign(il)
void
a.assign(il.begin(), il.end()).
a.assign(n,t)
void
Requires: T shall be CopyInsertable into X and CopyAssignable.

Requires: t is not a reference into a.

Replaces elements in a with n copies of t.

Invalidates all references, pointers and iterators referring to the elements of a.
For vector and deque, also invalidates the past-the-end iterator.
The iterator returned from a.insert(p, t) points to the copy of t inserted into a.
The iterator returned from a.insert(p, rv) points to the copy of rv inserted into a.
The iterator returned from a.insert(p, n, t) points to the copy of the first element inserted into a, or p if n == 0.
The iterator returned from a.insert(p, i, j) points to the copy of the first element inserted into a, or p if i == j.
The iterator returned from a.insert(p, il) points to the copy of the first element inserted into a, or p if il is empty.
The iterator returned from a.emplace(p, args) points to the new element constructed from args into a.
The iterator returned from a.erase(q) points to the element immediately following q prior to the element being erased.
If no such element exists, a.end() is returned.
The iterator returned by a.erase(q1, q2) points to the element pointed to by q2 prior to any elements being erased.
If no such element exists, a.end() is returned.
For every sequence container defined in this Clause and in Clause [strings]:
  • If the constructor
    template <class InputIterator>
      X(InputIterator first, InputIterator last,
        const allocator_type& alloc = allocator_type());
    is called with a type InputIterator that does not qualify as an input iterator, then the constructor shall not participate in overload resolution.
  • If the member functions of the forms:
    template <class InputIterator>
      return-type F(const_iterator p,
                    InputIterator first, InputIterator last);       // such as insert
    
    template <class InputIterator>
      return-type F(InputIterator first, InputIterator last);       // such as append, assign
    
    template <class InputIterator>
      return-type F(const_iterator i1, const_iterator i2,
                    InputIterator first, InputIterator last);       // such as replace
    
    are called with a type InputIterator that does not qualify as an input iterator, then these functions shall not participate in overload resolution.
  • A deduction guide for a sequence container shall not participate in overload resolution if it has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter, or if it has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
Table 83 lists operations that are provided for some types of sequence containers but not others.
An implementation shall provide these operations for all container types shown in the “container” column, and shall implement them so as to take amortized constant time.
Table 83 — Optional sequence container operations
Expression
Return type
Operational semantics
Container
a.front()
reference; const_­reference for constant a
*a.begin()
basic_­string, array, deque, forward_­list, list, vector
a.back()
reference; const_­reference for constant a
{ auto tmp = a.end();
--tmp;
return *tmp; }
basic_­string, array, deque, list, vector
a.emplace_­front(args)
reference
Prepends an object of type T constructed with std​::​forward<​Args​>(​args)....

Requires: T shall be EmplaceConstructible into X from args.

Returns: a.front().
deque, forward_­list, list
a.emplace_­back(args)
reference
Appends an object of type T constructed with std​::​forward<​Args​>(​args)....

Requires: T shall be EmplaceConstructible into X from args.
For vector, T shall also be MoveInsertable into X.

Returns: a.back().
deque, list, vector
a.push_­front(t)
void
Prepends a copy of t.

Requires: T shall be CopyInsertable into X.
deque, forward_­list, list
a.push_­front(rv)
void
Prepends a copy of rv.

Requires: T shall be MoveInsertable into X.
deque, forward_­list, list
a.push_­back(t)
void
Appends a copy of t.

Requires: T shall be CopyInsertable into X.
basic_­string, deque, list, vector
a.push_­back(rv)
void
Appends a copy of rv.

Requires: T shall be MoveInsertable into X.
basic_­string, deque, list, vector
a.pop_­front()
void
Destroys the first element.

Requires: a.empty() shall be false.
deque, forward_­list, list
a.pop_­back()
void
Destroys the last element.

Requires: a.empty() shall be false.
basic_­string, deque, list, vector
a[n]
reference; const_­reference for constant a
*(a.begin() + n)
basic_­string, array, deque, vector
a.at(n)
reference; const_­reference for constant a
*(a.begin() + n)
basic_­string, array, deque, vector
The member function at() provides bounds-checked access to container elements.
at() throws out_­of_­range if n >= a.size().

26.2.4 Node handles [container.node]

26.2.4.1 node_­handle overview [container.node.overview]

A node handle is an object that accepts ownership of a single element from an associative container ([associative.reqmts]) or an unordered associative container ([unord.req]).
It may be used to transfer that ownership to another container with compatible nodes.
Containers with compatible nodes have the same node handle type.
Elements may be transferred in either direction between container types in the same row of Table 84.
Table 84 — Container types with compatible nodes
map<K, T, C1, A>
map<K, T, C2, A>
map<K, T, C1, A>
multimap<K, T, C2, A>
set<K, C1, A>
set<K, C2, A>
set<K, C1, A>
multiset<K, C2, A>
unordered_­map<K, T, H1, E1, A>
unordered_­map<K, T, H2, E2, A>
unordered_­map<K, T, H1, E1, A>
unordered_­multimap<K, T, H2, E2, A>
unordered_­set<K, H1, E1, A>
unordered_­set<K, H2, E2, A>
unordered_­set<K, H1, E1, A>
unordered_­multiset<K, H2, E2, A>
If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container when the element was extracted.
If a node handle is empty, it contains no allocator.
Class node_­handle is for exposition only.
An implementation is permitted to provide equivalent functionality without providing a class with this name.
If a user-defined specialization of pair exists for pair<const Key, T> or pair<Key, T>, where Key is the container's key_­type and T is the container's mapped_­type, the behavior of operations involving node handles is undefined.
template<unspecified>
  class node_handle {
  public:
    // These type declarations are described in Tables 85 and 86.
    using value_type     = see below;   // not present for map containers
    using key_type       = see below;   // not present for set containers
    using mapped_type    = see below;   // not present for set containers
    using allocator_type = see below;

  private:
    using container_node_type = unspecified;
    using ator_traits = allocator_traits<allocator_type>;

    typename ator_traits::rebind_traits<container_node_type>::pointer ptr_;
    optional<allocator_type> alloc_;

  public:
    constexpr node_handle() noexcept : ptr_(), alloc_() {}
    ~node_handle();
    node_handle(node_handle&&) noexcept;
    node_handle& operator=(node_handle&&);

    value_type& value() const;          // not present for map containers
    key_type& key() const;              // not present for set containers
    mapped_type& mapped() const;        // not present for set containers

    allocator_type get_allocator() const;
    explicit operator bool() const noexcept;
    bool empty() const noexcept;

    void swap(node_handle&)
      noexcept(ator_traits::propagate_on_container_swap::value ||
               ator_traits::is_always_equal::value);

    friend void swap(node_handle& x, node_handle& y) noexcept(noexcept(x.swap(y))) {
      x.swap(y);
    }
};

26.2.4.2 node_­handle constructors, copy, and assignment [container.node.cons]

node_handle(node_handle&& nh) noexcept;
Effects: Constructs a node_­handle object initializing ptr_­ with nh.ptr_­.
Move constructs alloc_­ with nh.alloc_­.
Assigns nullptr to nh.ptr_­ and assigns nullopt to nh.alloc_­.
node_handle& operator=(node_handle&& nh);
Requires: Either !alloc_­, or ator_­traits​::​propagate_­on_­container_­move_­assignment is true, or alloc_­ == nh.alloc_­.
Effects:
  • If ptr_­ != nullptr, destroys the value_­type subobject in the container_­node_­type object pointed to by ptr_­ by calling ator_­traits​::​destroy, then deallocates ptr_­ by calling ator_­traits​::​rebind_­traits<container_­node_­type>​::​deallocate.
  • Assigns nh.ptr_­ to ptr_­.
  • If !alloc_ or ator_­traits​::​propagate_­on_­container_­move_­assignment is true, move assigns nh.alloc_­ to alloc_­.
  • Assigns nullptr to nh.ptr_­ and assigns nullopt to nh.alloc_­.
Returns: *this.
Throws: Nothing.

26.2.4.3 node_­handle destructor [container.node.dtor]

~node_handle();
Effects: If ptr_­ != nullptr, destroys the value_­type subobject in the container_­node_­type object pointed to by ptr_­ by calling ator_­traits​::​destroy, then deallocates ptr_­ by calling ator_­traits​::​rebind_­traits<container_­node_­type>​::​deallocate.

26.2.4.4 node_­handle observers [container.node.observers]

value_type& value() const;
Requires: empty() == false.
Returns: A reference to the value_­type subobject in the container_­node_­type object pointed to by ptr_­.
Throws: Nothing.
key_type& key() const;
Requires: empty() == false.
Returns: A non-const reference to the key_­type member of the value_­type subobject in the container_­node_­type object pointed to by ptr_­.
Throws: Nothing.
Remarks: Modifying the key through the returned reference is permitted.
mapped_type& mapped() const;
Requires: empty() == false.
Returns: A reference to the mapped_­type member of the value_­type subobject in the container_­node_­type object pointed to by ptr_­.
Throws: Nothing.
allocator_type get_allocator() const;
Requires: empty() == false.
Returns: *alloc_­.
Throws: Nothing.
explicit operator bool() const noexcept;
Returns: ptr_­ != nullptr.
bool empty() const noexcept;
Returns: ptr_­ == nullptr.

26.2.4.5 node_­handle modifiers [container.node.modifiers]

void swap(node_handle& nh) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value);
Requires: !alloc_­, or !nh.alloc_­, or ator_­traits​::​propagate_­on_­container_­swap is true, or alloc_­ == nh.alloc_­.
Effects: Calls swap(ptr_­, nh.ptr_­).
If !alloc_­, or !nh.alloc_­, or ator_­traits​::​propagate_­on_­container_­swap is true calls swap(alloc_­, nh.alloc_­).

26.2.5 Insert return type [container.insert.return]

The associative containers with unique keys and the unordered containers with unique keys have a member function insert that returns a nested type insert_­return_­type.
That return type is a specialization of the type specified in this subclause.
template <class Iterator, class NodeType>
struct INSERT_RETURN_TYPE
{
  Iterator position;
  bool     inserted;
  NodeType node;
};
The name INSERT_­RETURN_­TYPE is exposition only.
INSERT_­RETURN_­TYPE has the template parameters, data members, and special members specified above.
It has no base classes or members other than those specified.

26.2.6 Associative containers [associative.reqmts]

Associative containers provide fast retrieval of data based on keys.
The library provides four basic kinds of associative containers: set, multiset, map and multimap.
Each associative container is parameterized on Key and an ordering relation Compare that induces a strict weak ordering ([alg.sorting]) on elements of Key.
In addition, map and multimap associate an arbitrary mapped type T with the Key.
The object of type Compare is called the comparison object of a container.
The phrase “equivalence of keys” means the equivalence relation imposed by the comparison and not the operator== on keys.
That is, two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false.
For any two keys k1 and k2 in the same container, calling comp(k1, k2) shall always return the same value.
An associative container supports unique keys if it may contain at most one element for each key.
Otherwise, it supports equivalent keys.
The set and map classes support unique keys; the multiset and multimap classes support equivalent keys.
For multiset and multimap, insert, emplace, and erase preserve the relative ordering of equivalent elements.
For set and multiset the value type is the same as the key type.
For map and multimap it is equal to pair<const Key, T>.
iterator of an associative container is of the bidirectional iterator category.
For associative containers where the value type is the same as the key type, both iterator and const_­iterator are constant iterators.
It is unspecified whether or not iterator and const_­iterator are the same type.
[Note
:
iterator and const_­iterator have identical semantics in this case, and iterator is convertible to const_­iterator.
Users can avoid violating the one-definition rule by always using const_­iterator in their function parameter lists.
end note
]
The associative containers meet all the requirements of Allocator-aware containers ([container.requirements.general]), except that for map and multimap, the requirements placed on value_­type in Table 78 apply instead to key_­type and mapped_­type.
[Note
:
For example, in some cases key_­type and mapped_­type are required to be CopyAssignable even though the associated value_­type, pair<const key_­type, mapped_­type>, is not CopyAssignable.
end note
]
In Table 85, X denotes an associative container class, a denotes a value of type X, a2 denotes a value of a type with nodes compatible with type X (Table 84), b denotes a possibly const value of type X, u denotes the name of a variable being declared, a_­uniq denotes a value of type X when X supports unique keys, a_­eq denotes a value of type X when X supports multiple keys, a_­tran denotes a possibly const value of type X when the qualified-id X​::​key_­compare​::​is_­transparent is valid and denotes a type ([temp.deduct]), i and j satisfy input iterator requirements and refer to elements implicitly convertible to value_­type, [i, j) denotes a valid range, p denotes a valid constant iterator to a, q denotes a valid dereferenceable constant iterator to a, r denotes a valid dereferenceable iterator to a, [q1, q2) denotes a valid range of constant iterators in a, il designates an object of type initializer_­list<value_­type>, t denotes a value of type X​::​value_­type, k denotes a value of type X​::​key_­type and c denotes a possibly const value of type X​::​key_­compare; kl is a value such that a is partitioned ([alg.sorting]) with respect to c(r, kl), with r the key value of e and e in a; ku is a value such that a is partitioned with respect to !c(ku, r); ke is a value such that a is partitioned with respect to c(r, ke) and !c(ke, r), with c(r, ke) implying !c(ke, r).
A denotes the storage allocator used by X, if any, or allocator<X​::​value_­type> otherwise, m denotes an allocator of a type convertible to A, and nh denotes a non-const rvalue of type X​::​node_­type.
Table 85 — Associative container requirements (in addition to container)
Expression
Return type
Assertion/note
Complexity
pre-/post-condition
X​::​key_­type
Key
compile time
X​::​mapped_­type (map and multimap only)
T
compile time
X​::​value_­type (set and multiset only)
Key
Requires: value_­type is Erasable from X
compile time
X​::​value_­type (map and multimap only)
pair<const Key, T>
Requires: value_­type is Erasable from X
compile time
X​::​key_­compare
Compare
Requires: key_­compare is CopyConstructible.
compile time
X​::​value_­compare
a binary predicate type
is the same as key_­compare for set and multiset; is an ordering relation on pairs induced by the first component (i.e., Key) for map and multimap.
compile time
X​::​node_­type
a specialization of a node_­handle class template, such that the public nested types are the same types as the corresponding types in X.
compile time
X(c)
X u(c);
Effects: Constructs an empty container.
Uses a copy of c as a comparison object.
constant
X()
X u;
Requires: key_­compare is DefaultConstructible.

Effects: Constructs an empty container.
Uses Compare() as a comparison object
constant
X(i,j,c)
X u(i,j,c);
Requires: value_­type is EmplaceConstructible into X from *i.

Effects: Constructs an empty container and inserts elements from the range [i, j) into it; uses c as a comparison object.
in general, where N has the value distance(i, j); linear if [i, j) is sorted with value_­comp()
X(i,j)
X u(i,j);
Requires: key_­compare is DefaultConstructible.
value_­type is EmplaceConstructible into X from *i.

Effects: Same as above, but uses Compare() as a comparison object.
same as above
X(il)
same as X(il.begin(), il.end())
same as X(il.begin(), il.end())
X(il,c)
same as X(il.begin(), il.end(), c)
same as X(il.begin(), il.end(), c)
a = il
X&
Requires: value_­type is CopyInsertable into X and CopyAssignable.

Effects: Assigns the range [il.begin(), il.end()) into a.
All existing elements of a are either assigned to or destroyed.
in general, where N has the value il.size() + a.size(); linear if [il.begin(), il.end()) is sorted with value_­comp()
b.key_­comp()
X​::​key_­compare
returns the comparison object out of which b was constructed.
constant
b.value_­comp()
X​::​value_­compare
returns an object of value_­compare constructed out of the comparison object
constant
a_­uniq.​emplace(​args)
pair<​iterator, bool>
Requires: value_­type shall be EmplaceConstructible into X from args.

Effects: Inserts a value_­type object t constructed with std​::​forward<​Args​>(​args)... if and only if there is no element in the container with key equivalent to the key of t.
The bool component of the returned pair is true if and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key of t.
logarithmic
a_­eq.​emplace(​args)
iterator
Requires: value_­type shall be EmplaceConstructible into X from args.

Effects: Inserts a value_­type object t constructed with std​::​forward<​Args​>(​args)... and returns the iterator pointing to the newly inserted element.
If a range containing elements equivalent to t exists in a_­eq, t is inserted at the end of that range.
logarithmic
a.emplace_­hint(​p, args)
iterator
equivalent to a.emplace( std​::​forward<​Args​>(​args)...).
Return value is an iterator pointing to the element with the key equivalent to the newly inserted element.
The element is inserted as close as possible to the position just prior to p.
logarithmic in general, but amortized constant if the element is inserted right before p
a_­uniq.​insert(​t)
pair<​iterator, bool>
Requires: If t is a non-const rvalue expression, value_­type shall be MoveInsertable into X; otherwise, value_­type shall be CopyInsertable into X.

Effects: Inserts t if and only if there is no element in the container with key equivalent to the key of t.
The bool component of the returned pair is true if and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key of t.
logarithmic
a_­eq.​insert(​t)
iterator
Requires: If t is a non-const rvalue expression, value_­type shall be MoveInsertable into X; otherwise, value_­type shall be CopyInsertable into X.

Effects: Inserts t and returns the iterator pointing to the newly inserted element.
If a range containing elements equivalent to t exists in a_­eq, t is inserted at the end of that range.
logarithmic
a.​insert(​p, t)
iterator
Requires: If t is a non-const rvalue expression, value_­type shall be MoveInsertable into X; otherwise, value_­type shall be CopyInsertable into X.

Effects: Inserts t if and only if there is no element with key equivalent to the key of t in containers with unique keys; always inserts t in containers with equivalent keys.
Always returns the iterator pointing to the element with key equivalent to the key of t.
t is inserted as close as possible to the position just prior to p.
logarithmic in general, but amortized constant if t is inserted right before p.
a.​insert(​i, j)
void
Requires: value_­type shall be EmplaceConstructible into X from *i.

Requires: i, j are not iterators into a.
inserts each element from the range [i, j) if and only if there is no element with key equivalent to the key of that element in containers with unique keys; always inserts that element in containers with equivalent keys.
, where N has the value distance(i, j)
a.​insert(​il)
void
equivalent to a.insert(il.begin(), il.end())
a_­uniq.​insert(​nh)
insert_­return_­type
Requires: nh is empty or a_­uniq.get_­allocator() == nh.get_­allocator().

Effects: If nh is empty, has no effect.
Otherwise, inserts the element owned by nh if and only if there is no element in the container with a key equivalent to nh.key().

Postconditions: If nh is empty, inserted is false, position is end(), and node is empty.
Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty; if the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key().
logarithmic
a_­eq.​insert(​nh)
iterator
Requires: nh is empty or a_­eq.get_­allocator() == nh.get_­allocator().

Effects: If nh is empty, has no effect and returns a_­eq.end().
Otherwise, inserts the element owned by nh and returns an iterator pointing to the newly inserted element.
If a range containing elements with keys equivalent to nh.key() exists in a_­eq, the element is inserted at the end of that range.

Postconditions: nh is empty.
logarithmic
a.​insert(​p, nh)
iterator
Requires: nh is empty or a.get_­allocator() == nh.get_­allocator().

Effects: If nh is empty, has no effect and returns a.end().
Otherwise, inserts the element owned by nh if and only if there is no element with key equivalent to nh.key() in containers with unique keys; always inserts the element owned by nh in containers with equivalent keys.
Always returns the iterator pointing to the element with key equivalent to nh.key().
The element is inserted as close as possible to the position just prior to p.

Postconditions: nh is empty if insertion succeeds, unchanged if insertion fails.
logarithmic in general, but amortized constant if the element is inserted right before p.
a.​extract(​k)
node_­type
removes the first element in the container with key equivalent to k.
Returns a node_­type owning the element if found, otherwise an empty node_­type.
log(a.size())
a.​extract(​q)
node_­type
removes the element pointed to by q.
Returns a node_­type owning that element.
amortized constant
a.merge(a2)
void
Requires: a.get_­allocator() == a2.get_­allocator().

Attempts to extract each element in a2 and insert it into a using the comparison object of a.
In containers with unique keys, if there is an element in a with key equivalent to the key of an element from a2, then that element is not extracted from a2.

Postconditions: Pointers and references to the transferred elements of a2 refer to those same elements but as members of a.
Iterators referring to the transferred elements will continue to refer to their elements, but they now behave as iterators into a, not into a2.

Throws: Nothing unless the comparison object throws.
, where N has the value a2.size().
a.erase(k)
size_­type
erases all elements in the container with key equivalent to k.
returns the number of erased elements.
a.erase(q)
iterator
erases the element pointed to by q.
Returns an iterator pointing to the element immediately following q prior to the element being erased.
If no such element exists, returns a.end().
amortized constant
a.erase(r)
iterator
erases the element pointed to by r.
Returns an iterator pointing to the element immediately following r prior to the element being erased.
If no such element exists, returns a.end().
amortized constant
a.erase(
q1, q2)
iterator
erases all the elements in the range [q1, q2).
Returns an iterator pointing to the element pointed to by q2 prior to any elements being erased.
If no such element exists, a.end() is returned.
, where N has the value distance(q1, q2).
a.clear()
void
a.erase(a.begin(),a.end())
Postconditions: a.empty() returns true.
linear in a.size().
b.find(k)
iterator; const_­iterator for constant b.
returns an iterator pointing to an element with the key equivalent to k, or b.end() if such an element is not found
logarithmic
a_­tran.
find(ke)
iterator; const_­iterator for constant a_­tran.
returns an iterator pointing to an element with key r such that !c(r, ke) && !c(ke, r), or a_­tran.end() if such an element is not found
logarithmic
b.count(k)
size_­type
returns the number of elements with key equivalent to k
a_­tran.
count(ke)
size_­type
returns the number of elements with key r such that !c(r, ke) && !c(ke, r)
b.lower_­bound(k)
iterator; const_­iterator for constant b.
returns an iterator pointing to the first element with key not less than k, or b.end() if such an element is not found.
logarithmic
a_­tran.
lower_­bound(kl)
iterator; const_­iterator for constant a_­tran.
returns an iterator pointing to the first element with key r such that !c(r, kl), or a_­tran.end() if such an element is not found.
logarithmic
b.upper_­bound(k)
iterator; const_­iterator for constant b.
returns an iterator pointing to the first element with key greater than k, or b.end() if such an element is not found.
logarithmic
a_­tran.
upper_­bound(ku)
iterator; const_­iterator for constant a_­tran.
returns an iterator pointing to the first element with key r such that c(ku, r), or a_­tran.end() if such an element is not found.
logarithmic
b.equal_­range(k)
pair<​iterator, iterator>; pair<​const_­iterator, const_­iterator> for constant b.
equivalent to make_­pair(b.lower_­bound(k), b.upper_­bound(k)).
logarithmic
a_­tran.
equal_­range(ke)
pair<​iterator, iterator>; pair<​const_­iterator, const_­iterator> for constant a_­tran.
equivalent to make_­pair(
a_­tran.lower_­bound(ke), a_­tran.upper_­bound(ke)).
logarithmic
The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.
The extract members invalidate only iterators to the removed element; pointers and references to the removed element remain valid.
However, accessing the element through such pointers and references while the element is owned by a node_­type is undefined behavior.
References and pointers to an element obtained while it is owned by a node_­type are invalidated if the element is successfully inserted.
The fundamental property of iterators of associative containers is that they iterate through the containers in the non-descending order of keys where non-descending is defined by the comparison that was used to construct them.
For any two dereferenceable iterators i and j such that distance from i to j is positive, the following condition holds:
value_comp(*j, *i) == false
For associative containers with unique keys the stronger condition holds:
value_comp(*i, *j) != false
When an associative container is constructed by passing a comparison object the container shall not store a pointer or reference to the passed object, even if that object is passed by reference.
When an associative container is copied, either through a copy constructor or an assignment operator, the target container shall then use the comparison object from the container being copied, as if that comparison object had been passed to the target container in its constructor.
The member function templates find, count, lower_­bound, upper_­bound, and equal_­range shall not participate in overload resolution unless the qualified-id Compare​::​is_­transparent is valid and denotes a type ([temp.deduct]).
A deduction guide for an associative container shall not participate in overload resolution if any of the following are true:
  • It has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter.
  • It has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
  • It has a Compare template parameter and a type that qualifies as an allocator is deduced for that parameter.

26.2.6.1 Exception safety guarantees [associative.reqmts.except]

For associative containers, no clear() function throws an exception.
erase(k) does not throw an exception unless that exception is thrown by the container's Compare object (if any).
For associative containers, if an exception is thrown by any operation from within an insert or emplace function inserting a single element, the insertion has no effect.
For associative containers, no swap function throws an exception unless that exception is thrown by the swap of the container's Compare object (if any).

26.2.7 Unordered associative containers [unord.req]

Unordered associative containers provide an ability for fast retrieval of data based on keys.
The worst-case complexity for most operations is linear, but the average case is much faster.
The library provides four unordered associative containers: unordered_­set, unordered_­map, unordered_­multiset, and unordered_­multimap.
Unordered associative containers conform to the requirements for Containers ([container.requirements]), except that the expressions a == b and a != b have different semantics than for the other container types.
Each unordered associative container is parameterized by Key, by a function object type Hash that meets the Hash requirements ([hash.requirements]) and acts as a hash function for argument values of type Key, and by a binary predicate Pred that induces an equivalence relation on values of type Key.
Additionally, unordered_­map and unordered_­multimap associate an arbitrary mapped type T with the Key.
The container's object of type Hash — denoted by hash — is called the hash function of the container.
The container's object of type Pred — denoted by pred — is called the key equality predicate of the container.
Two values k1 and k2 of type Key are considered equivalent if the container's key equality predicate returns true when passed those values.
If k1 and k2 are equivalent, the container's hash function shall return the same value for both.
[Note
:
Thus, when an unordered associative container is instantiated with a non-default Pred parameter it usually needs a non-default Hash parameter as well.
end note
]
For any two keys k1 and k2 in the same container, calling pred(k1, k2) shall always return the same value.
For any key k in a container, calling hash(k) shall always return the same value.
An unordered associative container supports unique keys if it may contain at most one element for each key.
Otherwise, it supports equivalent keys.
unordered_­set and unordered_­map support unique keys.
unordered_­multiset and unordered_­multimap support equivalent keys.
In containers that support equivalent keys, elements with equivalent keys are adjacent to each other in the iteration order of the container.
Thus, although the absolute order of elements in an unordered container is not specified, its elements are grouped into equivalent-key groups such that all elements of each group have equivalent keys.
Mutating operations on unordered containers shall preserve the relative order of elements within each equivalent-key group unless otherwise specified.
For unordered_­set and unordered_­multiset the value type is the same as the key type.
For unordered_­map and unordered_­multimap it is pair<const Key, T>.
For unordered containers where the value type is the same as the key type, both iterator and const_­iterator are constant iterators.
It is unspecified whether or not iterator and const_­iterator are the same type.
[Note
:
iterator and const_­iterator have identical semantics in this case, and iterator is convertible to const_­iterator.
Users can avoid violating the one-definition rule by always using const_­iterator in their function parameter lists.
end note
]
The elements of an unordered associative container are organized into buckets.
Keys with the same hash code appear in the same bucket.
The number of buckets is automatically increased as elements are added to an unordered associative container, so that the average number of elements per bucket is kept below a bound.
Rehashing invalidates iterators, changes ordering between elements, and changes which buckets elements appear in, but does not invalidate pointers or references to elements.
For unordered_­multiset and unordered_­multimap, rehashing preserves the relative ordering of equivalent elements.
The unordered associative containers meet all the requirements of Allocator-aware containers ([container.requirements.general]), except that for unordered_­map and unordered_­multimap, the requirements placed on value_­type in Table 78 apply instead to key_­type and mapped_­type.
[Note
:
For example, key_­type and mapped_­type are sometimes required to be CopyAssignable even though the associated value_­type, pair<const key_­type, mapped_­type>, is not CopyAssignable.
end note
]
In Table 86: X denotes an unordered associative container class, a denotes a value of type X, a2 denotes a value of a type with nodes compatible with type X (Table 84), b denotes a possibly const value of type X, a_­uniq denotes a value of type X when X supports unique keys, a_­eq denotes a value of type X when X supports equivalent keys, i and j denote input iterators that refer to value_­type, [i, j) denotes a valid range, p and q2 denote valid constant iterators to a, q and q1 denote valid dereferenceable constant iterators to a, r denotes a valid dereferenceable iterator to a, [q1, q2) denotes a valid range in a, il denotes a value of type initializer_­list<value_­type>, t denotes a value of type X​::​value_­type, k denotes a value of type key_­type, hf denotes a possibly const value of type hasher, eq denotes a possibly const value of type key_­equal, n denotes a value of type size_­type, z denotes a value of type float, and nh denotes a non-const rvalue of type X​::​node_­type.
Table 86 — Unordered associative container requirements (in addition to container)
Expression
Return type
Assertion/note
Complexity
pre-/post-condition
X​::​key_­type
Key
compile time
X​::​mapped_­type (unordered_­map and unordered_­multimap only)
T
compile time
X​::​value_­type (unordered_­set and unordered_­multiset only)
Key
Requires: value_­type is Erasable from X
compile time
X​::​value_­type (unordered_­map and unordered_­multimap only)
pair<const Key, T>
Requires: value_­type is Erasable from X
compile time
X​::​hasher
Hash
Hash shall be a unary function object type such that the expression hf(k) has type size_­t.
compile time
X​::​key_­equal
Pred
Requires: Pred is CopyConstructible.

Pred shall be a binary predicate that takes two arguments of type Key.
Pred is an equivalence relation.
compile time
X​::​local_­iterator
An iterator type whose category, value type, difference type, and pointer and reference types are the same as X​::​iterator's.
A local_­iterator object may be used to iterate through a single bucket, but may not be used to iterate across buckets.
compile time
X​::​const_­local_­iterator
An iterator type whose category, value type, difference type, and pointer and reference types are the same as X​::​const_­iterator's.
A const_­local_­iterator object may be used to iterate through a single bucket, but may not be used to iterate across buckets.
compile time
X​::​node_­type
a specialization of a node_­handle class template, such that the public nested types are the same types as the corresponding types in X.
compile time
X(n, hf, eq)
X a(n, hf, eq);
X
Effects: Constructs an empty container with at least n buckets, using hf as the hash function and eq as the key equality predicate.
X(n, hf)
X a(n, hf);
X
Requires: key_­equal is DefaultConstructible.

Effects: Constructs an empty container with at least n buckets, using hf as the hash function and key_­equal() as the key equality predicate.
X(n)
X a(n);
X
Requires: hasher and key_­equal are DefaultConstructible.

Effects: Constructs an empty container with at least n buckets, using hasher() as the hash function and key_­equal() as the key equality predicate.
X()
X a;
X
Requires: hasher and key_­equal are DefaultConstructible.

Effects: Constructs an empty container with an unspecified number of buckets, using hasher() as the hash function and key_­equal() as the key equality predicate.
constant
X(i, j, n, hf, eq)
X a(i, j, n, hf, eq);
X
Requires: value_­type is EmplaceConstructible into X from *i.

Effects: Constructs an empty container with at least n buckets, using hf as the hash function and eq as the key equality predicate, and inserts elements from [i, j) into it.
Average case (N is distance(i, j)), worst case
X(i, j, n, hf)
X a(i, j, n, hf);
X
Requires: key_­equal is DefaultConstructible.
value_­type is EmplaceConstructible into X from *i.

Effects: Constructs an empty container with at least n buckets, using hf as the hash function and key_­equal() as the key equality predicate, and inserts elements from [i, j) into it.
Average case (N is distance(i, j)), worst case
X(i, j, n)
X a(i, j, n);
X
Requires: hasher and key_­equal are DefaultConstructible.
value_­type is EmplaceConstructible into X from *i.

Effects: Constructs an empty container with at least n buckets, using hasher() as the hash function and key_­equal() as the key equality predicate, and inserts elements from [i, j) into it.
Average case (N is distance(i, j)), worst case
X(i, j)
X a(i, j);
X
Requires: hasher and key_­equal are DefaultConstructible.
value_­type is EmplaceConstructible into X from *i.

Effects: Constructs an empty container with an unspecified number of buckets, using hasher() as the hash function and key_­equal() as the key equality predicate, and inserts elements from [i, j) into it.
Average case (N is distance(i, j)), worst case
X(il)
X
Same as X(il.begin(), il.end()).
Same as X(il.begin(), il.end()).
X(il, n)
X
Same as X(il.begin(), il.end(), n).
Same as X(il.begin(), il.end(), n).
X(il, n, hf)
X
Same as X(il.begin(), il.end(), n, hf).
Same as X(il.begin(), il.end(), n, hf).
X(il, n, hf, eq)
X
Same as X(il.begin(), il.end(), n, hf, eq).
Same as X(il.begin(), il.end(), n, hf, eq).
X(b)
X a(b);
X
Copy constructor.
In addition to the requirements of Table 78, copies the hash function, predicate, and maximum load factor.
Average case linear in b.size(), worst case quadratic.
a = b
X&
Copy assignment operator.
In addition to the requirements of Table 78, copies the hash function, predicate, and maximum load factor.
Average case linear in b.size(), worst case quadratic.
a = il
X&
Requires: value_­type is CopyInsertable into X and CopyAssignable.

Effects: Assigns the range [il.begin(), il.end()) into a.
All existing elements of a are either assigned to or destroyed.
Same as a = X(il).
b.hash_­function()
hasher
Returns b's hash function.
constant
b.key_­eq()
key_­equal
Returns b's key equality predicate.
constant
a_­uniq. emplace(args)
pair<iterator, bool>
Requires: value_­type shall be EmplaceConstructible into X from args.

Effects: Inserts a value_­type object t constructed with std​::​forward<​Args​>(​args)... if and only if there is no element in the container with key equivalent to the key of t.
The bool component of the returned pair is true if and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key of t.
Average case , worst case .
a_­eq.emplace(args)
iterator
Requires: value_­type shall be EmplaceConstructible into X from args.

Effects: Inserts a value_­type object t constructed with std​::​forward<​Args>(​args)... and returns the iterator pointing to the newly inserted element.
Average case , worst case .
a.emplace_­hint(p, args)
iterator
Requires: value_­type shall be EmplaceConstructible into X from args.

Effects: Equivalent to a.emplace( std​::​forward<​Args>(​args)...).
Return value is an iterator pointing to the element with the key equivalent to the newly inserted element.
The const_­iterator p is a hint pointing to where the search should start.
Implementations are permitted to ignore the hint.
Average case , worst case .
a_­uniq.insert(t)
pair<iterator, bool>
Requires: If t is a non-const rvalue expression, value_­type shall be MoveInsertable into X; otherwise, value_­type shall be CopyInsertable into X.

Effects: Inserts t if and only if there is no element in the container with key equivalent to the key of t.
The bool component of the returned pair indicates whether the insertion takes place, and the iterator component points to the element with key equivalent to the key of t.
Average case , worst case .
a_­eq.insert(t)
iterator
Requires: If t is a non-const rvalue expression, value_­type shall be MoveInsertable into X; otherwise, value_­type shall be CopyInsertable into X.

Effects: Inserts t, and returns an iterator pointing to the newly inserted element.
Average case , worst case .
a.insert(p, t)
iterator
Requires: If t is a non-const rvalue expression, value_­type shall be MoveInsertable into X; otherwise, value_­type shall be CopyInsertable into X.

Effects: Equivalent to a.
insert(t).
Return value is an iterator pointing to the element with the key equivalent to that of t.
The iterator p is a hint pointing to where the search should start.
Implementations are permitted to ignore the hint.
Average case , worst case .
a.insert(i, j)
void
Requires: value_­type shall be EmplaceConstructible into X from *i.

Requires: i and j are not iterators in a.
Equivalent to a.insert(t) for each element in [i,j).
Average case , where N is distance(i, j).
Worst case .
a.insert(il)
void
Same as a.insert(il.begin(), il.end()).
Same as a.insert( il.begin(), il.end()).
a_­uniq.
insert(nh)
insert_­return_­type
Requires: nh is empty or a_­uniq.get_­allocator() == nh.get_­allocator().

Effects: If nh is empty, has no effect.
Otherwise, inserts the element owned by nh if and only if there is no element in the container with a key equivalent to nh.key().

Postconditions: If nh is empty, inserted is false, position is end(), and node is empty.
Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty; if the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key().
Average case , worst case .
a_­eq.
insert(nh)
iterator
Requires: nh is empty or a_­eq.get_­allocator() == nh.get_­allocator().

Effects: If nh is empty, has no effect and returns a_­eq.end().
Otherwise, inserts the element owned by nh and returns an iterator pointing to the newly inserted element.

Postconditions: nh is empty.
Average case , worst case .
a.insert(q, nh)
iterator
Requires: nh is empty or a.get_­allocator() == nh.get_­allocator().

Effects: If nh is empty, has no effect and returns a.end().
Otherwise, inserts the element owned by nh if and only if there is no element with key equivalent to nh.key() in containers with unique keys; always inserts the element owned by nh in containers with equivalent keys.
Always returns the iterator pointing to the element with key equivalent to nh.key().
The iterator q is a hint pointing to where the search should start.
Implementations are permitted to ignore the hint.

Postconditions: nh is empty if insertion succeeds, unchanged if insertion fails.
Average case , worst case .
a.extract(k)
node_­type
Removes an element in the container with key equivalent to k.
Returns a node_­type owning the element if found, otherwise an empty node_­type.
Average case , worst case .
a.extract(q)
node_­type
Removes the element pointed to by q.
Returns a node_­type owning that element.
Average case , worst case .
a.merge(a2)
void
Requires: a.get_­allocator() == a2.get_­allocator().

Attempts to extract each element in a2 and insert it into a using the hash function and key equality predicate of a.
In containers with unique keys, if there is an element in a with key equivalent to the key of an element from a2, then that element is not extracted from a2.
Postconditions: Pointers and references to the transferred elements of a2 refer to those same elements but as members of a.
Iterators referring to the transferred elements and all iterators referring to a will be invalidated, but iterators to elements remaining in a2 will remain valid.

Throws: Nothing unless the hash function or key equality predicate throws.
Average case , where N is a2.size().
Worst case .
a.erase(k)
size_­type
Erases all elements with key equivalent to k.
Returns the number of elements erased.
Average case .
Worst case .
a.erase(q)
iterator
Erases the element pointed to by q.
Returns the iterator immediately following q prior to the erasure.
Average case , worst case .
a.erase(r)
iterator
Erases the element pointed to by r.
Returns the iterator immediately following r prior to the erasure.
Average case , worst case .
a.erase(q1, q2)
iterator
Erases all elements in the range [q1, q2).
Returns the iterator immediately following the erased elements prior to the erasure.
Average case linear in distance(q1, q2), worst case .
a.clear()
void
Erases all elements in the container.
Postconditions: a.empty() returns true
Linear in a.size().
b.find(k)
iterator;
const_­iterator for const b.
Returns an iterator pointing to an element with key equivalent to k, or b.end() if no such element exists.
Average case , worst case .
b.count(k)
size_­type
Returns the number of elements with key equivalent to k.
Average case , worst case .
b.equal_­range(k)
pair<iterator, iterator>;
pair<const_­iterator, const_­iterator> for const b.
Returns a range containing all elements with keys equivalent to k.
Returns make_­pair(b.end(), b.end()) if no such elements exist.
Average case .
Worst case .
b.bucket_­count()
size_­type
Returns the number of buckets that b contains.
Constant
b.max_­bucket_­count()
size_­type
Returns an upper bound on the number of buckets that b might ever contain.
Constant
b.bucket(k)
size_­type
Requires: b.bucket_­count() > 0.

Returns the index of the bucket in which elements with keys equivalent to k would be found, if any such element existed.
Postconditions: the return value shall be in the range [0, b.bucket_­count()).
Constant
b.bucket_­size(n)
size_­type
Requires: n shall be in the range [0, b.bucket_­count()).
Returns the number of elements in the bucket.
b.begin(n)
local_­iterator;
const_­local_­iterator for const b.
Requires: n shall be in the range [0, b.bucket_­count()).
b.begin(n) returns an iterator referring to the first element in the bucket.
If the bucket is empty, then b.begin(n) == b.end(n).
Constant
b.end(n)
local_­iterator;
const_­local_­iterator for const b.
Requires: n shall be in the range [0, b.bucket_­count()).
b.end(n) returns an iterator which is the past-the-end value for the bucket.
Constant
b.cbegin(n)
const_­local_­iterator
Requires: n shall be in the range [0, b.bucket_­count()).
Note: [b.cbegin(n), b.cend(n)) is a valid range containing all of the elements in the bucket.
Constant
b.cend(n)
const_­local_­iterator
Requires: n shall be in the range [0, b.bucket_­count()).
Constant
b.load_­factor()
float
Returns the average number of elements per bucket.
Constant
b.max_­load_­factor()
float
Returns a positive number that the container attempts to keep the load factor less than or equal to.
The container automatically increases the number of buckets as necessary to keep the load factor below this number.
Constant
a.max_­load_­factor(z)
void
Requires: z shall be positive.
May change the container's maximum load factor, using z as a hint.
Constant
a.rehash(n)
void
Postconditions: a.bucket_­count() >= a.size() / a.max_­load_­factor() and a.bucket_­count() >= n.
Average case linear in a.size(), worst case quadratic.
a.reserve(n)
void
Same as a.rehash(ceil(n / a.max_­load_­factor())).
Average case linear in a.size(), worst case quadratic.
Two unordered containers a and b compare equal if a.size() == b.size() and, for every equivalent-key group [Ea1, Ea2) obtained from a.equal_­range(Ea1), there exists an equivalent-key group [Eb1, Eb2) obtained from b.equal_­range(Ea1), such that is_­permutation(Ea1, Ea2, Eb1, Eb2) returns true.
For unordered_­set and unordered_­map, the complexity of operator== (i.e., the number of calls to the == operator of the value_­type, to the predicate returned by key_­eq(), and to the hasher returned by hash_­function()) is proportional to N in the average case and to in the worst case, where N is a.
size().
For unordered_­multiset and unordered_­multimap, the complexity of operator== is proportional to in the average case and to in the worst case, where N is a.size(), and is the size of the equivalent-key group in a.
However, if the respective elements of each corresponding pair of equivalent-key groups and are arranged in the same order (as is commonly the case, e.g., if a and b are unmodified copies of the same container), then the average-case complexity for unordered_­multiset and unordered_­multimap becomes proportional to N (but worst-case complexity remains , e.g., for a pathologically bad hash function). The behavior of a program that uses operator== or operator!= on unordered containers is undefined unless the Hash and Pred function objects respectively have the same behavior for both containers and the equality comparison function for Key is a refinement257 of the partition into equivalent-key groups produced by Pred.
The iterator types iterator and const_­iterator of an unordered associative container are of at least the forward iterator category.
For unordered associative containers where the key type and value type are the same, both iterator and const_­iterator are constant iterators.
The insert and emplace members shall not affect the validity of references to container elements, but may invalidate all iterators to the container.
The erase members shall invalidate only iterators and references to the erased elements, and preserve the relative order of the elements that are not erased.
The insert and emplace members shall not affect the validity of iterators if (N+n) <= z * B, where N is the number of elements in the container prior to the insert operation, n is the number of elements inserted, B is the container's bucket count, and z is the container's maximum load factor.
The extract members invalidate only iterators to the removed element, and preserve the relative order of the elements that are not erased; pointers and references to the removed element remain valid.
However, accessing the element through such pointers and references while the element is owned by a node_­type is undefined behavior.
References and pointers to an element obtained while it is owned by a node_­type are invalidated if the element is successfully inserted.
A deduction guide for an unordered associative container shall not participate in overload resolution if any of the following are true:
  • It has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter.
  • It has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
  • It has a Hash template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter.
  • It has a Pred template parameter and a type that qualifies as an allocator is deduced for that parameter.
Equality comparison is a refinement of partitioning if no two objects that compare equal fall into different partitions.

26.2.7.1 Exception safety guarantees [unord.req.except]

For unordered associative containers, no clear() function throws an exception.
erase(k) does not throw an exception unless that exception is thrown by the container's Hash or Pred object (if any).
For unordered associative containers, if an exception is thrown by any operation other than the container's hash function from within an insert or emplace function inserting a single element, the insertion has no effect.
For unordered associative containers, no swap function throws an exception unless that exception is thrown by the swap of the container's Hash or Pred object (if any).
For unordered associative containers, if an exception is thrown from within a rehash() function other than by the container's hash function or comparison function, the rehash() function has no effect.

26.3 Sequence containers [sequences]

26.3.1 In general [sequences.general]

The headers <array>, <deque>, <forward_­list>, <list>, and <vector> define class templates that meet the requirements for sequence containers.

26.3.2 Header <array> synopsis [array.syn]

#include <initializer_list>

namespace std {
  // [array], class template array
  template <class T, size_t N> struct array;
  template <class T, size_t N>
    bool operator==(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator!=(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator< (const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator> (const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator<=(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    bool operator>=(const array<T, N>& x, const array<T, N>& y);
  template <class T, size_t N>
    void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));

  template <class T> class tuple_size;
  template <size_t I, class T> class tuple_element;
  template <class T, size_t N>
    struct tuple_size<array<T, N>>;
  template <size_t I, class T, size_t N>
    struct tuple_element<I, array<T, N>>;
  template <size_t I, class T, size_t N>
    constexpr T& get(array<T, N>&) noexcept;
  template <size_t I, class T, size_t N>
    constexpr T&& get(array<T, N>&&) noexcept;
  template <size_t I, class T, size_t N>
    constexpr const T& get(const array<T, N>&) noexcept;
  template <size_t I, class T, size_t N>
    constexpr const T&& get(const array<T, N>&&) noexcept;
}

26.3.3 Header <deque> synopsis [deque.syn]

#include <initializer_list>

namespace std {
  // [deque], class template deque
  template <class T, class Allocator = allocator<T>> class deque;
  template <class T, class Allocator>
    bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class T>
      using deque = std::deque<T, polymorphic_allocator<T>>;
  }
}

26.3.4 Header <forward_­list> synopsis [forward_list.syn]

#include <initializer_list>

namespace std {
  // [forwardlist], class template forward_­list
  template <class T, class Allocator = allocator<T>> class forward_list;
  template <class T, class Allocator>
    bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class T>
      using forward_list = std::forward_list<T, polymorphic_allocator<T>>;
  }
}

26.3.5 Header <list> synopsis [list.syn]

#include <initializer_list>

namespace std {
  // [list], class template list
  template <class T, class Allocator = allocator<T>> class list;
  template <class T, class Allocator>
    bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(list<T, Allocator>& x, list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class T>
      using list = std::list<T, polymorphic_allocator<T>>;
  }
}

26.3.6 Header <vector> synopsis [vector.syn]

#include <initializer_list>

namespace std {
  // [vector], class template vector
  template <class T, class Allocator = allocator<T>> class vector;
  template <class T, class Allocator>
    bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  // [vector.bool], class vector<bool>
  template <class Allocator> class vector<bool, Allocator>;

  // hash support
  template <class T> struct hash;
  template <class Allocator> struct hash<vector<bool, Allocator>>;

  namespace pmr {
    template <class T>
      using vector = std::vector<T, polymorphic_allocator<T>>;
  }
}

26.3.7 Class template array [array]

26.3.7.1 Class template array overview [array.overview]

The header <array> defines a class template for storing fixed-size sequences of objects.
An array is a contiguous container ([container.requirements.general]).
An instance of array<T, N> stores N elements of type T, so that size() == N is an invariant.
An array is an aggregate ([dcl.init.aggr]) that can be list-initialized with up to N elements whose types are convertible to T.
An array satisfies all of the requirements of a container and of a reversible container ([container.requirements]), except that a default constructed array object is not empty and that swap does not have constant complexity.
An array satisfies some of the requirements of a sequence container ([sequence.reqmts]).
Descriptions are provided here only for operations on array that are not described in one of these tables and for operations where there is additional semantic information.
namespace std {
  template <class T, size_t N>
  struct array {
    //  types:
    using value_type             = T;
    using pointer                = T*;
    using const_pointer          = const T*;
    using reference              = T&;
    using const_reference        = const T&;
    using size_type              = size_t;
    using difference_type        = ptrdiff_t;
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // no explicit construct/copy/destroy for aggregate type

    void fill(const T& u);
    void swap(array&) noexcept(is_nothrow_swappable_v<T>);

    // iterators:
    constexpr iterator               begin() noexcept;
    constexpr const_iterator         begin() const noexcept;
    constexpr iterator               end() noexcept;
    constexpr const_iterator         end() const noexcept;

    constexpr reverse_iterator       rbegin() noexcept;
    constexpr const_reverse_iterator rbegin() const noexcept;
    constexpr reverse_iterator       rend() noexcept;
    constexpr const_reverse_iterator rend() const noexcept;

    constexpr const_iterator         cbegin() const noexcept;
    constexpr const_iterator         cend() const noexcept;
    constexpr const_reverse_iterator crbegin() const noexcept;
    constexpr const_reverse_iterator crend() const noexcept;

    // capacity:
    constexpr bool      empty() const noexcept;
    constexpr size_type size() const noexcept;
    constexpr size_type max_size() const noexcept;

    // element access:
    constexpr reference       operator[](size_type n);
    constexpr const_reference operator[](size_type n) const;
    constexpr reference       at(size_type n);
    constexpr const_reference at(size_type n) const;
    constexpr reference       front();
    constexpr const_reference front() const;
    constexpr reference       back();
    constexpr const_reference back() const;

    constexpr T *       data() noexcept;
    constexpr const T * data() const noexcept;
  };

  template<class T, class... U>
    array(T, U...) -> array<T, 1 + sizeof...(U)>;
}

26.3.7.2 array constructors, copy, and assignment [array.cons]

The conditions for an aggregate ([dcl.init.aggr]) shall be met.
Class array relies on the implicitly-declared special member functions ([class.ctor], [class.dtor], and [class.copy]) to conform to the container requirements table in [container.requirements].
In addition to the requirements specified in the container requirements table, the implicit move constructor and move assignment operator for array require that T be MoveConstructible or MoveAssignable, respectively.
template<class T, class... U> array(T, U...) -> array<T, 1 + sizeof...(U)>;
Requires: (is_­same_­v<T, U> && ...) is true.
Otherwise the program is ill-formed.

26.3.7.3 array specialized algorithms [array.special]

template <class T, size_t N> void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
Remarks: This function shall not participate in overload resolution unless N == 0 or is_­swappable_­v<T> is true.
Effects: As if by x.swap(y).
Complexity: Linear in N.

26.3.7.4 array​::​size [array.size]

template <class T, size_t N> constexpr size_type array<T, N>::size() const noexcept;
Returns: N.

26.3.7.5 array​::​data [array.data]

constexpr T* data() noexcept; constexpr const T* data() const noexcept;
Returns: A pointer such that data() == addressof(front()), and [data(), data() + size()) is a valid range.

26.3.7.6 array​::​fill [array.fill]

void fill(const T& u);
Effects: As if by fill_­n(begin(), N, u).

26.3.7.7 array​::​swap [array.swap]

void swap(array& y) noexcept(is_nothrow_swappable_v<T>);
Effects: Equivalent to swap_­ranges(begin(), end(), y.begin()).
[Note
:
Unlike the swap function for other containers, array​::​swap takes linear time, may exit via an exception, and does not cause iterators to become associated with the other container.
end note
]

26.3.7.8 Zero sized arrays [array.zero]

array shall provide support for the special case N == 0.
In the case that N == 0, begin() == end() == unique value.
The return value of data() is unspecified.
The effect of calling front() or back() for a zero-sized array is undefined.
Member function swap() shall have a non-throwing exception specification.

26.3.7.9 Tuple interface to class template array [array.tuple]

template <class T, size_t N> struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };
tuple_element<I, array<T, N>>::type
Requires: I < N.
The program is ill-formed if I is out of bounds.
Value: The type T.
template <size_t I, class T, size_t N> constexpr T& get(array<T, N>& a) noexcept; template <size_t I, class T, size_t N> constexpr T&& get(array<T, N>&& a) noexcept; template <size_t I, class T, size_t N> constexpr const T& get(const array<T, N>& a) noexcept; template <size_t I, class T, size_t N> constexpr const T&& get(const array<T, N>&& a) noexcept;
Requires: I < N.
The program is ill-formed if I is out of bounds.
Returns: A reference to the Ith element of a, where indexing is zero-based.

26.3.8 Class template deque [deque]

26.3.8.1 Class template deque overview [deque.overview]

A deque is a sequence container that supports random access iterators ([random.access.iterators]).
In addition, it supports constant time insert and erase operations at the beginning or the end; insert and erase in the middle take linear time.
That is, a deque is especially optimized for pushing and popping elements at the beginning and end.
Storage management is handled automatically.
A deque satisfies all of the requirements of a container, of a reversible container (given in tables in [container.requirements]), of a sequence container, including the optional sequence container requirements ([sequence.reqmts]), and of an allocator-aware container (Table 81).
Descriptions are provided here only for operations on deque that are not described in one of these tables or for operations where there is additional semantic information.
namespace std {
  template <class T, class Allocator = allocator<T>>
  class deque {
  public:
    // types:
    using value_type             = T;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // [deque.cons], construct/copy/destroy
    deque() : deque(Allocator()) { }
    explicit deque(const Allocator&);
    explicit deque(size_type n, const Allocator& = Allocator());
    deque(size_type n, const T& value, const Allocator& = Allocator());
    template <class InputIterator>
      deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
    deque(const deque& x);
    deque(deque&&);
    deque(const deque&, const Allocator&);
    deque(deque&&, const Allocator&);
    deque(initializer_list<T>, const Allocator& = Allocator());

    ~deque();
    deque& operator=(const deque& x);
    deque& operator=(deque&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    deque& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& t);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [deque.capacity], capacity
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    void      resize(size_type sz);
    void      resize(size_type sz, const T& c);
    void      shrink_to_fit();

    // element access:
    reference       operator[](size_type n);
    const_reference operator[](size_type n) const;
    reference       at(size_type n);
    const_reference at(size_type n) const;
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // [deque.modifiers], modifiers
    template <class... Args> reference emplace_front(Args&&... args);
    template <class... Args> reference emplace_back(Args&&... args);
    template <class... Args> iterator emplace(const_iterator position, Args&&... args);

    void push_front(const T& x);
    void push_front(T&& x);
    void push_back(const T& x);
    void push_back(T&& x);

    iterator insert(const_iterator position, const T& x);
    iterator insert(const_iterator position, T&& x);
    iterator insert(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert(const_iterator position, InputIterator first, InputIterator last);
    iterator insert(const_iterator position, initializer_list<T>);

    void pop_front();
    void pop_back();

    iterator erase(const_iterator position);
    iterator erase(const_iterator first, const_iterator last);
    void     swap(deque&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    void     clear() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    deque(InputIterator, InputIterator, Allocator = Allocator())
      -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y);

  // [deque.special], specialized algorithms
  template <class T, class Allocator>
    void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

26.3.8.2 deque constructors, copy, and assignment [deque.cons]

explicit deque(const Allocator&);
Effects: Constructs an empty deque, using the specified allocator.
Complexity: Constant.
explicit deque(size_type n, const Allocator& = Allocator());
Effects: Constructs a deque with n default-inserted elements using the specified allocator.
Requires: T shall be DefaultInsertable into *this.
Complexity: Linear in n.
deque(size_type n, const T& value, const Allocator& = Allocator());
Effects: Constructs a deque with n copies of value, using the specified allocator.
Requires: T shall be CopyInsertable into *this.
Complexity: Linear in n.
template <class InputIterator> deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a deque equal to the range [first, last), using the specified allocator.
Complexity: Linear in distance(first, last).

26.3.8.3 deque capacity [deque.capacity]

void resize(size_type sz);
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() default-inserted elements to the sequence.
Requires: T shall be MoveInsertable and DefaultInsertable into *this.
void resize(size_type sz, const T& c);
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() copies of c to the sequence.
Requires: T shall be CopyInsertable into *this.
void shrink_to_fit();
Requires: T shall be MoveInsertable into *this.
Effects: shrink_­to_­fit is a non-binding request to reduce memory use but does not change the size of the sequence.
[Note
:
The request is non-binding to allow latitude for implementation-specific optimizations.
end note
]
If an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no effects.
Complexity: Linear in the size of the sequence.
Remarks: shrink_­to_­fit invalidates all the references, pointers, and iterators referring to the elements in the sequence as well as the past-the-end iterator.

26.3.8.4 deque modifiers [deque.modifiers]

iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); template <class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list<T>); template <class... Args> reference emplace_front(Args&&... args); template <class... Args> reference emplace_back(Args&&... args); template <class... Args> iterator emplace(const_iterator position, Args&&... args); void push_front(const T& x); void push_front(T&& x); void push_back(const T& x); void push_back(T&& x);
Effects: An insertion in the middle of the deque invalidates all the iterators and references to elements of the deque.
An insertion at either end of the deque invalidates all the iterators to the deque, but has no effect on the validity of references to elements of the deque.
Remarks: If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T there are no effects.
If an exception is thrown while inserting a single element at either end, there are no effects.
Otherwise, if an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified.
Complexity: The complexity is linear in the number of elements inserted plus the lesser of the distances to the beginning and end of the deque.
Inserting a single element either at the beginning or end of a deque always takes constant time and causes a single call to a constructor of T.
iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_front(); void pop_back();
Effects: An erase operation that erases the last element of a deque invalidates only the past-the-end iterator and all iterators and references to the erased elements.
An erase operation that erases the first element of a deque but not the last element invalidates only iterators and references to the erased elements.
An erase operation that erases neither the first element nor the last element of a deque invalidates the past-the-end iterator and all iterators and references to all the elements of the deque.
[Note
:
pop_­front and pop_­back are erase operations.
end note
]
Complexity: The number of calls to the destructor of T is the same as the number of elements erased, but the number of calls to the assignment operator of T is no more than the lesser of the number of elements before the erased elements and the number of elements after the erased elements.
Throws: Nothing unless an exception is thrown by the copy constructor, move constructor, assignment operator, or move assignment operator of T.

26.3.8.5 deque specialized algorithms [deque.special]

template <class T, class Allocator> void swap(deque<T, Allocator>& x, deque<T, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.3.9 Class template forward_­list [forwardlist]

26.3.9.1 Class template forward_­list overview [forwardlist.overview]

A forward_­list is a container that supports forward iterators and allows constant time insert and erase operations anywhere within the sequence, with storage management handled automatically.
Fast random access to list elements is not supported.
[Note
:
It is intended that forward_­list have zero space or time overhead relative to a hand-written C-style singly linked list.
Features that would conflict with that goal have been omitted.
end note
]
A forward_­list satisfies all of the requirements of a container (Table 78), except that the size() member function is not provided and operator== has linear complexity.
A forward_­list also satisfies all of the requirements for an allocator-aware container (Table 81).
In addition, a forward_­list provides the assign member functions (Table 82) and several of the optional container requirements (Table 83).
Descriptions are provided here only for operations on forward_­list that are not described in that table or for operations where there is additional semantic information.
[Note
:
Modifying any list requires access to the element preceding the first element of interest, but in a forward_­list there is no constant-time way to access a preceding element.
For this reason, ranges that are modified, such as those supplied to erase and splice, must be open at the beginning.
end note
]
namespace std {
  template <class T, class Allocator = allocator<T>>
  class forward_list {
  public:
    // types:
    using value_type      = T;
    using allocator_type  = Allocator;
    using pointer         = typename allocator_traits<Allocator>::pointer;
    using const_pointer   = typename allocator_traits<Allocator>::const_pointer;
    using reference       = value_type&;
    using const_reference = const value_type&;
    using size_type       = implementation-defined; // see [container.requirements]
    using difference_type = implementation-defined; // see [container.requirements]
    using iterator        = implementation-defined; // see [container.requirements]
    using const_iterator  = implementation-defined; // see [container.requirements]

    // [forwardlist.cons], construct/copy/destroy
    forward_list() : forward_list(Allocator()) { }
    explicit forward_list(const Allocator&);
    explicit forward_list(size_type n, const Allocator& = Allocator());
    forward_list(size_type n, const T& value,
                 const Allocator& = Allocator());
    template <class InputIterator>
      forward_list(InputIterator first, InputIterator last,
                   const Allocator& = Allocator());
    forward_list(const forward_list& x);
    forward_list(forward_list&& x);
    forward_list(const forward_list& x, const Allocator&);
    forward_list(forward_list&& x, const Allocator&);
    forward_list(initializer_list<T>, const Allocator& = Allocator());
    ~forward_list();
    forward_list& operator=(const forward_list& x);
    forward_list& operator=(forward_list&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    forward_list& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& t);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // [forwardlist.iter], iterators
    iterator before_begin() noexcept;
    const_iterator before_begin() const noexcept;
    iterator begin() noexcept;
    const_iterator begin() const noexcept;
    iterator end() noexcept;
    const_iterator end() const noexcept;

    const_iterator cbegin() const noexcept;
    const_iterator cbefore_begin() const noexcept;
    const_iterator cend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type max_size() const noexcept;

    // [forwardlist.access], element access
    reference front();
    const_reference front() const;

    // [forwardlist.modifiers], modifiers
    template <class... Args> reference emplace_front(Args&&... args);
    void push_front(const T& x);
    void push_front(T&& x);
    void pop_front();

    template <class... Args> iterator emplace_after(const_iterator position, Args&&... args);
    iterator insert_after(const_iterator position, const T& x);
    iterator insert_after(const_iterator position, T&& x);

    iterator insert_after(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
    iterator insert_after(const_iterator position, initializer_list<T> il);

    iterator erase_after(const_iterator position);
    iterator erase_after(const_iterator position, const_iterator last);
    void swap(forward_list&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);

    void resize(size_type sz);
    void resize(size_type sz, const value_type& c);
    void clear() noexcept;

    // [forwardlist.ops], forward_­list operations
    void splice_after(const_iterator position, forward_list& x);
    void splice_after(const_iterator position, forward_list&& x);
    void splice_after(const_iterator position, forward_list& x,
                      const_iterator i);
    void splice_after(const_iterator position, forward_list&& x,
                      const_iterator i);
    void splice_after(const_iterator position, forward_list& x,
                      const_iterator first, const_iterator last);
    void splice_after(const_iterator position, forward_list&& x,
                      const_iterator first, const_iterator last);

    void remove(const T& value);
    template <class Predicate> void remove_if(Predicate pred);

    void unique();
    template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);

    void merge(forward_list& x);
    void merge(forward_list&& x);
    template <class Compare> void merge(forward_list& x, Compare comp);
    template <class Compare> void merge(forward_list&& x, Compare comp);

    void sort();
    template <class Compare> void sort(Compare comp);

    void reverse() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    forward_list(InputIterator, InputIterator, Allocator = Allocator())
      -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y);

  // [forwardlist.spec], specialized algorithms
  template <class T, class Allocator>
    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}
An incomplete type T may be used when instantiating forward_­list if the allocator satisfies the allocator completeness requirements ([allocator.requirements.completeness]).
T shall be complete before any member of the resulting specialization of forward_­list is referenced.

26.3.9.2 forward_­list constructors, copy, assignment [forwardlist.cons]

explicit forward_list(const Allocator&);
Effects: Constructs an empty forward_­list object using the specified allocator.
Complexity: Constant.
explicit forward_list(size_type n, const Allocator& = Allocator());
Effects: Constructs a forward_­list object with n default-inserted elements using the specified allocator.
Requires: T shall be DefaultInsertable into *this.
Complexity: Linear in n.
forward_list(size_type n, const T& value, const Allocator& = Allocator());
Effects: Constructs a forward_­list object with n copies of value using the specified allocator.
Requires: T shall be CopyInsertable into *this.
Complexity: Linear in n.
template <class InputIterator> forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a forward_­list object equal to the range [first, last).
Complexity: Linear in distance(first, last).

26.3.9.3 forward_­list iterators [forwardlist.iter]

iterator before_begin() noexcept; const_iterator before_begin() const noexcept; const_iterator cbefore_begin() const noexcept;
Returns: A non-dereferenceable iterator that, when incremented, is equal to the iterator returned by begin().
Effects: cbefore_­begin() is equivalent to const_­cast<forward_­list const&>(*this).before_­begin().
Remarks: before_­begin() == end() shall equal false.

26.3.9.4 forward_­list element access [forwardlist.access]

reference front(); const_reference front() const;
Returns: *begin()

26.3.9.5 forward_­list modifiers [forwardlist.modifiers]

None of the overloads of insert_­after shall affect the validity of iterators and references, and erase_­after shall invalidate only iterators and references to the erased elements.
If an exception is thrown during insert_­after there shall be no effect.
Inserting n elements into a forward_­list is linear in n, and the number of calls to the copy or move constructor of T is exactly equal to n.
Erasing n elements from a forward_­list is linear in n and the number of calls to the destructor of type T is exactly equal to n.
template <class... Args> reference emplace_front(Args&&... args);
Effects: Inserts an object of type value_­type constructed with value_­type(std​::​forward<Args>(​args)...) at the beginning of the list.
void push_front(const T& x); void push_front(T&& x);
Effects: Inserts a copy of x at the beginning of the list.
void pop_front();
Effects: As if by erase_­after(before_­begin()).
iterator insert_after(const_iterator position, const T& x); iterator insert_after(const_iterator position, T&& x);
Requires: position is before_­begin() or is a dereferenceable iterator in the range [begin(), end()).
Effects: Inserts a copy of x after position.
Returns: An iterator pointing to the copy of x.
iterator insert_after(const_iterator position, size_type n, const T& x);
Requires: position is before_­begin() or is a dereferenceable iterator in the range [begin(), end()).
Effects: Inserts n copies of x after position.
Returns: An iterator pointing to the last inserted copy of x or position if n == 0.
template <class InputIterator> iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
Requires: position is before_­begin() or is a dereferenceable iterator in the range [begin(), end()).
first and last are not iterators in *this.
Effects: Inserts copies of elements in [first, last) after position.
Returns: An iterator pointing to the last inserted element or position if first == last.
iterator insert_after(const_iterator position, initializer_list<T> il);
Effects: insert_­after(p, il.begin(), il.end()).
Returns: An iterator pointing to the last inserted element or position if il is empty.
template <class... Args> iterator emplace_after(const_iterator position, Args&&... args);
Requires: position is before_­begin() or is a dereferenceable iterator in the range [begin(), end()).
Effects: Inserts an object of type value_­type constructed with value_­type(std​::​forward<Args>(​args)...) after position.
Returns: An iterator pointing to the new object.
iterator erase_after(const_iterator position);
Requires: The iterator following position is dereferenceable.
Effects: Erases the element pointed to by the iterator following position.
Returns: An iterator pointing to the element following the one that was erased, or end() if no such element exists.
Throws: Nothing.
iterator erase_after(const_iterator position, const_iterator last);
Requires: All iterators in the range (position, last) are dereferenceable.
Effects: Erases the elements in the range (position, last).
Returns: last.
Throws: Nothing.
void resize(size_type sz);
Effects: If sz < distance(begin(), end()), erases the last distance(begin(), end()) - sz elements from the list.
Otherwise, inserts sz - distance(begin(), end()) default-inserted elements at the end of the list.
Requires: T shall be DefaultInsertable into *this.
void resize(size_type sz, const value_type& c);
Effects: If sz < distance(begin(), end()), erases the last distance(begin(), end()) - sz elements from the list.
Otherwise, inserts sz - distance(begin(), end()) copies of c at the end of the list.
Requires: T shall be CopyInsertable into *this.
void clear() noexcept;
Effects: Erases all elements in the range [begin(), end()).
Remarks: Does not invalidate past-the-end iterators.

26.3.9.6 forward_­list operations [forwardlist.ops]

void splice_after(const_iterator position, forward_list& x); void splice_after(const_iterator position, forward_list&& x);
Requires: position is before_­begin() or is a dereferenceable iterator in the range [begin(), end()).
get_­allocator() == x.get_­allocator().
&x != this.
Effects: Inserts the contents of x after position, and x becomes empty.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity:
void splice_after(const_iterator position, forward_list& x, const_iterator i); void splice_after(const_iterator position, forward_list&& x, const_iterator i);
Requires: position is before_­begin() or is a dereferenceable iterator in the range [begin(), end()).
The iterator following i is a dereferenceable iterator in x.
get_­allocator() == x.get_­allocator().
Effects: Inserts the element following i into *this, following position, and removes it from x.
The result is unchanged if position == i or position == ++i.
Pointers and references to *++i continue to refer to the same element but as a member of *this.
Iterators to *++i continue to refer to the same element, but now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity:
void splice_after(const_iterator position, forward_list& x, const_iterator first, const_iterator last); void splice_after(const_iterator position, forward_list&& x, const_iterator first, const_iterator last);
Requires: position is before_­begin() or is a dereferenceable iterator in the range [begin(), end()).
(first, last) is a valid range in x, and all iterators in the range (first, last) are dereferenceable.
position is not an iterator in the range (first, last).
get_­allocator() == x.get_­allocator().
Effects: Inserts elements in the range (first, last) after position and removes the elements from x.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Complexity:
void remove(const T& value); template <class Predicate> void remove_if(Predicate pred);
Effects: Erases all the elements in the list referred by a list iterator i for which the following conditions hold: *i == value (for remove()), pred(*i) is true (for remove_­if()).
Invalidates only the iterators and references to the erased elements.
Throws: Nothing unless an exception is thrown by the equality comparison or the predicate.
Remarks: Stable ([algorithm.stable]).
Complexity: Exactly distance(begin(), end()) applications of the corresponding predicate.
void unique(); template <class BinaryPredicate> void unique(BinaryPredicate pred);
Effects: Erases all but the first element from every consecutive group of equal elements referred to by the iterator i in the range [first + 1, last) for which *i == *(i-1) (for the version with no arguments) or pred(*i, *(i - 1)) (for the version with a predicate argument) holds.
Invalidates only the iterators and references to the erased elements.
Throws: Nothing unless an exception is thrown by the equality comparison or the predicate.
Complexity: If the range [first, last) is not empty, exactly (last - first) - 1 applications of the corresponding predicate, otherwise no applications of the predicate.
void merge(forward_list& x); void merge(forward_list&& x); template <class Compare> void merge(forward_list& x, Compare comp); template <class Compare> void merge(forward_list&& x, Compare comp);
Requires: comp defines a strict weak ordering ([alg.sorting]), and *this and x are both sorted according to this ordering.
get_­allocator() == x.get_­allocator().
Effects: Merges the two sorted ranges [begin(), end()) and [x.begin(), x.end()).
x is empty after the merge.
If an exception is thrown other than by a comparison there are no effects.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Remarks: Stable ([algorithm.stable]).
The behavior is undefined if get_­allocator() != x.get_­allocator().
Complexity: At most distance(begin(), end()) + distance(x.begin(), x.end()) - 1 comparisons.
void sort(); template <class Compare> void sort(Compare comp);
Requires: operator< (for the version with no arguments) or comp (for the version with a comparison argument) defines a strict weak ordering ([alg.sorting]).
Effects: Sorts the list according to the operator< or the comp function object.
If an exception is thrown, the order of the elements in *this is unspecified.
Does not affect the validity of iterators and references.
Remarks: Stable ([algorithm.stable]).
Complexity: Approximately comparisons, where N is distance(begin(), end()).
void reverse() noexcept;
Effects: Reverses the order of the elements in the list.
Does not affect the validity of iterators and references.
Complexity: Linear time.

26.3.9.7 forward_­list specialized algorithms [forwardlist.spec]

template <class T, class Allocator> void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.3.10 Class template list [list]

26.3.10.1 Class template list overview [list.overview]

A list is a sequence container that supports bidirectional iterators and allows constant time insert and erase operations anywhere within the sequence, with storage management handled automatically.
Unlike vectors ([vector]) and deques ([deque]), fast random access to list elements is not supported, but many algorithms only need sequential access anyway.
A list satisfies all of the requirements of a container, of a reversible container (given in two tables in [container.requirements]), of a sequence container, including most of the optional sequence container requirements ([sequence.reqmts]), and of an allocator-aware container (Table 81).
The exceptions are the operator[] and at member functions, which are not provided.258
Descriptions are provided here only for operations on list that are not described in one of these tables or for operations where there is additional semantic information.
namespace std {
  template <class T, class Allocator = allocator<T>>
  class list {
  public:
    // types:
    using value_type             = T;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // [list.cons], construct/copy/destroy
    list() : list(Allocator()) { }
    explicit list(const Allocator&);
    explicit list(size_type n, const Allocator& = Allocator());
    list(size_type n, const T& value, const Allocator& = Allocator());
    template <class InputIterator>
      list(InputIterator first, InputIterator last, const Allocator& = Allocator());
    list(const list& x);
    list(list&& x);
    list(const list&, const Allocator&);
    list(list&&, const Allocator&);
    list(initializer_list<T>, const Allocator& = Allocator());
    ~list();
    list& operator=(const list& x);
    list& operator=(list&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    list& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& t);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [list.capacity], capacity
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    void      resize(size_type sz);
    void      resize(size_type sz, const T& c);

    // element access:
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // [list.modifiers], modifiers
    template <class... Args> reference emplace_front(Args&&... args);
    template <class... Args> reference emplace_back(Args&&... args);
    void push_front(const T& x);
    void push_front(T&& x);
    void pop_front();
    void push_back(const T& x);
    void push_back(T&& x);
    void pop_back();

    template <class... Args> iterator emplace(const_iterator position, Args&&... args);
    iterator insert(const_iterator position, const T& x);
    iterator insert(const_iterator position, T&& x);
    iterator insert(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert(const_iterator position, InputIterator first,
                      InputIterator last);
    iterator insert(const_iterator position, initializer_list<T> il);

    iterator erase(const_iterator position);
    iterator erase(const_iterator position, const_iterator last);
    void     swap(list&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value);
    void     clear() noexcept;

    // [list.ops], list operations
    void splice(const_iterator position, list& x);
    void splice(const_iterator position, list&& x);
    void splice(const_iterator position, list& x, const_iterator i);
    void splice(const_iterator position, list&& x, const_iterator i);
    void splice(const_iterator position, list& x,
                const_iterator first, const_iterator last);
    void splice(const_iterator position, list&& x,
                const_iterator first, const_iterator last);

    void remove(const T& value);
    template <class Predicate> void remove_if(Predicate pred);

    void unique();
    template <class BinaryPredicate>
      void unique(BinaryPredicate binary_pred);

    void merge(list& x);
    void merge(list&& x);
    template <class Compare> void merge(list& x, Compare comp);
    template <class Compare> void merge(list&& x, Compare comp);

    void sort();
    template <class Compare> void sort(Compare comp);

    void reverse() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    list(InputIterator, InputIterator, Allocator = Allocator())
      -> list<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const list<T, Allocator>& x, const list<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const list<T, Allocator>& x, const list<T, Allocator>& y);

  // [list.special], specialized algorithms
  template <class T, class Allocator>
    void swap(list<T, Allocator>& x, list<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}
An incomplete type T may be used when instantiating list if the allocator satisfies the allocator completeness requirements ([allocator.requirements.completeness]).
T shall be complete before any member of the resulting specialization of list is referenced.
These member functions are only provided by containers whose iterators are random access iterators.

26.3.10.2 list constructors, copy, and assignment [list.cons]

explicit list(const Allocator&);
Effects: Constructs an empty list, using the specified allocator.
Complexity: Constant.
explicit list(size_type n, const Allocator& = Allocator());
Effects: Constructs a list with n default-inserted elements using the specified allocator.
Requires: T shall be DefaultInsertable into *this.
Complexity: Linear in n.
list(size_type n, const T& value, const Allocator& = Allocator());
Effects: Constructs a list with n copies of value, using the specified allocator.
Requires: T shall be CopyInsertable into *this.
Complexity: Linear in n.
template <class InputIterator> list(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a list equal to the range [first, last).
Complexity: Linear in distance(first, last).

26.3.10.3 list capacity [list.capacity]

void resize(size_type sz);
Effects: If size() < sz, appends sz - size() default-inserted elements to the sequence.
If sz <= size(), equivalent to:
list<T>::iterator it = begin();
advance(it, sz);
erase(it, end());
Requires: T shall be DefaultInsertable into *this.
void resize(size_type sz, const T& c);
Effects: As if by:
if (sz > size())
  insert(end(), sz-size(), c);
else if (sz < size()) {
  iterator i = begin();
  advance(i, sz);
  erase(i, end());
}
else
  ;                 // do nothing
Requires: T shall be CopyInsertable into *this.

26.3.10.4 list modifiers [list.modifiers]

iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); template <class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list<T>); template <class... Args> reference emplace_front(Args&&... args); template <class... Args> reference emplace_back(Args&&... args); template <class... Args> iterator emplace(const_iterator position, Args&&... args); void push_front(const T& x); void push_front(T&& x); void push_back(const T& x); void push_back(T&& x);
Remarks: Does not affect the validity of iterators and references.
If an exception is thrown there are no effects.
Complexity: Insertion of a single element into a list takes constant time and exactly one call to a constructor of T.
Insertion of multiple elements into a list is linear in the number of elements inserted, and the number of calls to the copy constructor or move constructor of T is exactly equal to the number of elements inserted.
iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_front(); void pop_back(); void clear() noexcept;
Effects: Invalidates only the iterators and references to the erased elements.
Throws: Nothing.
Complexity: Erasing a single element is a constant time operation with a single call to the destructor of T.
Erasing a range in a list is linear time in the size of the range and the number of calls to the destructor of type T is exactly equal to the size of the range.

26.3.10.5 list operations [list.ops]

Since lists allow fast insertion and erasing from the middle of a list, certain operations are provided specifically for them.259
list provides three splice operations that destructively move elements from one list to another.
The behavior of splice operations is undefined if get_­allocator() != x.get_­allocator().
void splice(const_iterator position, list& x); void splice(const_iterator position, list&& x);
Requires: &x != this.
Effects: Inserts the contents of x before position and x becomes empty.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity: Constant time.
void splice(const_iterator position, list& x, const_iterator i); void splice(const_iterator position, list&& x, const_iterator i);
Requires: i is a valid dereferenceable iterator of x.
Effects: Inserts an element pointed to by i from list x before position and removes the element from x.
The result is unchanged if position == i or position == ++i.
Pointers and references to *i continue to refer to this same element but as a member of *this.
Iterators to *i (including i itself) continue to refer to the same element, but now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity: Constant time.
void splice(const_iterator position, list& x, const_iterator first, const_iterator last); void splice(const_iterator position, list&& x, const_iterator first, const_iterator last);
Requires: [first, last) is a valid range in x.
The program has undefined behavior if position is an iterator in the range [first, last).
Effects: Inserts elements in the range [first, last) before position and removes the elements from x.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Throws: Nothing.
Complexity: Constant time if &x == this; otherwise, linear time.
void remove(const T& value); template <class Predicate> void remove_if(Predicate pred);
Effects: Erases all the elements in the list referred by a list iterator i for which the following conditions hold: *i == value, pred(*i) != false.
Invalidates only the iterators and references to the erased elements.
Throws: Nothing unless an exception is thrown by *i == value or pred(*i) != false.
Remarks: Stable ([algorithm.stable]).
Complexity: Exactly size() applications of the corresponding predicate.
void unique(); template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
Effects: Erases all but the first element from every consecutive group of equal elements referred to by the iterator i in the range [first + 1, last) for which *i == *(i-1) (for the version of unique with no arguments) or pred(*i, *(i - 1)) (for the version of unique with a predicate argument) holds.
Invalidates only the iterators and references to the erased elements.
Throws: Nothing unless an exception is thrown by *i == *(i-1) or pred(*i, *(i - 1))
Complexity: If the range [first, last) is not empty, exactly (last - first) - 1 applications of the corresponding predicate, otherwise no applications of the predicate.
void merge(list& x); void merge(list&& x); template <class Compare> void merge(list& x, Compare comp); template <class Compare> void merge(list&& x, Compare comp);
Requires: comp shall define a strict weak ordering ([alg.sorting]), and both the list and the argument list shall be sorted according to this ordering.
Effects: If (&x == this) does nothing; otherwise, merges the two sorted ranges [begin(), end()) and [x.​begin(), x.end()).
The result is a range in which the elements will be sorted in non-decreasing order according to the ordering defined by comp; that is, for every iterator i, in the range other than the first, the condition comp(*i, *(i - 1)) will be false.
Pointers and references to the moved elements of x now refer to those same elements but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.
Remarks: Stable ([algorithm.stable]).
If (&x != this) the range [x.begin(), x.end()) is empty after the merge.
No elements are copied by this operation.
The behavior is undefined if get_­allocator() != x.get_­allocator().
Complexity: At most size() + x.size() - 1 applications of comp if (&x != this); otherwise, no applications of comp are performed.
If an exception is thrown other than by a comparison there are no effects.
void reverse() noexcept;
Effects: Reverses the order of the elements in the list.
Does not affect the validity of iterators and references.
Complexity: Linear time.
void sort(); template <class Compare> void sort(Compare comp);
Requires: operator< (for the first version) or comp (for the second version) shall define a strict weak ordering ([alg.sorting]).
Effects: Sorts the list according to the operator< or a Compare function object.
If an exception is thrown, the order of the elements in *this is unspecified.
Does not affect the validity of iterators and references.
Remarks: Stable ([algorithm.stable]).
Complexity: Approximately comparisons, where N == size().
As specified in [allocator.requirements], the requirements in this Clause apply only to lists whose allocators compare equal.

26.3.10.6 list specialized algorithms [list.special]

template <class T, class Allocator> void swap(list<T, Allocator>& x, list<T, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.3.11 Class template vector [vector]

26.3.11.1 Class template vector overview [vector.overview]

A vector is a sequence container that supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time.
Storage management is handled automatically, though hints can be given to improve efficiency.
A vector satisfies all of the requirements of a container and of a reversible container (given in two tables in [container.requirements]), of a sequence container, including most of the optional sequence container requirements ([sequence.reqmts]), of an allocator-aware container (Table 81), and, for an element type other than bool, of a contiguous container ([container.requirements.general]).
The exceptions are the push_­front, pop_­front, and emplace_­front member functions, which are not provided.
Descriptions are provided here only for operations on vector that are not described in one of these tables or for operations where there is additional semantic information.
namespace std {
  template <class T, class Allocator = allocator<T>>
  class vector {
  public:
    // types:
    using value_type             = T;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // [vector.cons], construct/copy/destroy
    vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
    explicit vector(const Allocator&) noexcept;
    explicit vector(size_type n, const Allocator& = Allocator());
    vector(size_type n, const T& value, const Allocator& = Allocator());
    template <class InputIterator>
      vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
    vector(const vector& x);
    vector(vector&&) noexcept;
    vector(const vector&, const Allocator&);
    vector(vector&&, const Allocator&);
    vector(initializer_list<T>, const Allocator& = Allocator());
    ~vector();
    vector& operator=(const vector& x);
    vector& operator=(vector&& x)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    vector& operator=(initializer_list<T>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const T& u);
    void assign(initializer_list<T>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [vector.capacity], capacity
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    size_type capacity() const noexcept;
    void      resize(size_type sz);
    void      resize(size_type sz, const T& c);
    void      reserve(size_type n);
    void      shrink_to_fit();

    // element access:
    reference       operator[](size_type n);
    const_reference operator[](size_type n) const;
    const_reference at(size_type n) const;
    reference       at(size_type n);
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // [vector.data], data access
    T*       data() noexcept;
    const T* data() const noexcept;

    // [vector.modifiers], modifiers
    template <class... Args> reference emplace_back(Args&&... args);
    void push_back(const T& x);
    void push_back(T&& x);
    void pop_back();

    template <class... Args> iterator emplace(const_iterator position, Args&&... args);
    iterator insert(const_iterator position, const T& x);
    iterator insert(const_iterator position, T&& x);
    iterator insert(const_iterator position, size_type n, const T& x);
    template <class InputIterator>
      iterator insert(const_iterator position, InputIterator first, InputIterator last);
    iterator insert(const_iterator position, initializer_list<T> il);
    iterator erase(const_iterator position);
    iterator erase(const_iterator first, const_iterator last);
    void     swap(vector&)
      noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    void     clear() noexcept;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    vector(InputIterator, InputIterator, Allocator = Allocator())
      -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>;

  template <class T, class Allocator>
    bool operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator!=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator> (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator>=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);
  template <class T, class Allocator>
    bool operator<=(const vector<T, Allocator>& x, const vector<T, Allocator>& y);

  // [vector.special], specialized algorithms
  template <class T, class Allocator>
    void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}
An incomplete type T may be used when instantiating vector if the allocator satisfies the allocator completeness requirements ([allocator.requirements.completeness]).
T shall be complete before any member of the resulting specialization of vector is referenced.

26.3.11.2 vector constructors, copy, and assignment [vector.cons]

explicit vector(const Allocator&);
Effects: Constructs an empty vector, using the specified allocator.
Complexity: Constant.
explicit vector(size_type n, const Allocator& = Allocator());
Effects: Constructs a vector with n default-inserted elements using the specified allocator.
Requires: T shall be DefaultInsertable into *this.
Complexity: Linear in n.
vector(size_type n, const T& value, const Allocator& = Allocator());
Effects: Constructs a vector with n copies of value, using the specified allocator.
Requires: T shall be CopyInsertable into *this.
Complexity: Linear in n.
template <class InputIterator> vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
Effects: Constructs a vector equal to the range [first, last), using the specified allocator.
Complexity: Makes only N calls to the copy constructor of T (where N is the distance between first and last) and no reallocations if iterators first and last are of forward, bidirectional, or random access categories.
It makes order N calls to the copy constructor of T and order logN reallocations if they are just input iterators.

26.3.11.3 vector capacity [vector.capacity]

size_type capacity() const noexcept;
Returns: The total number of elements that the vector can hold without requiring reallocation.
void reserve(size_type n);
Requires: T shall be MoveInsertable into *this.
Effects: A directive that informs a vector of a planned change in size, so that it can manage the storage allocation accordingly.
After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise.
Reallocation happens at this point if and only if the current capacity is less than the argument of reserve().
If an exception is thrown other than by the move constructor of a non-CopyInsertable type, there are no effects.
Complexity: It does not change the size of the sequence and takes at most linear time in the size of the sequence.
Throws: length_­error if n > max_­size().260
Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence.
No reallocation shall take place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the value of capacity().
void shrink_to_fit();
Requires: T shall be MoveInsertable into *this.
Effects: shrink_­to_­fit is a non-binding request to reduce capacity() to size().
[Note
:
The request is non-binding to allow latitude for implementation-specific optimizations.
end note
]
It does not increase capacity(), but may reduce capacity() by causing reallocation.
If an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no effects.
Complexity: Linear in the size of the sequence.
Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence as well as the past-the-end iterator.
If no reallocation happens, they remain valid.
void swap(vector& x) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Exchanges the contents and capacity() of *this with that of x.
Complexity: Constant time.
void resize(size_type sz);
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() default-inserted elements to the sequence.
Requires: T shall be MoveInsertable and DefaultInsertable into *this.
Remarks: If an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no effects.
void resize(size_type sz, const T& c);
Effects: If sz < size(), erases the last size() - sz elements from the sequence.
Otherwise, appends sz - size() copies of c to the sequence.
Requires: T shall be CopyInsertable into *this.
Remarks: If an exception is thrown there are no effects.
reserve() uses Allocator​::​allocate() which may throw an appropriate exception.

26.3.11.4 vector data [vector.data]

T* data() noexcept; const T* data() const noexcept;
Returns: A pointer such that [data(), data() + size()) is a valid range.
For a non-empty vector, data() == addressof(front()).
Complexity: Constant time.

26.3.11.5 vector modifiers [vector.modifiers]

iterator insert(const_iterator position, const T& x); iterator insert(const_iterator position, T&& x); iterator insert(const_iterator position, size_type n, const T& x); template <class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last); iterator insert(const_iterator position, initializer_list<T>); template <class... Args> reference emplace_back(Args&&... args); template <class... Args> iterator emplace(const_iterator position, Args&&... args); void push_back(const T& x); void push_back(T&& x);
Remarks: Causes reallocation if the new size is greater than the old capacity.
Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence.
If no reallocation happens, all the iterators and references before the insertion point remain valid.
If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T or by any InputIterator operation there are no effects.
If an exception is thrown while inserting a single element at the end and T is CopyInsertable or is_­nothrow_­move_­constructible_­v<T> is true, there are no effects.
Otherwise, if an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified.
Complexity: The complexity is linear in the number of elements inserted plus the distance to the end of the vector.
iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_back();
Effects: Invalidates iterators and references at or after the point of the erase.
Complexity: The destructor of T is called the number of times equal to the number of the elements erased, but the assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements.
Throws: Nothing unless an exception is thrown by the assignment operator or move assignment operator of T.

26.3.11.6 vector specialized algorithms [vector.special]

template <class T, class Allocator> void swap(vector<T, Allocator>& x, vector<T, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.3.12 Class vector<bool> [vector.bool]

To optimize space allocation, a specialization of vector for bool elements is provided:
namespace std {
  template <class Allocator>
  class vector<bool, Allocator> {
  public:
    // types:
    using value_type             = bool;
    using allocator_type         = Allocator;
    using pointer                = implementation-defined;
    using const_pointer          = implementation-defined;
    using const_reference        = bool;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // bit reference:
    class reference {
      friend class vector;
      reference() noexcept;
    public:
      ~reference();
      operator bool() const noexcept;
      reference& operator=(const bool x) noexcept;
      reference& operator=(const reference& x) noexcept;
      void flip() noexcept;     // flips the bit
    };

    // construct/copy/destroy:
    vector() : vector(Allocator()) { }
    explicit vector(const Allocator&);
    explicit vector(size_type n, const Allocator& = Allocator());
    vector(size_type n, const bool& value,
           const Allocator& = Allocator());
    template <class InputIterator>
      vector(InputIterator first, InputIterator last,
             const Allocator& = Allocator());
    vector(const vector<bool, Allocator>& x);
    vector(vector<bool, Allocator>&& x);
    vector(const vector&, const Allocator&);
    vector(vector&&, const Allocator&);
    vector(initializer_list<bool>, const Allocator& = Allocator()));
    ~vector();
    vector<bool, Allocator>& operator=(const vector<bool, Allocator>& x);
    vector<bool, Allocator>& operator=(vector<bool, Allocator>&& x);
    vector& operator=(initializer_list<bool>);
    template <class InputIterator>
      void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const bool& t);
    void assign(initializer_list<bool>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;
    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    size_type capacity() const noexcept;
    void      resize(size_type sz, bool c = false);
    void      reserve(size_type n);
    void      shrink_to_fit();

    // element access:
    reference       operator[](size_type n);
    const_reference operator[](size_type n) const;
    const_reference at(size_type n) const;
    reference       at(size_type n);
    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back() const;

    // modifiers:
    template <class... Args> reference emplace_back(Args&&... args);
    void push_back(const bool& x);
    void pop_back();
    template <class... Args> iterator emplace(const_iterator position, Args&&... args);
    iterator insert(const_iterator position, const bool& x);
    iterator insert(const_iterator position, size_type n, const bool& x);
    template <class InputIterator>
      iterator insert(const_iterator position,
                      InputIterator first, InputIterator last);
    iterator insert(const_iterator position, initializer_list<bool> il);

    iterator erase(const_iterator position);
    iterator erase(const_iterator first, const_iterator last);
    void swap(vector<bool, Allocator>&);
    static void swap(reference x, reference y) noexcept;
    void flip() noexcept;       // flips all bits
    void clear() noexcept;
  };
}
Unless described below, all operations have the same requirements and semantics as the primary vector template, except that operations dealing with the bool value type map to bit values in the container storage and allocator_­traits​::​construct ([allocator.traits.members]) is not used to construct these values.
There is no requirement that the data be stored as a contiguous allocation of bool values.
A space-optimized representation of bits is recommended instead.
reference is a class that simulates the behavior of references of a single bit in vector<bool>.
The conversion function returns true when the bit is set, and false otherwise.
The assignment operator sets the bit when the argument is (convertible to) true and clears it otherwise.
flip reverses the state of the bit.
void flip() noexcept;
Effects: Replaces each element in the container with its complement.
static void swap(reference x, reference y) noexcept;
Effects: Exchanges the contents of x and y as if by:
bool b = x;
x = y;
y = b;
template <class Allocator> struct hash<vector<bool, Allocator>>;
The specialization is enabled ([unord.hash]).

26.4 Associative containers [associative]

26.4.1 In general [associative.general]

The header <map> defines the class templates map and multimap; the header <set> defines the class templates set and multiset.
The following exposition-only alias templates may appear in deduction guides for associative containers:
template<class InputIterator>
  using iter_key_t = remove_const_t<
    typename iterator_traits<InputIterator>::value_type::first_type>; // exposition only
template<class InputIterator>
  using iter_val_t
    = typename iterator_traits<InputIterator>::value_type::second_type; // exposition only
template<class InputIterator>
  using iter_to_alloc_t
    = pair<add_const_t<typename iterator_traits<InputIterator>::value_type::first_type>,
           typename iterator_traits<InputIterator>::value_type::second_type>; // exposition only

26.4.2 Header <map> synopsis [associative.map.syn]

#include <initializer_list>

namespace std {
  // [map], class template map
  template <class Key, class T, class Compare = less<Key>,
            class Allocator = allocator<pair<const Key, T>>>
    class map;
  template <class Key, class T, class Compare, class Allocator>
    bool operator==(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator< (const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator!=(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator> (const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator>=(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator<=(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    void swap(map<Key, T, Compare, Allocator>& x,
              map<Key, T, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  // [multimap], class template multimap
  template <class Key, class T, class Compare = less<Key>,
            class Allocator = allocator<pair<const Key, T>>>
    class multimap;
  template <class Key, class T, class Compare, class Allocator>
    bool operator==(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator< (const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator!=(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator> (const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator>=(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator<=(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    void swap(multimap<Key, T, Compare, Allocator>& x,
              multimap<Key, T, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class Key, class T, class Compare = less<Key>>
      using map = std::map<Key, T, Compare,
                           polymorphic_allocator<pair<const Key, T>>>;

    template <class Key, class T, class Compare = less<Key>>
      using multimap = std::multimap<Key, T, Compare,
                                     polymorphic_allocator<pair<const Key, T>>>;
  }
}

26.4.3 Header <set> synopsis [associative.set.syn]

#include <initializer_list>

namespace std {
  // [set], class template set
  template <class Key, class Compare = less<Key>,
            class Allocator = allocator<Key>>
    class set;
  template <class Key, class Compare, class Allocator>
    bool operator==(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator< (const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator!=(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator> (const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator>=(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator<=(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    void swap(set<Key, Compare, Allocator>& x,
              set<Key, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  // [multiset], class template multiset
  template <class Key, class Compare = less<Key>,
            class Allocator = allocator<Key>>
    class multiset;
  template <class Key, class Compare, class Allocator>
    bool operator==(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator< (const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator!=(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator> (const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator>=(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator<=(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    void swap(multiset<Key, Compare, Allocator>& x,
              multiset<Key, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));

  namespace pmr {
    template <class Key, class Compare = less<Key>>
      using set = std::set<Key, Compare,
                           polymorphic_allocator<Key>>;

    template <class Key, class Compare = less<Key>>
      using multiset = std::multiset<Key, Compare,
                                     polymorphic_allocator<Key>>;
  }
}

26.4.4 Class template map [map]

26.4.4.1 Class template map overview [map.overview]

A map is an associative container that supports unique keys (contains at most one of each key value) and provides for fast retrieval of values of another type T based on the keys.
The map class supports bidirectional iterators.
A map satisfies all of the requirements of a container, of a reversible container ([container.requirements]), of an associative container ([associative.reqmts]), and of an allocator-aware container (Table 81).
A map also provides most operations described in [associative.reqmts] for unique keys.
This means that a map supports the a_­uniq operations in [associative.reqmts] but not the a_­eq operations.
For a map<Key,T> the key_­type is Key and the value_­type is pair<const Key,T>.
Descriptions are provided here only for operations on map that are not described in one of those tables or for operations where there is additional semantic information.
namespace std {
  template <class Key, class T, class Compare = less<Key>,
            class Allocator = allocator<pair<const Key, T>>>
  class map {
  public:
    // types:
    using key_type               = Key;
    using mapped_type            = T;
    using value_type             = pair<const Key, T>;
    using key_compare            = Compare;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    using node_type              = unspecified;
    using insert_return_type     = INSERT_RETURN_TYPE<iterator, node_type>;

    class value_compare {
      friend class map;
    protected:
      Compare comp;
      value_compare(Compare c) : comp(c) {}
    public:
      bool operator()(const value_type& x, const value_type& y) const {
        return comp(x.first, y.first);
      }
    };

    // [map.cons], construct/copy/destroy
    map() : map(Compare()) { }
    explicit map(const Compare& comp, const Allocator& = Allocator());
    template <class InputIterator>
      map(InputIterator first, InputIterator last,
          const Compare& comp = Compare(), const Allocator& = Allocator());
    map(const map& x);
    map(map&& x);
    explicit map(const Allocator&);
    map(const map&, const Allocator&);
    map(map&&, const Allocator&);
    map(initializer_list<value_type>,
      const Compare& = Compare(),
      const Allocator& = Allocator());
    template <class InputIterator>
      map(InputIterator first, InputIterator last, const Allocator& a)
        : map(first, last, Compare(), a) { }
    map(initializer_list<value_type> il, const Allocator& a)
      : map(il, Compare(), a) { }
    ~map();
    map& operator=(const map& x);
    map& operator=(map&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Compare>);
    map& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // [map.access], element access
    T& operator[](const key_type& x);
    T& operator[](key_type&& x);
    T&       at(const key_type& x);
    const T& at(const key_type& x) const;

    // [map.modifiers], modifiers
    template <class... Args> pair<iterator, bool> emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    pair<iterator, bool> insert(const value_type& x);
    pair<iterator, bool> insert(value_type&& x);
    template <class P> pair<iterator, bool> insert(P&& x);
    iterator insert(const_iterator position, const value_type& x);
    iterator insert(const_iterator position, value_type&& x);
    template <class P>
      iterator insert(const_iterator position, P&&);
    template <class InputIterator>
      void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    insert_return_type insert(node_type&& nh);
    iterator           insert(const_iterator hint, node_type&& nh);

    template <class... Args>
      pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
    template <class... Args>
      pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
    template <class... Args>
      iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
    template <class... Args>
      iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
    template <class M>
      pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
    template <class M>
      pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
    template <class M>
      iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
    template <class M>
      iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& x);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(map&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Compare>);
    void      clear() noexcept;

    template<class C2>
      void merge(map<Key, T, C2, Allocator>& source);
    template<class C2>
      void merge(map<Key, T, C2, Allocator>&& source);
    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>& source);
    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>&& source);

    // observers:
    key_compare key_comp() const;
    value_compare value_comp() const;

    // map operations:
    iterator       find(const key_type& x);
    const_iterator find(const key_type& x) const;
    template <class K> iterator       find(const K& x);
    template <class K> const_iterator find(const K& x) const;

    size_type      count(const key_type& x) const;
    template <class K> size_type count(const K& x) const;

    iterator       lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
    template <class K> iterator       lower_bound(const K& x);
    template <class K> const_iterator lower_bound(const K& x) const;

    iterator       upper_bound(const key_type& x);
    const_iterator upper_bound(const key_type& x) const;
    template <class K> iterator       upper_bound(const K& x);
    template <class K> const_iterator upper_bound(const K& x) const;

    pair<iterator, iterator>               equal_range(const key_type& x);
    pair<const_iterator, const_iterator>   equal_range(const key_type& x) const;
    template <class K>
      pair<iterator, iterator>             equal_range(const K& x);
    template <class K>
      pair<const_iterator, const_iterator> equal_range(const K& x) const;
  };

  template<class InputIterator, class Compare = less<iter_key_t<InputIterator>>,
           class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
    map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
      -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>;

  template<class Key, class T, class Compare = less<Key>,
           class Allocator = allocator<pair<const Key, T>>>
    map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
      -> map<Key, T, Compare, Allocator>;

  template <class InputIterator, class Allocator>
    map(InputIterator, InputIterator, Allocator)
      -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
             less<iter_key_t<InputIterator>>, Allocator>;

  template<class Key, class T, class Allocator>
    map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>;

  template <class Key, class T, class Compare, class Allocator>
    bool operator==(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator< (const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator!=(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator> (const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator>=(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator<=(const map<Key, T, Compare, Allocator>& x,
                    const map<Key, T, Compare, Allocator>& y);

  // [map.special], specialized algorithms
  template <class Key, class T, class Compare, class Allocator>
    void swap(map<Key, T, Compare, Allocator>& x,
              map<Key, T, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

26.4.4.2 map constructors, copy, and assignment [map.cons]

explicit map(const Compare& comp, const Allocator& = Allocator());
Effects: Constructs an empty map using the specified comparison object and allocator.
Complexity: Constant.
template <class InputIterator> map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty map using the specified comparison object and allocator, and inserts elements from the range [first, last).
Complexity: Linear in N if the range [first, last) is already sorted using comp and otherwise , where N is last - first.

26.4.4.3 map element access [map.access]

T& operator[](const key_type& x);
Effects: Equivalent to: return try_­emplace(x).first->second;
T& operator[](key_type&& x);
Effects: Equivalent to: return try_­emplace(move(x)).first->second;
T& at(const key_type& x); const T& at(const key_type& x) const;
Returns: A reference to the mapped_­type corresponding to x in *this.
Throws: An exception object of type out_­of_­range if no such element is present.
Complexity: Logarithmic.

26.4.4.4 map modifiers [map.modifiers]

template <class P> pair<iterator, bool> insert(P&& x); template <class P> iterator insert(const_iterator position, P&& x);
Effects: The first form is equivalent to return emplace(std​::​forward<P>(x)).
The second form is equivalent to return emplace_­hint(position, std​::​forward<P>(x)).
Remarks: These signatures shall not participate in overload resolution unless is_­constructible_­v<value_­type, P&&> is true.
template <class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template <class... Args> iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
Requires: value_­type shall be EmplaceConstructible into map from piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std​::​forward<Args>(args)...).
Effects: If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_­type constructed with piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std​::​forward<Args>(args)...).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.
template <class... Args> pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template <class... Args> iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
Requires: value_­type shall be EmplaceConstructible into map from piecewise_­construct, forward_­as_­tuple(std​::​move(k)), forward_­as_­tuple(std​::​forward<Args>(args)...).
Effects: If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_­type constructed with piecewise_­construct, forward_­as_­tuple(std​::​move(k)), forward_­as_­tuple(std​::​forward<Args>(args)...).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.
template <class M> pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template <class M> iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
Requires: is_­assignable_­v<mapped_­type&, M&&> shall be true.
value_­type shall be EmplaceConstructible into map from k, forward<M>(obj).
Effects: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward<M>(obj) to e.second.
Otherwise inserts an object of type value_­type constructed with k, std​::​forward<M>(obj).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.
template <class M> pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template <class M> iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
Requires: is_­assignable_­v<mapped_­type&, M&&> shall be true.
value_­type shall be EmplaceConstructible into map from move(k), forward<M>(obj).
Effects: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward<M>(obj) to e.second.
Otherwise inserts an object of type value_­type constructed with std​::​​move(k), std​::​forward<M>(obj).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.

26.4.4.5 map specialized algorithms [map.special]

template <class Key, class T, class Compare, class Allocator> void swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.4.5 Class template multimap [multimap]

26.4.5.1 Class template multimap overview [multimap.overview]

A multimap is an associative container that supports equivalent keys (possibly containing multiple copies of the same key value) and provides for fast retrieval of values of another type T based on the keys.
The multimap class supports bidirectional iterators.
A multimap satisfies all of the requirements of a container and of a reversible container ([container.requirements]), of an associative container ([associative.reqmts]), and of an allocator-aware container (Table 81).
A multimap also provides most operations described in [associative.reqmts] for equal keys.
This means that a multimap supports the a_­eq operations in [associative.reqmts] but not the a_­uniq operations.
For a multimap<Key,T> the key_­type is Key and the value_­type is pair<const Key,T>.
Descriptions are provided here only for operations on multimap that are not described in one of those tables or for operations where there is additional semantic information.
namespace std {
  template <class Key, class T, class Compare = less<Key>,
            class Allocator = allocator<pair<const Key, T>>>
  class multimap {
  public:
    // types:
    using key_type               = Key;
    using mapped_type            = T;
    using value_type             = pair<const Key, T>;
    using key_compare            = Compare;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    using node_type              = unspecified;

    class value_compare {
      friend class multimap;
    protected:
      Compare comp;
      value_compare(Compare c) : comp(c) { }
    public:
      bool operator()(const value_type& x, const value_type& y) const {
        return comp(x.first, y.first);
      }
    };

    // [multimap.cons], construct/copy/destroy
    multimap() : multimap(Compare()) { }
    explicit multimap(const Compare& comp, const Allocator& = Allocator());
    template <class InputIterator>
      multimap(InputIterator first, InputIterator last,
               const Compare& comp = Compare(),
               const Allocator& = Allocator());
    multimap(const multimap& x);
    multimap(multimap&& x);
    explicit multimap(const Allocator&);
    multimap(const multimap&, const Allocator&);
    multimap(multimap&&, const Allocator&);
    multimap(initializer_list<value_type>,
      const Compare& = Compare(),
      const Allocator& = Allocator());
    template <class InputIterator>
      multimap(InputIterator first, InputIterator last, const Allocator& a)
        : multimap(first, last, Compare(), a) { }
    multimap(initializer_list<value_type> il, const Allocator& a)
      : multimap(il, Compare(), a) { }
    ~multimap();
    multimap& operator=(const multimap& x);
    multimap& operator=(multimap&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Compare>);
    multimap& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // [multimap.modifiers], modifiers
    template <class... Args> iterator emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    iterator insert(const value_type& x);
    iterator insert(value_type&& x);
    template <class P> iterator insert(P&& x);
    iterator insert(const_iterator position, const value_type& x);
    iterator insert(const_iterator position, value_type&& x);
    template <class P> iterator insert(const_iterator position, P&& x);
    template <class InputIterator>
      void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    iterator insert(node_type&& nh);
    iterator insert(const_iterator hint, node_type&& nh);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& x);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(multimap&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Compare>);
    void      clear() noexcept;

    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>& source);
    template<class C2>
      void merge(multimap<Key, T, C2, Allocator>&& source);
    template<class C2>
      void merge(map<Key, T, C2, Allocator>& source);
    template<class C2>
      void merge(map<Key, T, C2, Allocator>&& source);

    // observers:
    key_compare key_comp() const;
    value_compare value_comp() const;

    // map operations:
    iterator       find(const key_type& x);
    const_iterator find(const key_type& x) const;
    template <class K> iterator       find(const K& x);
    template <class K> const_iterator find(const K& x) const;

    size_type      count(const key_type& x) const;
    template <class K> size_type count(const K& x) const;

    iterator       lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
    template <class K> iterator       lower_bound(const K& x);
    template <class K> const_iterator lower_bound(const K& x) const;

    iterator       upper_bound(const key_type& x);
    const_iterator upper_bound(const key_type& x) const;
    template <class K> iterator       upper_bound(const K& x);
    template <class K> const_iterator upper_bound(const K& x) const;

    pair<iterator, iterator>               equal_range(const key_type& x);
    pair<const_iterator, const_iterator>   equal_range(const key_type& x) const;
    template <class K>
      pair<iterator, iterator>             equal_range(const K& x);
    template <class K>
      pair<const_iterator, const_iterator> equal_range(const K& x) const;
  };

  template<class InputIterator, class Compare = less<iter_key_t<InputIterator>>,
           class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
    multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())
      -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>;

  template<class Key, class T, class Compare = less<Key>,
           class Allocator = allocator<pair<const Key, T>>>
    multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())
      -> multimap<Key, T, Compare, Allocator>;

  template<class InputIterator, class Allocator>
    multimap(InputIterator, InputIterator, Allocator)
      -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
                  less<iter_key_t<InputIterator>>, Allocator>;

  template<class Key, class T, class Allocator>
    multimap(initializer_list<pair<const Key, T>>, Allocator)
      -> multimap<Key, T, less<Key>, Allocator>;

  template <class Key, class T, class Compare, class Allocator>
    bool operator==(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator< (const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator!=(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator> (const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator>=(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);
  template <class Key, class T, class Compare, class Allocator>
    bool operator<=(const multimap<Key, T, Compare, Allocator>& x,
                    const multimap<Key, T, Compare, Allocator>& y);

  // [multimap.special], specialized algorithms
  template <class Key, class T, class Compare, class Allocator>
    void swap(multimap<Key, T, Compare, Allocator>& x,
              multimap<Key, T, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

26.4.5.2 multimap constructors [multimap.cons]

explicit multimap(const Compare& comp, const Allocator& = Allocator());
Effects: Constructs an empty multimap using the specified comparison object and allocator.
Complexity: Constant.
template <class InputIterator> multimap(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty multimap using the specified comparison object and allocator, and inserts elements from the range [first, last).
Complexity: Linear in N if the range [first, last) is already sorted using comp and otherwise , where N is last - first.

26.4.5.3 multimap modifiers [multimap.modifiers]

template <class P> iterator insert(P&& x); template <class P> iterator insert(const_iterator position, P&& x);
Effects: The first form is equivalent to return emplace(std​::​forward<P>(x)).
The second form is equivalent to return emplace_­hint(position, std​::​forward<P>(x)).
Remarks: These signatures shall not participate in overload resolution unless is_­constructible_­v<value_­type, P&&> is true.

26.4.5.4 multimap specialized algorithms [multimap.special]

template <class Key, class T, class Compare, class Allocator> void swap(multimap<Key, T, Compare, Allocator>& x, multimap<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.4.6 Class template set [set]

26.4.6.1 Class template set overview [set.overview]

A set is an associative container that supports unique keys (contains at most one of each key value) and provides for fast retrieval of the keys themselves.
The set class supports bidirectional iterators.
A set satisfies all of the requirements of a container, of a reversible container ([container.requirements]), of an associative container ([associative.reqmts]), and of an allocator-aware container (Table 81).
A set also provides most operations described in [associative.reqmts] for unique keys.
This means that a set supports the a_­uniq operations in [associative.reqmts] but not the a_­eq operations.
For a set<Key> both the key_­type and value_­type are Key.
Descriptions are provided here only for operations on set that are not described in one of these tables and for operations where there is additional semantic information.
namespace std {
  template <class Key, class Compare = less<Key>,
            class Allocator = allocator<Key>>
  class set {
  public:
    // types:
    using key_type               = Key;
    using key_compare            = Compare;
    using value_type             = Key;
    using value_compare          = Compare;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    using node_type              = unspecified;
    using insert_return_type     = INSERT_RETURN_TYPE<iterator, node_type>;

    // [set.cons], construct/copy/destroy
    set() : set(Compare()) { }
    explicit set(const Compare& comp, const Allocator& = Allocator());
    template <class InputIterator>
      set(InputIterator first, InputIterator last,
          const Compare& comp = Compare(), const Allocator& = Allocator());
    set(const set& x);
    set(set&& x);
    explicit set(const Allocator&);
    set(const set&, const Allocator&);
    set(set&&, const Allocator&);
    set(initializer_list<value_type>, const Compare& = Compare(),
        const Allocator& = Allocator());
    template <class InputIterator>
      set(InputIterator first, InputIterator last, const Allocator& a)
        : set(first, last, Compare(), a) { }
    set(initializer_list<value_type> il, const Allocator& a)
      : set(il, Compare(), a) { }
    ~set();
    set& operator=(const set& x);
    set& operator=(set&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Compare>);
    set& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // modifiers:
    template <class... Args> pair<iterator, bool> emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    pair<iterator,bool> insert(const value_type& x);
    pair<iterator,bool> insert(value_type&& x);
    iterator insert(const_iterator position, const value_type& x);
    iterator insert(const_iterator position, value_type&& x);
    template <class InputIterator>
      void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    insert_return_type insert(node_type&& nh);
    iterator           insert(const_iterator hint, node_type&& nh);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& x);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(set&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Compare>);
    void      clear() noexcept;

    template<class C2>
      void merge(set<Key, C2, Allocator>& source);
    template<class C2>
      void merge(set<Key, C2, Allocator>&& source);
    template<class C2>
      void merge(multiset<Key, C2, Allocator>& source);
    template<class C2>
      void merge(multiset<Key, C2, Allocator>&& source);

    // observers:
    key_compare key_comp() const;
    value_compare value_comp() const;

    // set operations:
    iterator       find(const key_type& x);
    const_iterator find(const key_type& x) const;
    template <class K> iterator       find(const K& x);
    template <class K> const_iterator find(const K& x) const;

    size_type      count(const key_type& x) const;
    template <class K> size_type count(const K& x) const;

    iterator       lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
    template <class K> iterator       lower_bound(const K& x);
    template <class K> const_iterator lower_bound(const K& x) const;

    iterator       upper_bound(const key_type& x);
    const_iterator upper_bound(const key_type& x) const;
    template <class K> iterator       upper_bound(const K& x);
    template <class K> const_iterator upper_bound(const K& x) const;

    pair<iterator, iterator>               equal_range(const key_type& x);
    pair<const_iterator, const_iterator>   equal_range(const key_type& x) const;
    template <class K>
      pair<iterator, iterator>             equal_range(const K& x);
    template <class K>
      pair<const_iterator, const_iterator> equal_range(const K& x) const;
  };

  template<class InputIterator,
           class Compare = less<typename iterator_traits<InputIterator>::value_type>,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    set(InputIterator, InputIterator,
        Compare = Compare(), Allocator = Allocator())
      -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;

  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
    set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
      -> set<Key, Compare, Allocator>;

  template<class InputIterator, class Allocator>
    set(InputIterator, InputIterator, Allocator)
      -> set<typename iterator_traits<InputIterator>::value_type,
             less<typename iterator_traits<InputIterator>::value_type>, Allocator>;

  template<class Key, class Allocator>
    set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>;

  template <class Key, class Compare, class Allocator>
    bool operator==(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator< (const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator!=(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator> (const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator>=(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator<=(const set<Key, Compare, Allocator>& x,
                    const set<Key, Compare, Allocator>& y);

  // [set.special], specialized algorithms
  template <class Key, class Compare, class Allocator>
    void swap(set<Key, Compare, Allocator>& x,
              set<Key, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

26.4.6.2 set constructors, copy, and assignment [set.cons]

explicit set(const Compare& comp, const Allocator& = Allocator());
Effects: Constructs an empty set using the specified comparison objects and allocator.
Complexity: Constant.
template <class InputIterator> set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty set using the specified comparison object and allocator, and inserts elements from the range [first, last).
Complexity: Linear in N if the range [first, last) is already sorted using comp and otherwise , where N is last - first.

26.4.6.3 set specialized algorithms [set.special]

template <class Key, class Compare, class Allocator> void swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.4.7 Class template multiset [multiset]

26.4.7.1 Class template multiset overview [multiset.overview]

A multiset is an associative container that supports equivalent keys (possibly contains multiple copies of the same key value) and provides for fast retrieval of the keys themselves.
The multiset class supports bidirectional iterators.
A multiset satisfies all of the requirements of a container, of a reversible container ([container.requirements]), of an associative container ([associative.reqmts]), and of an allocator-aware container (Table 81).
multiset also provides most operations described in [associative.reqmts] for duplicate keys.
This means that a multiset supports the a_­eq operations in [associative.reqmts] but not the a_­uniq operations.
For a multiset<Key> both the key_­type and value_­type are Key.
Descriptions are provided here only for operations on multiset that are not described in one of these tables and for operations where there is additional semantic information.
namespace std {
  template <class Key, class Compare = less<Key>,
            class Allocator = allocator<Key>>
  class multiset {
  public:
    // types:
    using key_type               = Key;
    using key_compare            = Compare;
    using value_type             = Key;
    using value_compare          = Compare;
    using allocator_type         = Allocator;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using size_type              = implementation-defined; // see [container.requirements]
    using difference_type        = implementation-defined; // see [container.requirements]
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    using node_type              = unspecified;

    // [multiset.cons], construct/copy/destroy
    multiset() : multiset(Compare()) { }
    explicit multiset(const Compare& comp, const Allocator& = Allocator());
    template <class InputIterator>
      multiset(InputIterator first, InputIterator last,
               const Compare& comp = Compare(), const Allocator& = Allocator());
    multiset(const multiset& x);
    multiset(multiset&& x);
    explicit multiset(const Allocator&);
    multiset(const multiset&, const Allocator&);
    multiset(multiset&&, const Allocator&);
    multiset(initializer_list<value_type>, const Compare& = Compare(),
             const Allocator& = Allocator());
    template <class InputIterator>
      multiset(InputIterator first, InputIterator last, const Allocator& a)
        : multiset(first, last, Compare(), a) { }
    multiset(initializer_list<value_type> il, const Allocator& a)
      : multiset(il, Compare(), a) { }
    ~multiset();
    multiset& operator=(const multiset& x);
    multiset& operator=(multiset&& x)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Compare>);
    multiset& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator               begin() noexcept;
    const_iterator         begin() const noexcept;
    iterator               end() noexcept;
    const_iterator         end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // modifiers:
    template <class... Args> iterator emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    iterator insert(const value_type& x);
    iterator insert(value_type&& x);
    iterator insert(const_iterator position, const value_type& x);
    iterator insert(const_iterator position, value_type&& x);
    template <class InputIterator>
      void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    iterator insert(node_type&& nh);
    iterator insert(const_iterator hint, node_type&& nh);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& x);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(multiset&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Compare>);
    void      clear() noexcept;

    template<class C2>
      void merge(multiset<Key, C2, Allocator>& source);
    template<class C2>
      void merge(multiset<Key, C2, Allocator>&& source);
    template<class C2>
      void merge(set<Key, C2, Allocator>& source);
    template<class C2>
      void merge(set<Key, C2, Allocator>&& source);

    // observers:
    key_compare key_comp() const;
    value_compare value_comp() const;

    // set operations:
    iterator       find(const key_type& x);
    const_iterator find(const key_type& x) const;
    template <class K> iterator       find(const K& x);
    template <class K> const_iterator find(const K& x) const;

    size_type      count(const key_type& x) const;
    template <class K> size_type count(const K& x) const;

    iterator       lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
    template <class K> iterator       lower_bound(const K& x);
    template <class K> const_iterator lower_bound(const K& x) const;

    iterator       upper_bound(const key_type& x);
    const_iterator upper_bound(const key_type& x) const;
    template <class K> iterator       upper_bound(const K& x);
    template <class K> const_iterator upper_bound(const K& x) const;

    pair<iterator, iterator>               equal_range(const key_type& x);
    pair<const_iterator, const_iterator>   equal_range(const key_type& x) const;
    template <class K>
      pair<iterator, iterator>             equal_range(const K& x);
    template <class K>
      pair<const_iterator, const_iterator> equal_range(const K& x) const;
  };

  template<class InputIterator,
           class Compare = less<typename iterator_traits<InputIterator>::value_type>,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    multiset(InputIterator, InputIterator,
             Compare = Compare(), Allocator = Allocator())
      -> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>;

  template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
    multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())
      -> multiset<Key, Compare, Allocator>;

  template<class InputIterator, class Allocator>
    multiset(InputIterator, InputIterator, Allocator)
      -> multiset<typename iterator_traits<InputIterator>::value_type,
                  less<typename iterator_traits<InputIterator>::value_type>, Allocator>;

  template<class Key, class Allocator>
    multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>;

  template <class Key, class Compare, class Allocator>
    bool operator==(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator< (const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator!=(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator> (const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator>=(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);
  template <class Key, class Compare, class Allocator>
    bool operator<=(const multiset<Key, Compare, Allocator>& x,
                    const multiset<Key, Compare, Allocator>& y);

  // [multiset.special], specialized algorithms
  template <class Key, class Compare, class Allocator>
    void swap(multiset<Key, Compare, Allocator>& x,
              multiset<Key, Compare, Allocator>& y)
      noexcept(noexcept(x.swap(y)));
}

26.4.7.2 multiset constructors [multiset.cons]

explicit multiset(const Compare& comp, const Allocator& = Allocator());
Effects: Constructs an empty multiset using the specified comparison object and allocator.
Complexity: Constant.
template <class InputIterator> multiset(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator());
Effects: Constructs an empty multiset using the specified comparison object and allocator, and inserts elements from the range [first, last).
Complexity: Linear in N if the range [first, last) is already sorted using comp and otherwise , where N is last - first.

26.4.7.3 multiset specialized algorithms [multiset.special]

template <class Key, class Compare, class Allocator> void swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.5 Unordered associative containers [unord]

26.5.1 In general [unord.general]

The header <unordered_­map> defines the class templates unordered_­map and unordered_­multimap; the header <unordered_­set> defines the class templates unordered_­set and unordered_­multiset.
The exposition-only alias templates iter_­key_­t, iter_­val_­t, and iter_­to_­alloc_­t defined in [associative.general] may appear in deduction guides for unordered containers.

26.5.2 Header <unordered_­map> synopsis [unord.map.syn]

#include <initializer_list>

namespace std {
  // [unord.map], class template unordered_­map
  template <class Key,
            class T,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Alloc = allocator<pair<const Key, T>>>
    class unordered_map;

  // [unord.multimap], class template unordered_­multimap
  template <class Key,
            class T,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Alloc = allocator<pair<const Key, T>>>
    class unordered_multimap;

  template <class Key, class T, class Hash, class Pred, class Alloc>
    void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
              unordered_map<Key, T, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));

  template <class Key, class T, class Hash, class Pred, class Alloc>
    void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
              unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));

  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_map<Key, T, Hash, Pred, Alloc>& b);
  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_map<Key, T, Hash, Pred, Alloc>& b);
  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);

  namespace pmr {
    template <class Key,
              class T,
              class Hash = hash<Key>,
              class Pred = equal_to<Key>>
      using unordered_map =
        std::unordered_map<Key, T, Hash, Pred,
                           polymorphic_allocator<pair<const Key, T>>>;
    template <class Key,
              class T,
              class Hash = hash<Key>,
              class Pred = equal_to<Key>>
      using unordered_multimap =
        std::unordered_multimap<Key, T, Hash, Pred,
                                polymorphic_allocator<pair<const Key, T>>>;

  }
}

26.5.3 Header <unordered_­set> synopsis [unord.set.syn]

#include <initializer_list>

namespace std {
  // [unord.set], class template unordered_­set
  template <class Key,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Alloc = allocator<Key>>
    class unordered_set;

  // [unord.multiset], class template unordered_­multiset
  template <class Key,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Alloc = allocator<Key>>
    class unordered_multiset;

  template <class Key, class Hash, class Pred, class Alloc>
    void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
              unordered_set<Key, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));

  template <class Key, class Hash, class Pred, class Alloc>
    void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
              unordered_multiset<Key, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));

  template <class Key, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a,
                    const unordered_set<Key, Hash, Pred, Alloc>& b);
  template <class Key, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_set<Key, Hash, Pred, Alloc>& a,
                    const unordered_set<Key, Hash, Pred, Alloc>& b);
  template <class Key, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
                    const unordered_multiset<Key, Hash, Pred, Alloc>& b);
  template <class Key, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
                    const unordered_multiset<Key, Hash, Pred, Alloc>& b);

  namespace pmr {
    template <class Key,
              class Hash = hash<Key>,
              class Pred = equal_to<Key>>
      using unordered_set = std::unordered_set<Key, Hash, Pred,
                                               polymorphic_allocator<Key>>;

    template <class Key,
              class Hash = hash<Key>,
              class Pred = equal_to<Key>>
      using unordered_multiset = std::unordered_multiset<Key, Hash, Pred,
                                                         polymorphic_allocator<Key>>;
  }
}

26.5.4 Class template unordered_­map [unord.map]

26.5.4.1 Class template unordered_­map overview [unord.map.overview]

An unordered_­map is an unordered associative container that supports unique keys (an unordered_­map contains at most one of each key value) and that associates values of another type mapped_­type with the keys.
The unordered_­map class supports forward iterators.
An unordered_­map satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 81).
It provides the operations described in the preceding requirements table for unique keys; that is, an unordered_­map supports the a_­uniq operations in that table, not the a_­eq operations.
For an unordered_­map<Key, T> the key type is Key, the mapped type is T, and the value type is pair<const Key, T>.
This section only describes operations on unordered_­map that are not described in one of the requirement tables, or for which there is additional semantic information.
namespace std {
  template <class Key,
            class T,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Allocator = allocator<pair<const Key, T>>>
  class unordered_map {
  public:
    // types:
    using key_type             = Key;
    using mapped_type          = T;
    using value_type           = pair<const Key, T>;
    using hasher               = Hash;
    using key_equal            = Pred;
    using allocator_type       = Allocator;
    using pointer              = typename allocator_traits<Allocator>::pointer;
    using const_pointer        = typename allocator_traits<Allocator>::const_pointer;
    using reference            = value_type&;
    using const_reference      = const value_type&;
    using size_type            = implementation-defined; // see [container.requirements]
    using difference_type      = implementation-defined; // see [container.requirements]

    using iterator             = implementation-defined; // see [container.requirements]
    using const_iterator       = implementation-defined; // see [container.requirements]
    using local_iterator       = implementation-defined; // see [container.requirements]
    using const_local_iterator = implementation-defined; // see [container.requirements]
    using node_type            = unspecified;
    using insert_return_type   = INSERT_RETURN_TYPE<iterator, node_type>;

    // [unord.map.cnstr], construct/copy/destroy
    unordered_map();
    explicit unordered_map(size_type n,
                           const hasher& hf = hasher(),
                           const key_equal& eql = key_equal(),
                           const allocator_type& a = allocator_type());
    template <class InputIterator>
      unordered_map(InputIterator f, InputIterator l,
                    size_type n = see below,
                    const hasher& hf = hasher(),
                    const key_equal& eql = key_equal(),
                    const allocator_type& a = allocator_type());
    unordered_map(const unordered_map&);
    unordered_map(unordered_map&&);
    explicit unordered_map(const Allocator&);
    unordered_map(const unordered_map&, const Allocator&);
    unordered_map(unordered_map&&, const Allocator&);
    unordered_map(initializer_list<value_type> il,
                  size_type n = see below,
                  const hasher& hf = hasher(),
                  const key_equal& eql = key_equal(),
                  const allocator_type& a = allocator_type());
    unordered_map(size_type n, const allocator_type& a)
      : unordered_map(n, hasher(), key_equal(), a) { }
    unordered_map(size_type n, const hasher& hf, const allocator_type& a)
      : unordered_map(n, hf, key_equal(), a) { }
    template <class InputIterator>
      unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
        : unordered_map(f, l, n, hasher(), key_equal(), a) { }
    template <class InputIterator>
      unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
                    const allocator_type& a)
        : unordered_map(f, l, n, hf, key_equal(), a) { }
    unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
      : unordered_map(il, n, hasher(), key_equal(), a) { }
    unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
                  const allocator_type& a)
      : unordered_map(il, n, hf, key_equal(), a) { }
    ~unordered_map();
    unordered_map& operator=(const unordered_map&);
    unordered_map& operator=(unordered_map&&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Hash> &&
               is_nothrow_move_assignable_v<Pred>);
    unordered_map& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;
    const_iterator cbegin() const noexcept;
    const_iterator cend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // [unord.map.modifiers], modifiers
    template <class... Args> pair<iterator, bool> emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    pair<iterator, bool> insert(const value_type& obj);
    pair<iterator, bool> insert(value_type&& obj);
    template <class P> pair<iterator, bool> insert(P&& obj);
    iterator       insert(const_iterator hint, const value_type& obj);
    iterator       insert(const_iterator hint, value_type&& obj);
    template <class P> iterator insert(const_iterator hint, P&& obj);
    template <class InputIterator> void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    insert_return_type insert(node_type&& nh);
    iterator           insert(const_iterator hint, node_type&& nh);

    template <class... Args>
      pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
    template <class... Args>
      pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
    template <class... Args>
      iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
    template <class... Args>
      iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
    template <class M>
      pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
    template <class M>
      pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
    template <class M>
      iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
    template <class M>
      iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& k);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(unordered_map&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Hash> &&
               is_nothrow_swappable_v<Pred>);
    void      clear() noexcept;

    template<class H2, class P2>
      void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
    template<class H2, class P2>
      void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);

    // observers:
    hasher hash_function() const;
    key_equal key_eq() const;

    // map operations:
    iterator       find(const key_type& k);
    const_iterator find(const key_type& k) const;
    size_type      count(const key_type& k) const;
    pair<iterator, iterator>             equal_range(const key_type& k);
    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;

    // [unord.map.elem], element access
    mapped_type& operator[](const key_type& k);
    mapped_type& operator[](key_type&& k);
    mapped_type& at(const key_type& k);
    const mapped_type& at(const key_type& k) const;

    // bucket interface:
    size_type bucket_count() const noexcept;
    size_type max_bucket_count() const noexcept;
    size_type bucket_size(size_type n) const;
    size_type bucket(const key_type& k) const;
    local_iterator begin(size_type n);
    const_local_iterator begin(size_type n) const;
    local_iterator end(size_type n);
    const_local_iterator end(size_type n) const;
    const_local_iterator cbegin(size_type n) const;
    const_local_iterator cend(size_type n) const;

    // hash policy:
    float load_factor() const noexcept;
    float max_load_factor() const noexcept;
    void max_load_factor(float z);
    void rehash(size_type n);
    void reserve(size_type n);
  };

  template<class InputIterator,
           class Hash = hash<iter_key_t<InputIterator>>,
           class Pred = equal_to<iter_key_t<InputIterator>>,
           class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
    unordered_map(InputIterator, InputIterator, typename see below::size_type = see below,
                  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -> unordered_map<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
                       Allocator>;

  template<class Key, class T, class Hash = hash<Key>,
           class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
    unordered_map(initializer_list<pair<const Key, T>>,
                  typename see below::size_type = see below, Hash = Hash(),
                  Pred = Pred(), Allocator = Allocator())
      -> unordered_map<Key, T, Hash, Pred, Allocator>;

  template<class InputIterator, class Allocator>
    unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator)
      -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
                       hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>,
                       Allocator>;

  template<class InputIterator, class Allocator>
    unordered_map(InputIterator, InputIterator, Allocator)
      -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
                       hash<iter_key_t<InputIterator>>, equal_to<iter_key_t<InputIterator>>,
                       Allocator>;

  template<class InputIterator, class Hash, class Allocator>
    unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator)
      -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
                       equal_to<iter_key_t<InputIterator>>, Allocator>;

  template<class Key, class T, typename Allocator>
    unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type,
                  Allocator)
      -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;

  template<class Key, class T, typename Allocator>
    unordered_map(initializer_list<pair<const Key, T>>, Allocator)
      -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>;

  template<class Key, class T, class Hash, class Allocator>
    unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Hash,
                  Allocator)
      -> unordered_map<Key, T, Hash, equal_to<Key>, Allocator>;

  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_map<Key, T, Hash, Pred, Alloc>& b);
  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_map<Key, T, Hash, Pred, Alloc>& b);

  // [unord.map.swap], swap
  template <class Key, class T, class Hash, class Pred, class Alloc>
    void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
              unordered_map<Key, T, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));
}
A size_­type parameter type in an unordered_­map deduction guide refers to the size_­type member type of the type deduced by the deduction guide.

26.5.4.2 unordered_­map constructors [unord.map.cnstr]

unordered_map() : unordered_map(size_type(see below)) { } explicit unordered_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­map using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_­load_­factor() returns 1.0.
Complexity: Constant.
template <class InputIterator> unordered_map(InputIterator f, InputIterator l, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_map(initializer_list<value_type> il, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­map using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l) for the first form, or from the range [il.begin(), il.end()) for the second form.
max_­load_­factor() returns 1.0.
Complexity: Average case linear, worst case quadratic.

26.5.4.3 unordered_­map element access [unord.map.elem]

mapped_type& operator[](const key_type& k);
Effects: Equivalent to: return try_­emplace(k).first->second;
mapped_type& operator[](key_type&& k);
Effects: Equivalent to: return try_­emplace(move(k)).first->second;
mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const;
Returns: A reference to x.second, where x is the (unique) element whose key is equivalent to k.
Throws: An exception object of type out_­of_­range if no such element is present.

26.5.4.4 unordered_­map modifiers [unord.map.modifiers]

template <class P> pair<iterator, bool> insert(P&& obj);
Effects: Equivalent to: return emplace(std​::​forward<P>(obj));
Remarks: This signature shall not participate in overload resolution unless is_­constructible_­v<value_­type, P&&> is true.
template <class P> iterator insert(const_iterator hint, P&& obj);
Effects: Equivalent to: return emplace_­hint(hint, std​::​forward<P>(obj));
Remarks: This signature shall not participate in overload resolution unless is_­constructible_­v<value_­type, P&&> is true.
template <class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template <class... Args> iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
Requires: value_­type shall be EmplaceConstructible into unordered_­map from piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std​::​forward<Args>(args)...).
Effects: If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_­type constructed with piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std​::​forward<Args>(args)...).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.
template <class... Args> pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template <class... Args> iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
Requires: value_­type shall be EmplaceConstructible into unordered_­map from piecewise_­construct, forward_­as_­tuple(std​::​move(k)), forward_­as_­tuple(std​::​forward<Args>(args)...).
Effects: If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_­type constructed with piecewise_­construct, forward_­as_­tuple(std​::​move(k)), forward_­as_­tuple(std​::​forward<Args>(args)...).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.
template <class M> pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template <class M> iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
Requires: is_­assignable_­v<mapped_­type&, M&&> shall be true.
value_­type shall be EmplaceConstructible into unordered_­map from k, std​::​forward<M>(obj).
Effects: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward<M>(obj) to e.second.
Otherwise inserts an object of type value_­type constructed with k, std​::​forward<M>(obj).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.
template <class M> pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template <class M> iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
Requires: is_­assignable_­v<mapped_­type&, M&&> shall be true.
value_­type shall be EmplaceConstructible into unordered_­map from std​::​move(k), std​::​forward<M>(obj).
Effects: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward<M>(obj) to e.second.
Otherwise inserts an object of type value_­type constructed with std​::​​move(k), std​::​forward<M>(obj).
Returns: In the first overload, the bool component of the returned pair is true if and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity: The same as emplace and emplace_­hint, respectively.

26.5.4.5 unordered_­map swap [unord.map.swap]

template <class Key, class T, class Hash, class Pred, class Alloc> void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x, unordered_map<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.5.5 Class template unordered_­multimap [unord.multimap]

26.5.5.1 Class template unordered_­multimap overview [unord.multimap.overview]

An unordered_­multimap is an unordered associative container that supports equivalent keys (an instance of unordered_­multimap may contain multiple copies of each key value) and that associates values of another type mapped_­type with the keys.
The unordered_­multimap class supports forward iterators.
An unordered_­multimap satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 81).
It provides the operations described in the preceding requirements table for equivalent keys; that is, an unordered_­multimap supports the a_­eq operations in that table, not the a_­uniq operations.
For an unordered_­multimap<Key, T> the key type is Key, the mapped type is T, and the value type is pair<const Key, T>.
This section only describes operations on unordered_­multimap that are not described in one of the requirement tables, or for which there is additional semantic information.
namespace std {
  template <class Key,
            class T,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Allocator = allocator<pair<const Key, T>>>
  class unordered_multimap {
  public:
    // types:
    using key_type             = Key;
    using mapped_type          = T;
    using value_type           = pair<const Key, T>;
    using hasher               = Hash;
    using key_equal            = Pred;
    using allocator_type       = Allocator;
    using pointer              = typename allocator_traits<Allocator>::pointer;
    using const_pointer        = typename allocator_traits<Allocator>::const_pointer;
    using reference            = value_type&;
    using const_reference      = const value_type&;
    using size_type            = implementation-defined; // see [container.requirements]
    using difference_type      = implementation-defined; // see [container.requirements]

    using iterator             = implementation-defined; // see [container.requirements]
    using const_iterator       = implementation-defined; // see [container.requirements]
    using local_iterator       = implementation-defined; // see [container.requirements]
    using const_local_iterator = implementation-defined; // see [container.requirements]
    using node_type            = unspecified;

    // [unord.multimap.cnstr], construct/copy/destroy
    unordered_multimap();
    explicit unordered_multimap(size_type n,
                                const hasher& hf = hasher(),
                                const key_equal& eql = key_equal(),
                                const allocator_type& a = allocator_type());
    template <class InputIterator>
      unordered_multimap(InputIterator f, InputIterator l,
                         size_type n = see below,
                         const hasher& hf = hasher(),
                         const key_equal& eql = key_equal(),
                         const allocator_type& a = allocator_type());
    unordered_multimap(const unordered_multimap&);
    unordered_multimap(unordered_multimap&&);
    explicit unordered_multimap(const Allocator&);
    unordered_multimap(const unordered_multimap&, const Allocator&);
    unordered_multimap(unordered_multimap&&, const Allocator&);
    unordered_multimap(initializer_list<value_type> il,
                       size_type n = see below,
                       const hasher& hf = hasher(),
                       const key_equal& eql = key_equal(),
                       const allocator_type& a = allocator_type());
    unordered_multimap(size_type n, const allocator_type& a)
      : unordered_multimap(n, hasher(), key_equal(), a) { }
    unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
      : unordered_multimap(n, hf, key_equal(), a) { }
    template <class InputIterator>
      unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
        : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
    template <class InputIterator>
      unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
                         const allocator_type& a)
        : unordered_multimap(f, l, n, hf, key_equal(), a) { }
    unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
      : unordered_multimap(il, n, hasher(), key_equal(), a) { }
    unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
                       const allocator_type& a)
      : unordered_multimap(il, n, hf, key_equal(), a) { }
    ~unordered_multimap();
    unordered_multimap& operator=(const unordered_multimap&);
    unordered_multimap& operator=(unordered_multimap&&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Hash> &&
               is_nothrow_move_assignable_v<Pred>);
    unordered_multimap& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;
    const_iterator cbegin() const noexcept;
    const_iterator cend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // [unord.multimap.modifiers], modifiers
    template <class... Args> iterator emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    iterator insert(const value_type& obj);
    iterator insert(value_type&& obj);
    template <class P> iterator insert(P&& obj);
    iterator insert(const_iterator hint, const value_type& obj);
    iterator insert(const_iterator hint, value_type&& obj);
    template <class P> iterator insert(const_iterator hint, P&& obj);
    template <class InputIterator> void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    iterator insert(node_type&& nh);
    iterator insert(const_iterator hint, node_type&& nh);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& k);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(unordered_multimap&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Hash> &&
               is_nothrow_swappable_v<Pred>);
    void      clear() noexcept;

    template<class H2, class P2>
      void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
    template<class H2, class P2>
      void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);

    // observers:
    hasher hash_function() const;
    key_equal key_eq() const;

    // map operations:
    iterator       find(const key_type& k);
    const_iterator find(const key_type& k) const;
    size_type      count(const key_type& k) const;
    pair<iterator, iterator>             equal_range(const key_type& k);
    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;

    // bucket interface:
    size_type bucket_count() const noexcept;
    size_type max_bucket_count() const noexcept;
    size_type bucket_size(size_type n) const;
    size_type bucket(const key_type& k) const;
    local_iterator begin(size_type n);
    const_local_iterator begin(size_type n) const;
    local_iterator end(size_type n);
    const_local_iterator end(size_type n) const;
    const_local_iterator cbegin(size_type n) const;
    const_local_iterator cend(size_type n) const;

    // hash policy
    float load_factor() const noexcept;
    float max_load_factor() const noexcept;
    void max_load_factor(float z);
    void rehash(size_type n);
    void reserve(size_type n);
  };

  template<class InputIterator,
           class Hash = hash<iter_key_t<InputIterator>>,
           class Pred = equal_to<iter_key_t<InputIterator>>,
           class Allocator = allocator<iter_to_alloc_t<InputIterator>>>
    unordered_multimap(InputIterator, InputIterator,
                       typename see below::size_type = see below,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -> unordered_multimap<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred,
                            Allocator>;

  template<class Key, class T, class Hash = hash<Key>,
           class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
    unordered_multimap(initializer_list<pair<const Key, T>>,
                       typename see below::size_type = see below,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -> unordered_multimap<Key, T, Hash, Pred, Allocator>;

  template<class InputIterator, class Allocator>
    unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator)
      -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
                            hash<iter_key_t<InputIterator>>,
                            equal_to<iter_key_t<InputIterator>>, Allocator>;

  template<class InputIterator, class Allocator>
    unordered_multimap(InputIterator, InputIterator, Allocator)
      -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,
                            hash<iter_key_t<InputIterator>>,
                            equal_to<iter_key_t<InputIterator>>, Allocator>;

  template<class InputIterator, class Hash, class Allocator>
    unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash,
                       Allocator)
      -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash,
                            equal_to<iter_key_t<InputIterator>>, Allocator>;

  template<class Key, class T, typename Allocator>
    unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type,
                       Allocator)
      -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;

  template<class Key, class T, typename Allocator>
    unordered_multimap(initializer_list<pair<const Key, T>>, Allocator)
      -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>;

  template<class Key, class T, class Hash, class Allocator>
    unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type,
                       Hash, Allocator)
      -> unordered_multimap<Key, T, Hash, equal_to<Key>, Allocator>;

  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
  template <class Key, class T, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a,
                    const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);

  // [unord.multimap.swap], swap
  template <class Key, class T, class Hash, class Pred, class Alloc>
    void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
              unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));
}
A size_­type parameter type in an unordered_­multimap deduction guide refers to the size_­type member type of the type deduced by the deduction guide.

26.5.5.2 unordered_­multimap constructors [unord.multimap.cnstr]

unordered_multimap() : unordered_multimap(size_type(see below)) { } explicit unordered_multimap(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­multimap using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_­load_­factor() returns 1.0.
Complexity: Constant.
template <class InputIterator> unordered_multimap(InputIterator f, InputIterator l, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_multimap(initializer_list<value_type> il, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­multimap using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l) for the first form, or from the range [il.begin(), il.end()) for the second form.
max_­load_­factor() returns 1.0.
Complexity: Average case linear, worst case quadratic.

26.5.5.3 unordered_­multimap modifiers [unord.multimap.modifiers]

template <class P> iterator insert(P&& obj);
Effects: Equivalent to: return emplace(std​::​forward<P>(obj));
Remarks: This signature shall not participate in overload resolution unless is_­constructible_­v<value_­type, P&&> is true.
template <class P> iterator insert(const_iterator hint, P&& obj);
Effects: Equivalent to: return emplace_­hint(hint, std​::​forward<P>(obj));
Remarks: This signature shall not participate in overload resolution unless is_­constructible_­v<value_­type, P&&> is true.

26.5.5.4 unordered_­multimap swap [unord.multimap.swap]

template <class Key, class T, class Hash, class Pred, class Alloc> void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x, unordered_multimap<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.5.6 Class template unordered_­set [unord.set]

26.5.6.1 Class template unordered_­set overview [unord.set.overview]

An unordered_­set is an unordered associative container that supports unique keys (an unordered_­set contains at most one of each key value) and in which the elements' keys are the elements themselves.
The unordered_­set class supports forward iterators.
An unordered_­set satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 81).
It provides the operations described in the preceding requirements table for unique keys; that is, an unordered_­set supports the a_­uniq operations in that table, not the a_­eq operations.
For an unordered_­set<Key> the key type and the value type are both Key.
The iterator and const_­iterator types are both constant iterator types.
It is unspecified whether they are the same type.
This section only describes operations on unordered_­set that are not described in one of the requirement tables, or for which there is additional semantic information.
namespace std {
  template <class Key,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Allocator = allocator<Key>>
  class unordered_set {
  public:
    // types:
    using key_type             = Key;
    using value_type           = Key;
    using hasher               = Hash;
    using key_equal            = Pred;
    using allocator_type       = Allocator;
    using pointer              = typename allocator_traits<Allocator>::pointer;
    using const_pointer        = typename allocator_traits<Allocator>::const_pointer;
    using reference            = value_type&;
    using const_reference      = const value_type&;
    using size_type            = implementation-defined; // see [container.requirements]
    using difference_type      = implementation-defined; // see [container.requirements]

    using iterator             = implementation-defined; // see [container.requirements]
    using const_iterator       = implementation-defined; // see [container.requirements]
    using local_iterator       = implementation-defined; // see [container.requirements]
    using const_local_iterator = implementation-defined; // see [container.requirements]
    using node_type            = unspecified;
    using insert_return_type   = INSERT_RETURN_TYPE<iterator, node_type>;

    // [unord.set.cnstr], construct/copy/destroy
    unordered_set();
    explicit unordered_set(size_type n,
                           const hasher& hf = hasher(),
                           const key_equal& eql = key_equal(),
                           const allocator_type& a = allocator_type());
    template <class InputIterator>
      unordered_set(InputIterator f, InputIterator l,
                    size_type n = see below,
                    const hasher& hf = hasher(),
                    const key_equal& eql = key_equal(),
                    const allocator_type& a = allocator_type());
    unordered_set(const unordered_set&);
    unordered_set(unordered_set&&);
    explicit unordered_set(const Allocator&);
    unordered_set(const unordered_set&, const Allocator&);
    unordered_set(unordered_set&&, const Allocator&);
    unordered_set(initializer_list<value_type> il,
                  size_type n = see below,
                  const hasher& hf = hasher(),
                  const key_equal& eql = key_equal(),
                  const allocator_type& a = allocator_type());
    unordered_set(size_type n, const allocator_type& a)
      : unordered_set(n, hasher(), key_equal(), a) { }
    unordered_set(size_type n, const hasher& hf, const allocator_type& a)
      : unordered_set(n, hf, key_equal(), a) { }
    template <class InputIterator>
      unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
        : unordered_set(f, l, n, hasher(), key_equal(), a) { }
    template <class InputIterator>
      unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf,
                    const allocator_type& a)
      : unordered_set(f, l, n, hf, key_equal(), a) { }
    unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
      : unordered_set(il, n, hasher(), key_equal(), a) { }
    unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf,
                  const allocator_type& a)
      : unordered_set(il, n, hf, key_equal(), a) { }
    ~unordered_set();
    unordered_set& operator=(const unordered_set&);
    unordered_set& operator=(unordered_set&&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Hash> &&
               is_nothrow_move_assignable_v<Pred>);
    unordered_set& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;
    const_iterator cbegin() const noexcept;
    const_iterator cend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // modifiers:
    template <class... Args> pair<iterator, bool> emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    pair<iterator, bool> insert(const value_type& obj);
    pair<iterator, bool> insert(value_type&& obj);
    iterator insert(const_iterator hint, const value_type& obj);
    iterator insert(const_iterator hint, value_type&& obj);
    template <class InputIterator> void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    insert_return_type insert(node_type&& nh);
    iterator           insert(const_iterator hint, node_type&& nh);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& k);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(unordered_set&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Hash> &&
               is_nothrow_swappable_v<Pred>);
    void      clear() noexcept;

    template<class H2, class P2>
      void merge(unordered_set<Key, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_set<Key, H2, P2, Allocator>&& source);
    template<class H2, class P2>
      void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);

    // observers:
    hasher hash_function() const;
    key_equal key_eq() const;

    // set operations:
    iterator       find(const key_type& k);
    const_iterator find(const key_type& k) const;
    size_type      count(const key_type& k) const;
    pair<iterator, iterator>             equal_range(const key_type& k);
    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;

    // bucket interface:
    size_type bucket_count() const noexcept;
    size_type max_bucket_count() const noexcept;
    size_type bucket_size(size_type n) const;
    size_type bucket(const key_type& k) const;
    local_iterator begin(size_type n);
    const_local_iterator begin(size_type n) const;
    local_iterator end(size_type n);
    const_local_iterator end(size_type n) const;
    const_local_iterator cbegin(size_type n) const;
    const_local_iterator cend(size_type n) const;

    // hash policy:
    float load_factor() const noexcept;
    float max_load_factor() const noexcept;
    void max_load_factor(float z);
    void rehash(size_type n);
    void reserve(size_type n);
  };

  template<class InputIterator,
           class Hash = hash<typename iterator_traits<InputIterator>::value_type>,
           class Pred = equal_to<typename iterator_traits<InputIterator>::value_type>,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    unordered_set(InputIterator, InputIterator, typename see below::size_type = see below,
                  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -> unordered_set<typename iterator_traits<InputIterator>::value_type,
                       Hash, Pred, Allocator>;

  template<class T, class Hash = hash<T>,
           class Pred = equal_to<T>, class Allocator = allocator<T>>
    unordered_set(initializer_list<T>, typename see below::size_type = see below,
                  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -> unordered_set<T, Hash, Pred, Allocator>;

  template<class InputIterator, class Allocator>
    unordered_set(InputIterator, InputIterator, typename see below::size_type, Allocator)
      -> unordered_set<typename iterator_traits<InputIterator>::value_type,
                       hash<typename iterator_traits<InputIterator>::value_type>,
                       equal_to<typename iterator_traits<InputIterator>::value_type>,
                       Allocator>;

  template<class InputIterator, class Hash, class Allocator>
    unordered_set(InputIterator, InputIterator, typename see below::size_type,
                  Hash, Allocator)
      -> unordered_set<typename iterator_traits<InputIterator>::value_type, Hash,
                       equal_to<typename iterator_traits<InputIterator>::value_type>,
                       Allocator>;

  template<class T, class Allocator>
    unordered_set(initializer_list<T>, typename see below::size_type, Allocator)
      -> unordered_set<T, hash<T>, equal_to<T>, Allocator>;

  template<class T, class Hash, class Allocator>
    unordered_set(initializer_list<T>, typename see below::size_type, Hash, Allocator)
      -> unordered_set<T, Hash, equal_to<T>, Allocator>;

  template <class Key, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a,
                    const unordered_set<Key, Hash, Pred, Alloc>& b);
  template <class Key, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_set<Key, Hash, Pred, Alloc>& a,
                    const unordered_set<Key, Hash, Pred, Alloc>& b);

  // [unord.set.swap], swap
  template <class Key, class Hash, class Pred, class Alloc>
    void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
              unordered_set<Key, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));
}
A size_­type parameter type in an unordered_­set deduction guide refers to the size_­type member type of the primary unordered_­set template.

26.5.6.2 unordered_­set constructors [unord.set.cnstr]

unordered_set() : unordered_set(size_type(see below)) { } explicit unordered_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­set using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_­load_­factor() returns 1.0.
Complexity: Constant.
template <class InputIterator> unordered_set(InputIterator f, InputIterator l, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_set(initializer_list<value_type> il, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­set using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l) for the first form, or from the range [il.begin(), il.end()) for the second form.
max_­load_­factor() returns 1.0.
Complexity: Average case linear, worst case quadratic.

26.5.6.3 unordered_­set swap [unord.set.swap]

template <class Key, class Hash, class Pred, class Alloc> void swap(unordered_set<Key, Hash, Pred, Alloc>& x, unordered_set<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.5.7 Class template unordered_­multiset [unord.multiset]

26.5.7.1 Class template unordered_­multiset overview [unord.multiset.overview]

An unordered_­multiset is an unordered associative container that supports equivalent keys (an instance of unordered_­multiset may contain multiple copies of the same key value) and in which each element's key is the element itself.
The unordered_­multiset class supports forward iterators.
An unordered_­multiset satisfies all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 81).
It provides the operations described in the preceding requirements table for equivalent keys; that is, an unordered_­multiset supports the a_­eq operations in that table, not the a_­uniq operations.
For an unordered_­multiset<Key> the key type and the value type are both Key.
The iterator and const_­iterator types are both constant iterator types.
It is unspecified whether they are the same type.
This section only describes operations on unordered_­multiset that are not described in one of the requirement tables, or for which there is additional semantic information.
namespace std {
  template <class Key,
            class Hash = hash<Key>,
            class Pred = equal_to<Key>,
            class Allocator = allocator<Key>>
  class unordered_multiset {
  public:
    // types:
    using key_type             = Key;
    using value_type           = Key;
    using hasher               = Hash;
    using key_equal            = Pred;
    using allocator_type       = Allocator;
    using pointer              = typename allocator_traits<Allocator>::pointer;
    using const_pointer        = typename allocator_traits<Allocator>::const_pointer;
    using reference            = value_type&;
    using const_reference      = const value_type&;
    using size_type            = implementation-defined; // see [container.requirements]
    using difference_type      = implementation-defined; // see [container.requirements]

    using iterator             = implementation-defined; // see [container.requirements]
    using const_iterator       = implementation-defined; // see [container.requirements]
    using local_iterator       = implementation-defined; // see [container.requirements]
    using const_local_iterator = implementation-defined; // see [container.requirements]
    using node_type            = unspecified;

    // [unord.multiset.cnstr], construct/copy/destroy
    unordered_multiset();
    explicit unordered_multiset(size_type n,
                                const hasher& hf = hasher(),
                                const key_equal& eql = key_equal(),
                                const allocator_type& a = allocator_type());
    template <class InputIterator>
      unordered_multiset(InputIterator f, InputIterator l,
                         size_type n = see below,
                         const hasher& hf = hasher(),
                         const key_equal& eql = key_equal(),
                         const allocator_type& a = allocator_type());
    unordered_multiset(const unordered_multiset&);
    unordered_multiset(unordered_multiset&&);
    explicit unordered_multiset(const Allocator&);
    unordered_multiset(const unordered_multiset&, const Allocator&);
    unordered_multiset(unordered_multiset&&, const Allocator&);
    unordered_multiset(initializer_list<value_type> il,
                       size_type n = see below,
                       const hasher& hf = hasher(),
                       const key_equal& eql = key_equal(),
                       const allocator_type& a = allocator_type());
    unordered_multiset(size_type n, const allocator_type& a)
      : unordered_multiset(n, hasher(), key_equal(), a) { }
    unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
      : unordered_multiset(n, hf, key_equal(), a) { }
    template <class InputIterator>
      unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
        : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
    template <class InputIterator>
      unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
                         const allocator_type& a)
      : unordered_multiset(f, l, n, hf, key_equal(), a) { }
    unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
      : unordered_multiset(il, n, hasher(), key_equal(), a) { }
    unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf,
                       const allocator_type& a)
      : unordered_multiset(il, n, hf, key_equal(), a) { }
    ~unordered_multiset();
    unordered_multiset& operator=(const unordered_multiset&);
    unordered_multiset& operator=(unordered_multiset&&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_move_assignable_v<Hash> &&
               is_nothrow_move_assignable_v<Pred>);
    unordered_multiset& operator=(initializer_list<value_type>);
    allocator_type get_allocator() const noexcept;

    // iterators:
    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;
    const_iterator cbegin() const noexcept;
    const_iterator cend() const noexcept;

    // capacity:
    bool      empty() const noexcept;
    size_type size() const noexcept;
    size_type max_size() const noexcept;

    // modifiers:
    template <class... Args> iterator emplace(Args&&... args);
    template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
    iterator insert(const value_type& obj);
    iterator insert(value_type&& obj);
    iterator insert(const_iterator hint, const value_type& obj);
    iterator insert(const_iterator hint, value_type&& obj);
    template <class InputIterator> void insert(InputIterator first, InputIterator last);
    void insert(initializer_list<value_type>);

    node_type extract(const_iterator position);
    node_type extract(const key_type& x);
    iterator insert(node_type&& nh);
    iterator insert(const_iterator hint, node_type&& nh);

    iterator  erase(iterator position);
    iterator  erase(const_iterator position);
    size_type erase(const key_type& k);
    iterator  erase(const_iterator first, const_iterator last);
    void      swap(unordered_multiset&)
      noexcept(allocator_traits<Allocator>::is_always_equal::value &&
               is_nothrow_swappable_v<Hash> &&
               is_nothrow_swappable_v<Pred>);
    void      clear() noexcept;

    template<class H2, class P2>
      void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
    template<class H2, class P2>
      void merge(unordered_set<Key, H2, P2, Allocator>& source);
    template<class H2, class P2>
      void merge(unordered_set<Key, H2, P2, Allocator>&& source);

    // observers:
    hasher hash_function() const;
    key_equal key_eq() const;

    // set operations:
    iterator       find(const key_type& k);
    const_iterator find(const key_type& k) const;
    size_type      count(const key_type& k) const;
    pair<iterator, iterator>             equal_range(const key_type& k);
    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;

    // bucket interface:
    size_type bucket_count() const noexcept;
    size_type max_bucket_count() const noexcept;
    size_type bucket_size(size_type n) const;
    size_type bucket(const key_type& k) const;
    local_iterator begin(size_type n);
    const_local_iterator begin(size_type n) const;
    local_iterator end(size_type n);
    const_local_iterator end(size_type n) const;
    const_local_iterator cbegin(size_type n) const;
    const_local_iterator cend(size_type n) const;

    // hash policy:
    float load_factor() const noexcept;
    float max_load_factor() const noexcept;
    void max_load_factor(float z);
    void rehash(size_type n);
    void reserve(size_type n);
  };

  template<class InputIterator,
           class Hash = hash<typename iterator_traits<InputIterator>::value_type>,
           class Pred = equal_to<typename iterator_traits<InputIterator>::value_type>,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    unordered_multiset(InputIterator, InputIterator, see below::size_type = see below,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -> unordered_multiset<typename iterator_traits<InputIterator>::value_type,
                            Hash, Pred, Allocator>;

  template<class T, class Hash = hash<T>,
           class Pred = equal_to<T>, class Allocator = allocator<T>>
    unordered_multiset(initializer_list<T>, typename see below::size_type = see below,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -> unordered_multiset<T, Hash, Pred, Allocator>;

  template<class InputIterator, class Allocator>
    unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator)
      -> unordered_multiset<typename iterator_traits<InputIterator>::value_type,
                            hash<typename iterator_traits<InputIterator>::value_type>,
                            equal_to<typename iterator_traits<InputIterator>::value_type>,
                            Allocator>;

  template<class InputIterator, class Hash, class Allocator>
    unordered_multiset(InputIterator, InputIterator, typename see below::size_type,
                       Hash, Allocator)
      -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash,
                            equal_to<typename iterator_traits<InputIterator>::value_type>,
                            Allocator>;

  template<class T, class Allocator>
    unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator)
      -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>;

  template<class T, class Hash, class Allocator>
    unordered_multiset(initializer_list<T>, typename see below::size_type, Hash, Allocator)
      -> unordered_multiset<T, Hash, equal_to<T>, Allocator>;

  template <class Key, class Hash, class Pred, class Alloc>
    bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
                    const unordered_multiset<Key, Hash, Pred, Alloc>& b);
  template <class Key, class Hash, class Pred, class Alloc>
    bool operator!=(const unordered_multiset<Key, Hash, Pred, Alloc>& a,
                    const unordered_multiset<Key, Hash, Pred, Alloc>& b);

  // [unord.multiset.swap], swap
  template <class Key, class Hash, class Pred, class Alloc>
    void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
              unordered_multiset<Key, Hash, Pred, Alloc>& y)
      noexcept(noexcept(x.swap(y)));
}
A size_­type parameter type in an unordered_­multiset deduction guide refers to the size_­type member type of the primary unordered_­multiset template.

26.5.7.2 unordered_­multiset constructors [unord.multiset.cnstr]

unordered_multiset() : unordered_multiset(size_type(see below)) { } explicit unordered_multiset(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­multiset using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_­load_­factor() returns 1.0.
Complexity: Constant.
template <class InputIterator> unordered_multiset(InputIterator f, InputIterator l, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_multiset(initializer_list<value_type> il, size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type());
Effects: Constructs an empty unordered_­multiset using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l) for the first form, or from the range [il.begin(), il.end()) for the second form.
max_­load_­factor() returns 1.0.
Complexity: Average case linear, worst case quadratic.

26.5.7.3 unordered_­multiset swap [unord.multiset.swap]

template <class Key, class Hash, class Pred, class Alloc> void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x, unordered_multiset<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
Effects: As if by x.swap(y).

26.6 Container adaptors [container.adaptors]

26.6.1 In general [container.adaptors.general]

The headers <queue> and <stack> define the container adaptors queue, priority_­queue, and stack.
The container adaptors each take a Container template parameter, and each constructor takes a Container reference argument.
This container is copied into the Container member of each adaptor.
If the container takes an allocator, then a compatible allocator may be passed in to the adaptor's constructor.
Otherwise, normal copy or move construction is used for the container argument.
The first template parameter T of the container adaptors shall denote the same type as Container​::​value_­type.
For container adaptors, no swap function throws an exception unless that exception is thrown by the swap of the adaptor's Container or Compare object (if any).
A deduction guide for a container adaptor shall not participate in overload resolution if any of the following are true:
  • It has an InputIterator template parameter and a type that does not qualify as an input iterator is deduced for that parameter.
  • It has a Compare template parameter and a type that qualifies as an allocator is deduced for that parameter.
  • It has a Container template parameter and a type that qualifies as an allocator is deduced for that parameter.
  • It has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter.
  • It has both Container and Allocator template parameters, and uses_­allocator_­v<Container, Allocator> is false.

26.6.2 Header <queue> synopsis [queue.syn]

#include <initializer_list>

namespace std {
  template <class T, class Container = deque<T>> class queue;
  template <class T, class Container = vector<T>,
            class Compare = less<typename Container::value_type>>
    class priority_queue;

  template <class T, class Container>
    bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);

  template <class T, class Container>
    void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
  template <class T, class Container, class Compare>
    void swap(priority_queue<T, Container, Compare>& x,
              priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
}

26.6.3 Header <stack> synopsis [stack.syn]

#include <initializer_list>

namespace std {
  template <class T, class Container = deque<T>> class stack;
  template <class T, class Container>
    bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
}

26.6.4 Class template queue [queue]

26.6.4.1 queue definition [queue.defn]

Any sequence container supporting operations front(), back(), push_­back() and pop_­front() can be used to instantiate queue.
In particular, list ([list]) and deque ([deque]) can be used.
namespace std {
  template <class T, class Container = deque<T>>
  class queue {
  public:
    using value_type      = typename Container::value_type;
    using reference       = typename Container::reference;
    using const_reference = typename Container::const_reference;
    using size_type       = typename Container::size_type;
    using container_type  =          Container;

  protected:
    Container c;

  public:
    explicit queue(const Container&);
    explicit queue(Container&& = Container());
    template <class Alloc> explicit queue(const Alloc&);
    template <class Alloc> queue(const Container&, const Alloc&);
    template <class Alloc> queue(Container&&, const Alloc&);
    template <class Alloc> queue(const queue&, const Alloc&);
    template <class Alloc> queue(queue&&, const Alloc&);

    bool              empty() const     { return c.empty(); }
    size_type         size()  const     { return c.size(); }
    reference         front()           { return c.front(); }
    const_reference   front() const     { return c.front(); }
    reference         back()            { return c.back(); }
    const_reference   back() const      { return c.back(); }
    void push(const value_type& x)      { c.push_back(x); }
    void push(value_type&& x)           { c.push_back(std::move(x)); }
    template <class... Args>
      reference emplace(Args&&... args) { return c.emplace_back(std::forward<Args>(args)...); }
    void pop()                          { c.pop_front(); }
    void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
      { using std::swap; swap(c, q.c); }
  };

  template<class Container>
    queue(Container) -> queue<typename Container::value_type, Container>;

  template<class Container, class Allocator>
    queue(Container, Allocator) -> queue<typename Container::value_type, Container>;

  template <class T, class Container>
    bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
  template <class T, class Container>
    bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);

  template <class T, class Container>
    void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));

  template <class T, class Container, class Alloc>
    struct uses_allocator<queue<T, Container>, Alloc>
      : uses_allocator<Container, Alloc>::type { };
}

26.6.4.2 queue constructors [queue.cons]

explicit queue(const Container& cont);
Effects: Initializes c with cont.
explicit queue(Container&& cont = Container());
Effects: Initializes c with std​::​move(cont).

26.6.4.3 queue constructors with allocators [queue.cons.alloc]

If uses_­allocator_­v<container_­type, Alloc> is false the constructors in this subclause shall not participate in overload resolution.
template <class Alloc> explicit queue(const Alloc& a);
Effects: Initializes c with a.
template <class Alloc> queue(const container_type& cont, const Alloc& a);
Effects: Initializes c with cont as the first argument and a as the second argument.
template <class Alloc> queue(container_type&& cont, const Alloc& a);
Effects: Initializes c with std​::​move(cont) as the first argument and a as the second argument.
template <class Alloc> queue(const queue& q, const Alloc& a);
Effects: Initializes c with q.c as the first argument and a as the second argument.
template <class Alloc> queue(queue&& q, const Alloc& a);
Effects: Initializes c with std​::​move(q.c) as the first argument and a as the second argument.

26.6.4.4 queue operators [queue.ops]

template <class T, class Container> bool operator==(const queue<T, Container>& x, const queue<T, Container>& y);
Returns: x.c == y.c.
template <class T, class Container> bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y);
Returns: x.c != y.c.
template <class T, class Container> bool operator< (const queue<T, Container>& x, const queue<T, Container>& y);
Returns: x.c < y.c.
template <class T, class Container> bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y);
Returns: x.c <= y.c.
template <class T, class Container> bool operator> (const queue<T, Container>& x, const queue<T, Container>& y);
Returns: x.c > y.c.
template <class T, class Container> bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y);
Returns: x.c >= y.c.

26.6.4.5 queue specialized algorithms [queue.special]

template <class T, class Container> void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y)));
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<Container> is true.
Effects: As if by x.swap(y).

26.6.5 Class template priority_­queue [priority.queue]

Any sequence container with random access iterator and supporting operations front(), push_­back() and pop_­back() can be used to instantiate priority_­queue.
In particular, vector ([vector]) and deque ([deque]) can be used.
Instantiating priority_­queue also involves supplying a function or function object for making priority comparisons; the library assumes that the function or function object defines a strict weak ordering ([alg.sorting]).
namespace std {
  template <class T, class Container = vector<T>,
    class Compare = less<typename Container::value_type>>
  class priority_queue {
  public:
    using value_type      = typename Container::value_type;
    using reference       = typename Container::reference;
    using const_reference = typename Container::const_reference;
    using size_type       = typename Container::size_type;
    using container_type  = Container;
    using value_compare   = Compare;

  protected:
    Container c;
    Compare comp;

  public:
    priority_queue(const Compare& x, const Container&);
    explicit priority_queue(const Compare& x = Compare(), Container&& = Container());
    template <class InputIterator>
      priority_queue(InputIterator first, InputIterator last,
             const Compare& x, const Container&);
    template <class InputIterator>
      priority_queue(InputIterator first, InputIterator last,
             const Compare& x = Compare(), Container&& = Container());
    template <class Alloc> explicit priority_queue(const Alloc&);
    template <class Alloc> priority_queue(const Compare&, const Alloc&);
    template <class Alloc> priority_queue(const Compare&, const Container&, const Alloc&);
    template <class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
    template <class Alloc> priority_queue(const priority_queue&, const Alloc&);
    template <class Alloc> priority_queue(priority_queue&&, const Alloc&);

    bool      empty() const       { return c.empty(); }
    size_type size()  const       { return c.size(); }
    const_reference   top() const { return c.front(); }
    void push(const value_type& x);
    void push(value_type&& x);
    template <class... Args> void emplace(Args&&... args);
    void pop();
    void swap(priority_queue& q) noexcept(is_nothrow_swappable_v<Container> &&
                                          is_nothrow_swappable_v<Compare>)
      { using std::swap; swap(c, q.c); swap(comp, q.comp); }
  };

  template<class Compare, class Container>
    priority_queue(Compare, Container)
      -> priority_queue<typename Container::value_type, Container, Compare>;

  template<class InputIterator,
           class Compare = less<typename iterator_traits<InputIterator>::value_type>,
           class Container = vector<typename iterator_traits<InputIterator>::value_type>>
    priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
      -> priority_queue<typename iterator_traits<InputIterator>::value_type, Container, Compare>;

  template<class Compare, class Container, class Allocator>
    priority_queue(Compare, Container, Allocator)
      -> priority_queue<typename Container::value_type, Container, Compare>;

  // no equality is provided

  template <class T, class Container, class Compare>
    void swap(priority_queue<T, Container, Compare>& x,
              priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));

  template <class T, class Container, class Compare, class Alloc>
    struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>
      : uses_allocator<Container, Alloc>::type { };
}

26.6.5.1 priority_­queue constructors [priqueue.cons]

priority_queue(const Compare& x, const Container& y); explicit priority_queue(const Compare& x = Compare(), Container&& y = Container());
Requires: x shall define a strict weak ordering ([alg.sorting]).
Effects: Initializes comp with x and c with y (copy constructing or move constructing as appropriate); calls make_­heap(c.begin(), c.end(), comp).
template <class InputIterator> priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y); template <class InputIterator> priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare(), Container&& y = Container());
Requires: x shall define a strict weak ordering ([alg.sorting]).
Effects: Initializes comp with x and c with y (copy constructing or move constructing as appropriate); calls c.insert(c.end(), first, last); and finally calls make_­heap(c.begin(), c.end(), comp).

26.6.5.2 priority_­queue constructors with allocators [priqueue.cons.alloc]

If uses_­allocator_­v<container_­type, Alloc> is false the constructors in this subclause shall not participate in overload resolution.
template <class Alloc> explicit priority_queue(const Alloc& a);
Effects: Initializes c with a and value-initializes comp.
template <class Alloc> priority_queue(const Compare& compare, const Alloc& a);
Effects: Initializes c with a and initializes comp with compare.
template <class Alloc> priority_queue(const Compare& compare, const Container& cont, const Alloc& a);
Effects: Initializes c with cont as the first argument and a as the second argument, and initializes comp with compare; calls make_­heap(c.begin(), c.end(), comp).
template <class Alloc> priority_queue(const Compare& compare, Container&& cont, const Alloc& a);
Effects: Initializes c with std​::​move(cont) as the first argument and a as the second argument, and initializes comp with compare; calls make_­heap(c.begin(), c.end(), comp).
template <class Alloc> priority_queue(const priority_queue& q, const Alloc& a);
Effects: Initializes c with q.c as the first argument and a as the second argument, and initializes comp with q.comp.
template <class Alloc> priority_queue(priority_queue&& q, const Alloc& a);
Effects: Initializes c with std​::​move(q.c) as the first argument and a as the second argument, and initializes comp with std​::​move(q.comp).

26.6.5.3 priority_­queue members [priqueue.members]

void push(const value_type& x);
Effects: As if by:
c.push_back(x);
push_heap(c.begin(), c.end(), comp);
void push(value_type&& x);
Effects: As if by:
c.push_back(std::move(x));
push_heap(c.begin(), c.end(), comp);
template <class... Args> void emplace(Args&&... args)
Effects: As if by:
c.emplace_back(std::forward<Args>(args)...);
push_heap(c.begin(), c.end(), comp);
void pop();
Effects: As if by:
pop_heap(c.begin(), c.end(), comp);
c.pop_back();

26.6.5.4 priority_­queue specialized algorithms [priqueue.special]

template <class T, class Container, class Compare> void swap(priority_queue<T, Container, Compare>& x, priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<Container> is true and is_­swappable_­v<Compare> is true.
Effects: As if by x.swap(y).

26.6.6 Class template stack [stack]

Any sequence container supporting operations back(), push_­back() and pop_­back() can be used to instantiate stack.
In particular, vector ([vector]), list ([list]) and deque ([deque]) can be used.

26.6.6.1 stack definition [stack.defn]

namespace std {
  template <class T, class Container = deque<T>>
  class stack {
  public:
    using value_type      = typename Container::value_type;
    using reference       = typename Container::reference;
    using const_reference = typename Container::const_reference;
    using size_type       = typename Container::size_type;
    using container_type  = Container;

  protected:
    Container c;

  public:
    explicit stack(const Container&);
    explicit stack(Container&& = Container());
    template <class Alloc> explicit stack(const Alloc&);
    template <class Alloc> stack(const Container&, const Alloc&);
    template <class Alloc> stack(Container&&, const Alloc&);
    template <class Alloc> stack(const stack&, const Alloc&);
    template <class Alloc> stack(stack&&, const Alloc&);

    bool      empty() const             { return c.empty(); }
    size_type size()  const             { return c.size(); }
    reference         top()             { return c.back(); }
    const_reference   top() const       { return c.back(); }
    void push(const value_type& x)      { c.push_back(x); }
    void push(value_type&& x)           { c.push_back(std::move(x)); }
    template <class... Args>
      reference emplace(Args&&... args) { return c.emplace_back(std::forward<Args>(args)...); }
    void pop()                          { c.pop_back(); }
    void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>)
      { using std::swap; swap(c, s.c); }
  };

  template<class Container>
    stack(Container) -> stack<typename Container::value_type, Container>;

  template<class Container, class Allocator>
    stack(Container, Allocator) -> stack<typename Container::value_type, Container>;

  template <class T, class Container>
    bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
  template <class T, class Container>
    void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));

  template <class T, class Container, class Alloc>
    struct uses_allocator<stack<T, Container>, Alloc>
      : uses_allocator<Container, Alloc>::type { };
}

26.6.6.2 stack constructors [stack.cons]

explicit stack(const Container& cont);
Effects: Initializes c with cont.
explicit stack(Container&& cont = Container());
Effects: Initializes c with std​::​move(cont).

26.6.6.3 stack constructors with allocators [stack.cons.alloc]

If uses_­allocator_­v<container_­type, Alloc> is false the constructors in this subclause shall not participate in overload resolution.
template <class Alloc> explicit stack(const Alloc& a);
Effects: Initializes c with a.
template <class Alloc> stack(const container_type& cont, const Alloc& a);
Effects: Initializes c with cont as the first argument and a as the second argument.
template <class Alloc> stack(container_type&& cont, const Alloc& a);
Effects: Initializes c with std​::​move(cont) as the first argument and a as the second argument.
template <class Alloc> stack(const stack& s, const Alloc& a);
Effects: Initializes c with s.c as the first argument and a as the second argument.
template <class Alloc> stack(stack&& s, const Alloc& a);
Effects: Initializes c with std​::​move(s.c) as the first argument and a as the second argument.

26.6.6.4 stack operators [stack.ops]

template <class T, class Container> bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
Returns: x.c == y.c.
template <class T, class Container> bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
Returns: x.c != y.c.
template <class T, class Container> bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
Returns: x.c < y.c.
template <class T, class Container> bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
Returns: x.c <= y.c.
template <class T, class Container> bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
Returns: x.c > y.c.
template <class T, class Container> bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
Returns: x.c >= y.c.

26.6.6.5 stack specialized algorithms [stack.special]

template <class T, class Container> void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y)));
Remarks: This function shall not participate in overload resolution unless is_­swappable_­v<Container> is true.
Effects: As if by x.swap(y).

27 Iterators library [iterators]

27.1 General [iterators.general]

This Clause describes components that C++ programs may use to perform iterations over containers (Clause [containers]), streams ([iostream.format]), and stream buffers ([stream.buffers]).
The following subclauses describe iterator requirements, and components for iterator primitives, predefined iterators, and stream iterators, as summarized in Table 87.
Table 87 — Iterators library summary
Subclause
Header(s)
Requirements
Iterator primitives
<iterator>
Predefined iterators
Stream iterators

27.2 Iterator requirements [iterator.requirements]

27.2.1 In general [iterator.requirements.general]

Iterators are a generalization of pointers that allow a C++ program to work with different data structures (containers) in a uniform manner.
To be able to construct template algorithms that work correctly and efficiently on different types of data structures, the library formalizes not just the interfaces but also the semantics and complexity assumptions of iterators.
An input iterator i supports the expression *i, resulting in a value of some object type T, called the value type of the iterator.
An output iterator i has a non-empty set of types that are writable to the iterator; for each such type T, the expression *i = o is valid where o is a value of type T.
An iterator i for which the expression (*i).m is well-defined supports the expression i->m with the same semantics as (*i).m.
For every iterator type X for which equality is defined, there is a corresponding signed integer type called the difference type of the iterator.
Since iterators are an abstraction of pointers, their semantics is a generalization of most of the semantics of pointers in C++.
This ensures that every function template that takes iterators works as well with regular pointers.
This International Standard defines five categories of iterators, according to the operations defined on them: input iterators, output iterators, forward iterators, bidirectional iterators and random access iterators, as shown in Table 88.
Table 88 — Relations among iterator categories
Random Access
Bidirectional
Forward
Input
Output
Forward iterators satisfy all the requirements of input iterators and can be used whenever an input iterator is specified; Bidirectional iterators also satisfy all the requirements of forward iterators and can be used whenever a forward iterator is specified; Random access iterators also satisfy all the requirements of bidirectional iterators and can be used whenever a bidirectional iterator is specified.
Iterators that further satisfy the requirements of output iterators are called mutable iterators.
Nonmutable iterators are referred to as constant iterators.
In addition to the requirements in this subclause, the nested typedef-names specified in [iterator.traits] shall be provided for the iterator type.
[Note
:
Either the iterator type must provide the typedef-names directly (in which case iterator_­traits pick them up automatically), or an iterator_­traits specialization must provide them.
end note
]
Iterators that further satisfy the requirement that, for integral values n and dereferenceable iterator values a and (a + n), *(a + n) is equivalent to *(addressof(*a) + n), are called contiguous iterators.
[Note
:
For example, the type “pointer to int” is a contiguous iterator, but reverse_­iterator<int *> is not.
For a valid iterator range [ab) with dereferenceable a, the corresponding range denoted by pointers is [addressof(*a)addressof(*a) + (b - a)); b might not be dereferenceable.
end note
]
Just as a regular pointer to an array guarantees that there is a pointer value pointing past the last element of the array, so for any iterator type there is an iterator value that points past the last element of a corresponding sequence.
These values are called past-the-end values.
Values of an iterator i for which the expression *i is defined are called dereferenceable.
The library never assumes that past-the-end values are dereferenceable.
Iterators can also have singular values that are not associated with any sequence.
[Example
:
After the declaration of an uninitialized pointer x (as with int* x;), x must always be assumed to have a singular value of a pointer.
end example
]
Results of most expressions are undefined for singular values; the only exceptions are destroying an iterator that holds a singular value, the assignment of a non-singular value to an iterator that holds a singular value, and, for iterators that satisfy the DefaultConstructible requirements, using a value-initialized iterator as the source of a copy or move operation.
[Note
:
This guarantee is not offered for default-initialization, although the distinction only matters for types with trivial default constructors such as pointers or aggregates holding pointers.
end note
]
In these cases the singular value is overwritten the same way as any other value.
Dereferenceable values are always non-singular.
An iterator j is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == j.
If j is reachable from i, they refer to elements of the same sequence.
Most of the library's algorithmic templates that operate on data structures have interfaces that use ranges.
A range is a pair of iterators that designate the beginning and end of the computation.
A range [i, i) is an empty range; in general, a range [i, j) refers to the elements in the data structure starting with the element pointed to by i and up to but not including the element pointed to by j.
Range [i, j) is valid if and only if j is reachable from i.
The result of the application of functions in the library to invalid ranges is undefined.
All the categories of iterators require only those functions that are realizable for a given category in constant time (amortized).
Therefore, requirement tables for the iterators do not have a complexity column.
Destruction of an iterator may invalidate pointers and references previously obtained from that iterator.
An invalid iterator is an iterator that may be singular.261
In the following sections, a and b denote values of type X or const X, difference_­type and reference refer to the types iterator_­traits<X>​::​difference_­type and iterator_­traits<X>​::​reference, respectively, n denotes a value of difference_­type, u, tmp, and m denote identifiers, r denotes a value of X&, t denotes a value of value type T, o denotes a value of some type that is writable to the output iterator.
[Note
:
For an iterator type X there must be an instantiation of iterator_­traits<X> ([iterator.traits]).
end note
]
This definition applies to pointers, since pointers are iterators.
The effect of dereferencing an iterator that has been invalidated is undefined.

27.2.2 Iterator [iterator.iterators]

The Iterator requirements form the basis of the iterator concept taxonomy; every iterator satisfies the Iterator requirements.
This set of requirements specifies operations for dereferencing and incrementing an iterator.
Most algorithms will require additional operations to read ([input.iterators]) or write ([output.iterators]) values, or to provide a richer set of iterator movements ([forward.iterators], [bidirectional.iterators], [random.access.iterators]).
A type X satisfies the Iterator requirements if:
Table 89 — Iterator requirements
Expression
Return type
Operational
Assertion/note
semantics
pre-/post-condition
*r
unspecified
Requires: r is dereferenceable.
++r
X&

27.2.3 Input iterators [input.iterators]

A class or pointer type X satisfies the requirements of an input iterator for the value type T if X satisfies the Iterator ([iterator.iterators]) and EqualityComparable (Table 20) requirements and the expressions in Table 90 are valid and have the indicated semantics.
In Table 90, the term the domain of == is used in the ordinary mathematical sense to denote the set of values over which == is (required to be) defined.
This set can change over time.
Each algorithm places additional requirements on the domain of == for the iterator values it uses.
These requirements can be inferred from the uses that algorithm makes of == and !=.
[Example
:
The call find(a,b,x) is defined only if the value of a has the property p defined as follows: b has property p and a value i has property p if (*i==x) or if (*i!=x and ++i has property p).
end example
]
Table 90 — Input iterator requirements (in addition to Iterator)
Expression
Return type
Operational
Assertion/note
semantics
pre-/post-condition
a != b
contextually convertible to bool
!(a == b)
Requires: (a, b) is in the domain of ==.
*a
reference, convertible to T
Requires: a is dereferenceable.

The expression
(void)*a, *a is equivalent to *a.

If a == b and (a, b) is in the domain of == then *a is equivalent to *b.
a->m
(*a).m
Requires: a is dereferenceable.
++r
X&
Requires: r is dereferenceable.

Postconditions: r is dereferenceable or r is past-the-end;
any copies of the previous value of r are no longer required either to be dereferenceable or to be in the domain of ==.
(void)r++
equivalent to (void)++r
*r++
convertible to T
{ T tmp = *r;
++r;
return tmp; }
[Note
:
For input iterators, a == b does not imply ++a == ++b.
(Equality does not guarantee the substitution property or referential transparency.)
Algorithms on input iterators should never attempt to pass through the same iterator twice.
They should be single pass algorithms.
Value type T is not required to be a CopyAssignable type (Table 26).
These algorithms can be used with istreams as the source of the input data through the istream_­iterator class template.
end note
]

27.2.4 Output iterators [output.iterators]

A class or pointer type X satisfies the requirements of an output iterator if X satisfies the Iterator requirements ([iterator.iterators]) and the expressions in Table 91 are valid and have the indicated semantics.
Table 91 — Output iterator requirements (in addition to Iterator)
Expression
Return type
Operational
Assertion/note
semantics
pre-/post-condition
*r = o
result is not used
Remarks: After this operation r is not required to be dereferenceable.

Postconditions: r is incrementable.
++r
X&
&r == &++r.

Remarks: After this operation r is not required to be dereferenceable.

Postconditions: r is incrementable.
r++
convertible to const X&
{ X tmp = r;
++r;
return tmp; }
Remarks: After this operation r is not required to be dereferenceable.

Postconditions: r is incrementable.
*r++ = o
result is not used
Remarks: After this operation r is not required to be dereferenceable.

Postconditions: r is incrementable.
[Note
:
The only valid use of an operator* is on the left side of the assignment statement.
Assignment through the same value of the iterator happens only once. Algorithms on output iterators should never attempt to pass through the same iterator twice.
They should be single pass algorithms.
Equality and inequality might not be defined.
Algorithms that take output iterators can be used with ostreams as the destination for placing data through the ostream_­iterator class as well as with insert iterators and insert pointers.
end note
]

27.2.5 Forward iterators [forward.iterators]

A class or pointer type X satisfies the requirements of a forward iterator if
  • X satisfies the requirements of an input iterator ([input.iterators]),
  • X satisfies the DefaultConstructible requirements ([utility.arg.requirements]),
  • if X is a mutable iterator, reference is a reference to T; if X is a constant iterator, reference is a reference to const T,
  • the expressions in Table 92 are valid and have the indicated semantics, and
  • objects of type X offer the multi-pass guarantee, described below.
The domain of == for forward iterators is that of iterators over the same underlying sequence.
However, value-initialized iterators may be compared and shall compare equal to other value-initialized iterators of the same type.
[Note
:
Value-initialized iterators behave as if they refer past the end of the same empty sequence.
end note
]
Two dereferenceable iterators a and b of type X offer the multi-pass guarantee if:
  • a == b implies ++a == ++b and
  • X is a pointer type or the expression (void)++X(a), *a is equivalent to the expression *a.
[Note
:
The requirement that a == b implies ++a == ++b (which is not true for input and output iterators) and the removal of the restrictions on the number of the assignments through a mutable iterator (which applies to output iterators) allows the use of multi-pass one-directional algorithms with forward iterators.
end note
]
Table 92 — Forward iterator requirements (in addition to input iterator)
Expression
Return type
Operational
Assertion/note
semantics
pre-/post-condition
r++
convertible to const X&
{ X tmp = r;
++r;
return tmp; }
*r++
reference
If a and b are equal, then either a and b are both dereferenceable or else neither is dereferenceable.
If a and b are both dereferenceable, then a == b if and only if *a and *b are bound to the same object.

27.2.6 Bidirectional iterators [bidirectional.iterators]

A class or pointer type X satisfies the requirements of a bidirectional iterator if, in addition to satisfying the requirements for forward iterators, the following expressions are valid as shown in Table 93.
Table 93 — Bidirectional iterator requirements (in addition to forward iterator)
Expression
Return type
Operational
Assertion/note
semantics
pre-/post-condition
--r
X&
Requires: there exists s such that r == ++s.

Postconditions: r is dereferenceable.

--(++r) == r.

--r == --s implies r == s.

&r == &--r.
r--
convertible to const X&
{ X tmp = r;
--r;
return tmp; }
*r--
reference
[Note
:
Bidirectional iterators allow algorithms to move iterators backward as well as forward.
end note
]

27.2.7 Random access iterators [random.access.iterators]

A class or pointer type X satisfies the requirements of a random access iterator if, in addition to satisfying the requirements for bidirectional iterators, the following expressions are valid as shown in Table 94.
Table 94 — Random access iterator requirements (in addition to bidirectional iterator)
Expression
Return type
Operational
Assertion/note
semantics
pre-/post-condition
r += n
X&
{ difference_­type m = n;
if (m >= 0)
while (m--)
++r;
else
while (m++)
--r;
return r; }
a + n
n + a
X
{ X tmp = a;
return tmp += n; }
a + n == n + a.
r -= n
X&
return r += -n;
Requires: the absolute value of n is in the range of representable values of difference_­type.
a - n
X
{ X tmp = a;
return tmp -= n; }
b - a
difference_­type
return n
Requires: there exists a value n of type difference_­type such that a + n == b.

b == a + (b - a).
a[n]
convertible to reference
*(a + n)
a < b
contextually convertible to bool
b - a > 0
< is a total ordering relation
a > b
contextually convertible to bool
b < a
> is a total ordering relation opposite to <.
a >= b
contextually convertible to bool
!(a < b)
a <= b
contextually convertible to bool.
!(a > b)

27.3 Header <iterator> synopsis [iterator.synopsis]

namespace std {
  // [iterator.primitives], primitives
  template<class Iterator> struct iterator_traits;
  template<class T> struct iterator_traits<T*>;
  template<class T> struct iterator_traits<const T*>;

  struct input_iterator_tag { };
  struct output_iterator_tag { };
  struct forward_iterator_tag: public input_iterator_tag { };
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };

  // [iterator.operations], iterator operations
  template <class InputIterator, class Distance>
    constexpr void advance(InputIterator& i, Distance n);
  template <class InputIterator>
    constexpr typename iterator_traits<InputIterator>::difference_type
    distance(InputIterator first, InputIterator last);
  template <class InputIterator>
    constexpr InputIterator next(InputIterator x,
      typename iterator_traits<InputIterator>::difference_type n = 1);
  template <class BidirectionalIterator>
    constexpr BidirectionalIterator prev(BidirectionalIterator x,
      typename iterator_traits<BidirectionalIterator>::difference_type n = 1);

  // [predef.iterators], predefined iterators
  template <class Iterator> class reverse_iterator;

  template <class Iterator1, class Iterator2>
    constexpr bool operator==(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator!=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);

  template <class Iterator1, class Iterator2>
    constexpr auto operator-(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y) ->decltype(y.base() - x.base());
  template <class Iterator>
    constexpr reverse_iterator<Iterator>
      operator+(
    typename reverse_iterator<Iterator>::difference_type n,
    const reverse_iterator<Iterator>& x);

  template <class Iterator>
    constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);

  template <class Container> class back_insert_iterator;
  template <class Container>
    back_insert_iterator<Container> back_inserter(Container& x);

  template <class Container> class front_insert_iterator;
  template <class Container>
    front_insert_iterator<Container> front_inserter(Container& x);

  template <class Container> class insert_iterator;
  template <class Container>
    insert_iterator<Container> inserter(Container& x, typename Container::iterator i);

  template <class Iterator> class move_iterator;
  template <class Iterator1, class Iterator2>
    constexpr bool operator==(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator!=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

  template <class Iterator1, class Iterator2>
    constexpr auto operator-(
    const move_iterator<Iterator1>& x,
    const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
  template <class Iterator>
    constexpr move_iterator<Iterator> operator+(
      typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
  template <class Iterator>
    constexpr move_iterator<Iterator> make_move_iterator(Iterator i);

  // [stream.iterators], stream iterators
  template <class T, class charT = char, class traits = char_traits<charT>,
      class Distance = ptrdiff_t>
  class istream_iterator;
  template <class T, class charT, class traits, class Distance>
    bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
            const istream_iterator<T,charT,traits,Distance>& y);
  template <class T, class charT, class traits, class Distance>
    bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
            const istream_iterator<T,charT,traits,Distance>& y);

  template <class T, class charT = char, class traits = char_traits<charT>>
      class ostream_iterator;

  template<class charT, class traits = char_traits<charT>>
    class istreambuf_iterator;
  template <class charT, class traits>
    bool operator==(const istreambuf_iterator<charT,traits>& a,
            const istreambuf_iterator<charT,traits>& b);
  template <class charT, class traits>
    bool operator!=(const istreambuf_iterator<charT,traits>& a,
            const istreambuf_iterator<charT,traits>& b);

  template <class charT, class traits = char_traits<charT>>
    class ostreambuf_iterator;

  // [iterator.range], range access
  template <class C> constexpr auto begin(C& c) -> decltype(c.begin());
  template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
  template <class C> constexpr auto end(C& c) -> decltype(c.end());
  template <class C> constexpr auto end(const C& c) -> decltype(c.end());
  template <class T, size_t N> constexpr T* begin(T (&array)[N]) noexcept;
  template <class T, size_t N> constexpr T* end(T (&array)[N]) noexcept;
  template <class C> constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c)))
    -> decltype(std::begin(c));
  template <class C> constexpr auto cend(const C& c) noexcept(noexcept(std::end(c)))
    -> decltype(std::end(c));
  template <class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());
  template <class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());
  template <class C> constexpr auto rend(C& c) -> decltype(c.rend());
  template <class C> constexpr auto rend(const C& c) -> decltype(c.rend());
  template <class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]);
  template <class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]);
  template <class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
  template <class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);
  template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
  template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));

  // [iterator.container], container access
  template <class C> constexpr auto size(const C& c) -> decltype(c.size());
  template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept;
  template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());
  template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;
  template <class E> constexpr bool empty(initializer_list<E> il) noexcept;
  template <class C> constexpr auto data(C& c) -> decltype(c.data());
  template <class C> constexpr auto data(const C& c) -> decltype(c.data());
  template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;
  template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
}

27.4 Iterator primitives [iterator.primitives]

To simplify the task of defining iterators, the library provides several classes and functions:

27.4.1 Iterator traits [iterator.traits]

To implement algorithms only in terms of iterators, it is often necessary to determine the value and difference types that correspond to a particular iterator type.
Accordingly, it is required that if Iterator is the type of an iterator, the types
iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type
iterator_traits<Iterator>::iterator_category
be defined as the iterator's difference type, value type and iterator category, respectively.
In addition, the types
iterator_traits<Iterator>::reference
iterator_traits<Iterator>::pointer
shall be defined as the iterator's reference and pointer types, that is, for an iterator object a, the same type as the type of *a and a->, respectively.
In the case of an output iterator, the types
iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type
iterator_traits<Iterator>::reference
iterator_traits<Iterator>::pointer
may be defined as void.
If Iterator has valid ([temp.deduct]) member types difference_­type, value_­type, pointer, reference, and iterator_­category, iterator_­traits<Iterator> shall have the following as publicly accessible members:
  using difference_type   = typename Iterator::difference_type;
  using value_type        = typename Iterator::value_type;
  using pointer           = typename Iterator::pointer;
  using reference         = typename Iterator::reference;
  using iterator_category = typename Iterator::iterator_category;
Otherwise, iterator_­traits<Iterator> shall have no members by any of the above names.
It is specialized for pointers as
namespace std {
  template<class T> struct iterator_traits<T*> {
    using difference_type   = ptrdiff_t;
    using value_type        = T;
    using pointer           = T*;
    using reference         = T&;
    using iterator_category = random_access_iterator_tag;
  };
}
and for pointers to const as
namespace std {
  template<class T> struct iterator_traits<const T*> {
    using difference_type   = ptrdiff_t;
    using value_type        = T;
    using pointer           = const T*;
    using reference         = const T&;
    using iterator_category = random_access_iterator_tag;
  };
}
[Example
:
To implement a generic reverse function, a C++ program can do the following:
template <class BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last) {
  typename iterator_traits<BidirectionalIterator>::difference_type n =
    distance(first, last);
  --n;
  while(n > 0) {
    typename iterator_traits<BidirectionalIterator>::value_type
     tmp = *first;
    *first++ = *--last;
    *last = tmp;
    n -= 2;
  }
}
end example
]

27.4.2 Standard iterator tags [std.iterator.tags]

It is often desirable for a function template specialization to find out what is the most specific category of its iterator argument, so that the function can select the most efficient algorithm at compile time.
To facilitate this, the library introduces category tag classes which are used as compile time tags for algorithm selection.
They are: input_­iterator_­tag, output_­iterator_­tag, forward_­iterator_­tag, bidirectional_­iterator_­tag and random_­access_­iterator_­tag.
For every iterator of type Iterator, iterator_­traits<Iterator>​::​iterator_­category shall be defined to be the most specific category tag that describes the iterator's behavior.
namespace std {
  struct input_iterator_tag { };
  struct output_iterator_tag { };
  struct forward_iterator_tag: public input_iterator_tag { };
  struct bidirectional_iterator_tag: public forward_iterator_tag { };
  struct random_access_iterator_tag: public bidirectional_iterator_tag { };
}
[Example
:
For a program-defined iterator BinaryTreeIterator, it could be included into the bidirectional iterator category by specializing the iterator_­traits template:
template<class T> struct iterator_traits<BinaryTreeIterator<T>> {
  using iterator_category = bidirectional_iterator_tag;
  using difference_type   = ptrdiff_t;
  using value_type        = T;
  using pointer           = T*;
  using reference         = T&;
};
end example
]
[Example
:
If evolve() is well defined for bidirectional iterators, but can be implemented more efficiently for random access iterators, then the implementation is as follows:
template <class BidirectionalIterator>
inline void
evolve(BidirectionalIterator first, BidirectionalIterator last) {
  evolve(first, last,
    typename iterator_traits<BidirectionalIterator>::iterator_category());
}

template <class BidirectionalIterator>
void evolve(BidirectionalIterator first, BidirectionalIterator last,
  bidirectional_iterator_tag) {
  // more generic, but less efficient algorithm
}

template <class RandomAccessIterator>
void evolve(RandomAccessIterator first, RandomAccessIterator last,
  random_access_iterator_tag) {
  // more efficient, but less generic algorithm
}
end example
]

27.4.3 Iterator operations [iterator.operations]

Since only random access iterators provide + and - operators, the library provides two function templates advance and distance.
These function templates use + and - for random access iterators (and are, therefore, constant time for them); for input, forward and bidirectional iterators they use ++ to provide linear time implementations.
template <class InputIterator, class Distance> constexpr void advance(InputIterator& i, Distance n);
Requires: n shall be negative only for bidirectional and random access iterators.
Effects: Increments (or decrements for negative n) iterator reference i by n.
template <class InputIterator> constexpr typename iterator_traits<InputIterator>::difference_type distance(InputIterator first, InputIterator last);
Effects: If InputIterator meets the requirements of random access iterator, returns (last - first); otherwise, returns the number of increments needed to get from first to last.
Requires: If InputIterator meets the requirements of random access iterator, last shall be reachable from first or first shall be reachable from last; otherwise, last shall be reachable from first.
template <class InputIterator> constexpr InputIterator next(InputIterator x, typename iterator_traits<InputIterator>::difference_type n = 1);
Effects: Equivalent to: advance(x, n); return x;
template <class BidirectionalIterator> constexpr BidirectionalIterator prev(BidirectionalIterator x, typename iterator_traits<BidirectionalIterator>::difference_type n = 1);
Effects: Equivalent to: advance(x, -n); return x;

27.5 Iterator adaptors [predef.iterators]

27.5.1 Reverse iterators [reverse.iterators]

Class template reverse_­iterator is an iterator adaptor that iterates from the end of the sequence defined by its underlying iterator to the beginning of that sequence.
The fundamental relation between a reverse iterator and its corresponding iterator i is established by the identity: &*(reverse_­iterator(i)) == &*(i - 1).

27.5.1.1 Class template reverse_­iterator [reverse.iterator]

namespace std {
  template <class Iterator>
  class reverse_iterator {
  public:
    using iterator_type     = Iterator;
    using iterator_category = typename iterator_traits<Iterator>::iterator_category;
    using value_type        = typename iterator_traits<Iterator>::value_type;
    using difference_type   = typename iterator_traits<Iterator>::difference_type;
    using pointer           = typename iterator_traits<Iterator>::pointer;
    using reference         = typename iterator_traits<Iterator>::reference;

    constexpr reverse_iterator();
    constexpr explicit reverse_iterator(Iterator x);
    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);

    constexpr Iterator base() const;      // explicit
    constexpr reference operator*() const;
    constexpr pointer   operator->() const;

    constexpr reverse_iterator& operator++();
    constexpr reverse_iterator  operator++(int);
    constexpr reverse_iterator& operator--();
    constexpr reverse_iterator  operator--(int);

    constexpr reverse_iterator  operator+ (difference_type n) const;
    constexpr reverse_iterator& operator+=(difference_type n);
    constexpr reverse_iterator  operator- (difference_type n) const;
    constexpr reverse_iterator& operator-=(difference_type n);
    constexpr unspecified operator[](difference_type n) const;
  protected:
    Iterator current;
  };

  template <class Iterator1, class Iterator2>
    constexpr bool operator==(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator!=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<=(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr auto operator-(
      const reverse_iterator<Iterator1>& x,
      const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
  template <class Iterator>
    constexpr reverse_iterator<Iterator> operator+(
      typename reverse_iterator<Iterator>::difference_type n,
      const reverse_iterator<Iterator>& x);

  template <class Iterator>
    constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
}

27.5.1.2 reverse_­iterator requirements [reverse.iter.requirements]

The template parameter Iterator shall meet all the requirements of a Bidirectional Iterator ([bidirectional.iterators]).
Additionally, Iterator shall meet the requirements of a random access iterator ([random.access.iterators]) if any of the members operator+ ([reverse.iter.op+]), operator- ([reverse.iter.op-]), operator+= ([reverse.iter.op+=]), operator-= ([reverse.iter.op-=]), operator[] ([reverse.iter.opindex]), or the non-member operators operator< ([reverse.iter.op<]), operator> ([reverse.iter.op>]),
operator<= ([reverse.iter.op<=]), operator>= ([reverse.iter.op>=]), operator- ([reverse.iter.opdiff]) or operator+ ([reverse.iter.opsum]) are referenced in a way that requires instantiation ([temp.inst]).

27.5.1.3 reverse_­iterator operations [reverse.iter.ops]

27.5.1.3.1 reverse_­iterator constructor [reverse.iter.cons]

constexpr reverse_iterator();
Effects: Value-initializes current.
Iterator operations applied to the resulting iterator have defined behavior if and only if the corresponding operations are defined on a value-initialized iterator of type Iterator.
constexpr explicit reverse_iterator(Iterator x);
Effects: Initializes current with x.
template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
Effects: Initializes current with u.current.

27.5.1.3.2 reverse_­iterator​::​operator= [reverse.iter.op=]

template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);
Effects: Assigns u.base() to current.
Returns: *this.

27.5.1.3.3 Conversion [reverse.iter.conv]

constexpr Iterator base() const; // explicit
Returns: current.

27.5.1.3.4 operator* [reverse.iter.op.star]

constexpr reference operator*() const;
Effects: As if by:
Iterator tmp = current;
return *--tmp;

27.5.1.3.5 operator-> [reverse.iter.opref]

constexpr pointer operator->() const;
Returns: addressof(operator*()).

27.5.1.3.6 operator++ [reverse.iter.op++]

constexpr reverse_iterator& operator++();
Effects: As if by: --current;
Returns: *this.
constexpr reverse_iterator operator++(int);
Effects: As if by:
reverse_iterator tmp = *this;
--current;
return tmp;

27.5.1.3.7 operator-- [reverse.iter.op--]

constexpr reverse_iterator& operator--();
Effects: As if by ++current.
Returns: *this.
constexpr reverse_iterator operator--(int);
Effects: As if by:
reverse_iterator tmp = *this;
++current;
return tmp;

27.5.1.3.8 operator+ [reverse.iter.op+]

constexpr reverse_iterator operator+(difference_type n) const;
Returns: reverse_­iterator(current-n).

27.5.1.3.9 operator+= [reverse.iter.op+=]

constexpr reverse_iterator& operator+=(difference_type n);
Effects: As if by: current -= n;
Returns: *this.

27.5.1.3.10 operator- [reverse.iter.op-]

constexpr reverse_iterator operator-(difference_type n) const;
Returns: reverse_­iterator(current+n).

27.5.1.3.11 operator-= [reverse.iter.op-=]

constexpr reverse_iterator& operator-=(difference_type n);
Effects: As if by: current += n;
Returns: *this.

27.5.1.3.12 operator[] [reverse.iter.opindex]

constexpr unspecified operator[](difference_type n) const;
Returns: current[-n-1].

27.5.1.3.13 operator== [reverse.iter.op==]

template <class Iterator1, class Iterator2> constexpr bool operator==( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Returns: x.current == y.current.

27.5.1.3.14 operator< [reverse.iter.op<]

template <class Iterator1, class Iterator2> constexpr bool operator<( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Returns: x.current > y.current.

27.5.1.3.15 operator!= [reverse.iter.op!=]

template <class Iterator1, class Iterator2> constexpr bool operator!=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Returns: x.current != y.current.

27.5.1.3.16 operator> [reverse.iter.op>]

template <class Iterator1, class Iterator2> constexpr bool operator>( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Returns: x.current < y.current.

27.5.1.3.17 operator>= [reverse.iter.op>=]

template <class Iterator1, class Iterator2> constexpr bool operator>=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Returns: x.current <= y.current.

27.5.1.3.18 operator<= [reverse.iter.op<=]

template <class Iterator1, class Iterator2> constexpr bool operator<=( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
Returns: x.current >= y.current.

27.5.1.3.19 operator- [reverse.iter.opdiff]

template <class Iterator1, class Iterator2> constexpr auto operator-( const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
Returns: y.current - x.current.

27.5.1.3.20 operator+ [reverse.iter.opsum]

template <class Iterator> constexpr reverse_iterator<Iterator> operator+( typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);
Returns: reverse_­iterator<Iterator> (x.current - n).

27.5.1.3.21 Non-member function make_­reverse_­iterator() [reverse.iter.make]

template <class Iterator> constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);
Returns: reverse_­iterator<Iterator>(i).

27.5.2 Insert iterators [insert.iterators]

To make it possible to deal with insertion in the same way as writing into an array, a special kind of iterator adaptors, called insert iterators, are provided in the library.
With regular iterator classes,
while (first != last) *result++ = *first++;
causes a range [first, last) to be copied into a range starting with result.
The same code with result being an insert iterator will insert corresponding elements into the container.
This device allows all of the copying algorithms in the library to work in the insert mode instead of the regular overwrite mode.
An insert iterator is constructed from a container and possibly one of its iterators pointing to where insertion takes place if it is neither at the beginning nor at the end of the container.
Insert iterators satisfy the requirements of output iterators.
operator* returns the insert iterator itself.
The assignment operator=(const T& x) is defined on insert iterators to allow writing into them, it inserts x right before where the insert iterator is pointing.
In other words, an insert iterator is like a cursor pointing into the container where the insertion takes place.
back_­insert_­iterator inserts elements at the end of a container, front_­insert_­iterator inserts elements at the beginning of a container, and insert_­iterator inserts elements where the iterator points to in a container.
back_­inserter, front_­inserter, and inserter are three functions making the insert iterators out of a container.

27.5.2.1 Class template back_­insert_­iterator [back.insert.iterator]

namespace std {
  template <class Container>
  class back_insert_iterator {
  protected:
    Container* container;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    explicit back_insert_iterator(Container& x);
    back_insert_iterator& operator=(const typename Container::value_type& value);
    back_insert_iterator& operator=(typename Container::value_type&& value);

    back_insert_iterator& operator*();
    back_insert_iterator& operator++();
    back_insert_iterator  operator++(int);
  };

  template <class Container>
    back_insert_iterator<Container> back_inserter(Container& x);
}

27.5.2.2 back_­insert_­iterator operations [back.insert.iter.ops]

27.5.2.2.1 back_­insert_­iterator constructor [back.insert.iter.cons]

explicit back_insert_iterator(Container& x);
Effects: Initializes container with addressof(x).

27.5.2.2.2 back_­insert_­iterator​::​operator= [back.insert.iter.op=]

back_insert_iterator& operator=(const typename Container::value_type& value);
Effects: As if by: container->push_­back(value);
Returns: *this.
back_insert_iterator& operator=(typename Container::value_type&& value);
Effects: As if by: container->push_­back(std​::​move(value));
Returns: *this.

27.5.2.2.3 back_­insert_­iterator​::​operator* [back.insert.iter.op*]

back_insert_iterator& operator*();
Returns: *this.

27.5.2.2.4 back_­insert_­iterator​::​operator++ [back.insert.iter.op++]

back_insert_iterator& operator++(); back_insert_iterator operator++(int);
Returns: *this.

27.5.2.2.5 back_­inserter [back.inserter]

template <class Container> back_insert_iterator<Container> back_inserter(Container& x);
Returns: back_­insert_­iterator<Container>(x).

27.5.2.3 Class template front_­insert_­iterator [front.insert.iterator]

namespace std {
  template <class Container>
  class front_insert_iterator {
  protected:
    Container* container;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    explicit front_insert_iterator(Container& x);
    front_insert_iterator& operator=(const typename Container::value_type& value);
    front_insert_iterator& operator=(typename Container::value_type&& value);

    front_insert_iterator& operator*();
    front_insert_iterator& operator++();
    front_insert_iterator  operator++(int);
  };

  template <class Container>
    front_insert_iterator<Container> front_inserter(Container& x);
}

27.5.2.4 front_­insert_­iterator operations [front.insert.iter.ops]

27.5.2.4.1 front_­insert_­iterator constructor [front.insert.iter.cons]

explicit front_insert_iterator(Container& x);
Effects: Initializes container with addressof(x).

27.5.2.4.2 front_­insert_­iterator​::​operator= [front.insert.iter.op=]

front_insert_iterator& operator=(const typename Container::value_type& value);
Effects: As if by: container->push_­front(value);
Returns: *this.
front_insert_iterator& operator=(typename Container::value_type&& value);
Effects: As if by: container->push_­front(std​::​move(value));
Returns: *this.

27.5.2.4.3 front_­insert_­iterator​::​operator* [front.insert.iter.op*]

front_insert_iterator& operator*();
Returns: *this.

27.5.2.4.4 front_­insert_­iterator​::​operator++ [front.insert.iter.op++]

front_insert_iterator& operator++(); front_insert_iterator operator++(int);
Returns: *this.

27.5.2.4.5 front_­inserter [front.inserter]

template <class Container> front_insert_iterator<Container> front_inserter(Container& x);
Returns: front_­insert_­iterator<Container>(x).

27.5.2.5 Class template insert_­iterator [insert.iterator]

namespace std {
  template <class Container>
  class insert_iterator {
  protected:
    Container* container;
    typename Container::iterator iter;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    insert_iterator(Container& x, typename Container::iterator i);
    insert_iterator& operator=(const typename Container::value_type& value);
    insert_iterator& operator=(typename Container::value_type&& value);

    insert_iterator& operator*();
    insert_iterator& operator++();
    insert_iterator& operator++(int);
  };

  template <class Container>
    insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
}

27.5.2.6 insert_­iterator operations [insert.iter.ops]

27.5.2.6.1 insert_­iterator constructor [insert.iter.cons]

insert_iterator(Container& x, typename Container::iterator i);
Effects: Initializes container with addressof(x) and iter with i.

27.5.2.6.2 insert_­iterator​::​operator= [insert.iter.op=]

insert_iterator& operator=(const typename Container::value_type& value);
Effects: As if by:
iter = container->insert(iter, value);
++iter;
Returns: *this.
insert_iterator& operator=(typename Container::value_type&& value);
Effects: As if by:
iter = container->insert(iter, std::move(value));
++iter;
Returns: *this.

27.5.2.6.3 insert_­iterator​::​operator* [insert.iter.op*]

insert_iterator& operator*();
Returns: *this.

27.5.2.6.4 insert_­iterator​::​operator++ [insert.iter.op++]

insert_iterator& operator++(); insert_iterator& operator++(int);
Returns: *this.

27.5.2.6.5 inserter [inserter]

template <class Container> insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
Returns: insert_­iterator<Container>(x, i).

27.5.3 Move iterators [move.iterators]

Class template move_­iterator is an iterator adaptor with the same behavior as the underlying iterator except that its indirection operator implicitly converts the value returned by the underlying iterator's indirection operator to an rvalue.
Some generic algorithms can be called with move iterators to replace copying with moving.
[Example
:
list<string> s;
// populate the list s
vector<string> v1(s.begin(), s.end());          // copies strings into v1
vector<string> v2(make_move_iterator(s.begin()),
                  make_move_iterator(s.end())); // moves strings into v2
end example
]

27.5.3.1 Class template move_­iterator [move.iterator]

namespace std {
  template <class Iterator>
  class move_iterator {
  public:
    using iterator_type     = Iterator;
    using iterator_category = typename iterator_traits<Iterator>::iterator_category;
    using value_type        = typename iterator_traits<Iterator>::value_type;
    using difference_type   = typename iterator_traits<Iterator>::difference_type;
    using pointer           = Iterator;
    using reference         = see below;

    constexpr move_iterator();
    constexpr explicit move_iterator(Iterator i);
    template <class U> constexpr move_iterator(const move_iterator<U>& u);
    template <class U> constexpr move_iterator& operator=(const move_iterator<U>& u);

    constexpr iterator_type base() const;
    constexpr reference operator*() const;
    constexpr pointer operator->() const;

    constexpr move_iterator& operator++();
    constexpr move_iterator operator++(int);
    constexpr move_iterator& operator--();
    constexpr move_iterator operator--(int);

    constexpr move_iterator operator+(difference_type n) const;
    constexpr move_iterator& operator+=(difference_type n);
    constexpr move_iterator operator-(difference_type n) const;
    constexpr move_iterator& operator-=(difference_type n);
    constexpr unspecified operator[](difference_type n) const;

  private:
    Iterator current;   // exposition only
  };

  template <class Iterator1, class Iterator2>
    constexpr bool operator==(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator!=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator<=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
  template <class Iterator1, class Iterator2>
    constexpr bool operator>=(
      const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

  template <class Iterator1, class Iterator2>
    constexpr auto operator-(
      const move_iterator<Iterator1>& x,
      const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
  template <class Iterator>
    constexpr move_iterator<Iterator> operator+(
      typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
  template <class Iterator>
    constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
}
Let R denote iterator_­traits<Iterator>​::​reference.
If is_­reference_­v<R> is true, the template specialization move_­iterator<Iterator> shall define the nested type named reference as a synonym for remove_­reference_­t<R>&&, otherwise as a synonym for R.

27.5.3.2 move_­iterator requirements [move.iter.requirements]

The template parameter Iterator shall meet the requirements of an input iterator ([input.iterators]).
Additionally, if any of the bidirectional or random access traversal functions are instantiated, the template parameter shall meet the requirements for a Bidirectional Iterator ([bidirectional.iterators]) or a Random Access Iterator ([random.access.iterators]), respectively.

27.5.3.3 move_­iterator operations [move.iter.ops]

27.5.3.3.1 move_­iterator constructors [move.iter.op.const]

constexpr move_iterator();
Effects: Constructs a move_­iterator, value-initializing current.
Iterator operations applied to the resulting iterator have defined behavior if and only if the corresponding operations are defined on a value-initialized iterator of type Iterator.
constexpr explicit move_iterator(Iterator i);
Effects: Constructs a move_­iterator, initializing current with i.
template <class U> constexpr move_iterator(const move_iterator<U>& u);
Effects: Constructs a move_­iterator, initializing current with u.base().
Requires: U shall be convertible to Iterator.

27.5.3.3.2 move_­iterator​::​operator= [move.iter.op=]

template <class U> constexpr move_iterator& operator=(const move_iterator<U>& u);
Effects: Assigns u.base() to current.
Requires: U shall be convertible to Iterator.

27.5.3.3.3 move_­iterator conversion [move.iter.op.conv]

constexpr Iterator base() const;
Returns: current.

27.5.3.3.4 move_­iterator​::​operator* [move.iter.op.star]

constexpr reference operator*() const;
Returns: static_­cast<reference>(*current).

27.5.3.3.5 move_­iterator​::​operator-> [move.iter.op.ref]

constexpr pointer operator->() const;
Returns: current.

27.5.3.3.6 move_­iterator​::​operator++ [move.iter.op.incr]

constexpr move_iterator& operator++();
Effects: As if by ++current.
Returns: *this.
constexpr move_iterator operator++(int);
Effects: As if by:
move_iterator tmp = *this;
++current;
return tmp;

27.5.3.3.7 move_­iterator​::​operator-- [move.iter.op.decr]

constexpr move_iterator& operator--();
Effects: As if by --current.
Returns: *this.
constexpr move_iterator operator--(int);
Effects: As if by:
move_iterator tmp = *this;
--current;
return tmp;

27.5.3.3.8 move_­iterator​::​operator+ [move.iter.op.+]

constexpr move_iterator operator+(difference_type n) const;
Returns: move_­iterator(current + n).

27.5.3.3.9 move_­iterator​::​operator+= [move.iter.op.+=]

constexpr move_iterator& operator+=(difference_type n);
Effects: As if by: current += n;
Returns: *this.

27.5.3.3.10 move_­iterator​::​operator- [move.iter.op.-]

constexpr move_iterator operator-(difference_type n) const;
Returns: move_­iterator(current - n).

27.5.3.3.11 move_­iterator​::​operator-= [move.iter.op.-=]

constexpr move_iterator& operator-=(difference_type n);
Effects: As if by: current -= n;
Returns: *this.

27.5.3.3.12 move_­iterator​::​operator[] [move.iter.op.index]

constexpr unspecified operator[](difference_type n) const;
Returns: std​::​move(current[n]).

27.5.3.3.13 move_­iterator comparisons [move.iter.op.comp]

template <class Iterator1, class Iterator2> constexpr bool operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Returns: x.base() == y.base().
template <class Iterator1, class Iterator2> constexpr bool operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Returns: !(x == y).
template <class Iterator1, class Iterator2> constexpr bool operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Returns: x.base() < y.base().
template <class Iterator1, class Iterator2> constexpr bool operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Returns: !(y < x).
template <class Iterator1, class Iterator2> constexpr bool operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Returns: y < x.
template <class Iterator1, class Iterator2> constexpr bool operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
Returns: !(x < y).

27.5.3.3.14 move_­iterator non-member functions [move.iter.nonmember]

template <class Iterator1, class Iterator2> constexpr auto operator-( const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
Returns: x.base() - y.base().
template <class Iterator> constexpr move_iterator<Iterator> operator+( typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
Returns: x + n.
template <class Iterator> constexpr move_iterator<Iterator> make_move_iterator(Iterator i);
Returns: move_­iterator<Iterator>(i).

27.6 Stream iterators [stream.iterators]

To make it possible for algorithmic templates to work directly with input/output streams, appropriate iterator-like class templates are provided.
[Example
:
partial_sum(istream_iterator<double, char>(cin),
  istream_iterator<double, char>(),
  ostream_iterator<double, char>(cout, "\n"));
reads a file containing floating-point numbers from cin, and prints the partial sums onto cout.
end example
]

27.6.1 Class template istream_­iterator [istream.iterator]

The class template istream_­iterator is an input iterator ([input.iterators]) that reads (using operator>>) successive elements from the input stream for which it was constructed.
After it is constructed, and every time ++ is used, the iterator reads and stores a value of T.
If the iterator fails to read and store a value of T (fail() on the stream returns true), the iterator becomes equal to the end-of-stream iterator value.
The constructor with no arguments istream_­iterator() always constructs an end-of-stream input iterator object, which is the only legitimate iterator to be used for the end condition.
The result of operator* on an end-of-stream iterator is not defined.
For any other iterator value a const T& is returned.
The result of operator-> on an end-of-stream iterator is not defined.
For any other iterator value a const T* is returned.
The behavior of a program that applies operator++() to an end-of-stream iterator is undefined.
It is impossible to store things into istream iterators.
The type T shall meet the DefaultConstructible, CopyConstructible, and CopyAssignable requirements.
Two end-of-stream iterators are always equal.
An end-of-stream iterator is not equal to a non-end-of-stream iterator.
Two non-end-of-stream iterators are equal when they are constructed from the same stream.
namespace std {
  template <class T, class charT = char, class traits = char_traits<charT>,
      class Distance = ptrdiff_t>
  class istream_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = const T*;
    using reference         = const T&;
    using char_type         = charT;
    using traits_type       = traits;
    using istream_type      = basic_istream<charT,traits>;

    constexpr istream_iterator();
    istream_iterator(istream_type& s);
    istream_iterator(const istream_iterator& x) = default;
    ~istream_iterator() = default;

    const T& operator*() const;
    const T* operator->() const;
    istream_iterator& operator++();
    istream_iterator  operator++(int);
  private:
    basic_istream<charT,traits>* in_stream; // exposition only
    T value;                                // exposition only
  };

  template <class T, class charT, class traits, class Distance>
    bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
            const istream_iterator<T,charT,traits,Distance>& y);
  template <class T, class charT, class traits, class Distance>
    bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
            const istream_iterator<T,charT,traits,Distance>& y);
}

27.6.1.1 istream_­iterator constructors and destructor [istream.iterator.cons]

constexpr istream_iterator();
Effects: Constructs the end-of-stream iterator.
If is_­trivially_­default_­constructible_­v<T> is true, then this constructor is a constexpr constructor.
Postconditions: in_­stream == 0.
istream_iterator(istream_type& s);
Effects: Initializes in_­stream with addressof(s).
value may be initialized during construction or the first time it is referenced.
Postconditions: in_­stream == addressof(s).
istream_iterator(const istream_iterator& x) = default;
Effects: Constructs a copy of x.
If is_­trivially_­copy_­constructible_­v<T> is true, then this constructor is a trivial copy constructor.
Postconditions: in_­stream == x.in_­stream.
~istream_iterator() = default;
Effects: The iterator is destroyed.
If is_­trivially_­destructible_­v<T> is true, then this destructor is a trivial destructor.

27.6.1.2 istream_­iterator operations [istream.iterator.ops]

const T& operator*() const;
Returns: value.
const T* operator->() const;
Returns: addressof(operator*()).
istream_iterator& operator++();
Requires: in_­stream != 0.
Effects: As if by: *in_­stream >> value;
Returns: *this.
istream_iterator operator++(int);
Requires: in_­stream != 0.
Effects: As if by:
istream_iterator tmp = *this;
*in_stream >> value;
return (tmp);
template <class T, class charT, class traits, class Distance> bool operator==(const istream_iterator<T,charT,traits,Distance>& x, const istream_iterator<T,charT,traits,Distance>& y);
Returns: x.in_­stream == y.in_­stream.
template <class T, class charT, class traits, class Distance> bool operator!=(const istream_iterator<T,charT,traits,Distance>& x, const istream_iterator<T,charT,traits,Distance>& y);
Returns: !(x == y)

27.6.2 Class template ostream_­iterator [ostream.iterator]

ostream_­iterator writes (using operator<<) successive elements onto the output stream from which it was constructed.
If it was constructed with charT* as a constructor argument, this string, called a delimiter string, is written to the stream after every T is written.
It is not possible to get a value out of the output iterator.
Its only use is as an output iterator in situations like
while (first != last)
  *result++ = *first++;
ostream_­iterator is defined as:
namespace std {
  template <class T, class charT = char, class traits = char_traits<charT>>
  class ostream_iterator {
  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using char_type         = charT;
    using traits_type       = traits;
    using ostream_type      = basic_ostream<charT,traits>;

    ostream_iterator(ostream_type& s);
    ostream_iterator(ostream_type& s, const charT* delimiter);
    ostream_iterator(const ostream_iterator& x);
    ~ostream_iterator();
    ostream_iterator& operator=(const T& value);

    ostream_iterator& operator*();
    ostream_iterator& operator++();
    ostream_iterator& operator++(int);
  private:
    basic_ostream<charT,traits>* out_stream;  // exposition only
    const charT* delim;                       // exposition only
  };
}

27.6.2.1 ostream_­iterator constructors and destructor [ostream.iterator.cons.des]

ostream_iterator(ostream_type& s);
Effects: Initializes out_­stream with addressof(s) and delim with null.
ostream_iterator(ostream_type& s, const charT* delimiter);
Effects: Initializes out_­stream with addressof(s) and delim with delimiter.
ostream_iterator(const ostream_iterator& x);
Effects: Constructs a copy of x.
~ostream_iterator();
Effects: The iterator is destroyed.

27.6.2.2 ostream_­iterator operations [ostream.iterator.ops]

ostream_iterator& operator=(const T& value);
Effects: As if by:
*out_stream << value;
if (delim != 0)
  *out_stream << delim;
return *this;
ostream_iterator& operator*();
Returns: *this.
ostream_iterator& operator++(); ostream_iterator& operator++(int);
Returns: *this.

27.6.3 Class template istreambuf_­iterator [istreambuf.iterator]

The class template istreambuf_­iterator defines an input iterator ([input.iterators]) that reads successive characters from the streambuf for which it was constructed.
operator* provides access to the current input character, if any.
Each time operator++ is evaluated, the iterator advances to the next input character.
If the end of stream is reached (streambuf_­type​::​sgetc() returns traits​::​eof()), the iterator becomes equal to the end-of-stream iterator value.
The default constructor istreambuf_­iterator() and the constructor istreambuf_­iterator(0) both construct an end-of-stream iterator object suitable for use as an end-of-range.
All specializations of istreambuf_­iterator shall have a trivial copy constructor, a constexpr default constructor, and a trivial destructor.
The result of operator*() on an end-of-stream iterator is undefined.
For any other iterator value a char_­type value is returned.
It is impossible to assign a character via an input iterator.
namespace std {
  template<class charT, class traits = char_traits<charT>>
  class istreambuf_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = charT;
    using difference_type   = typename traits::off_type;
    using pointer           = unspecified;
    using reference         = charT;
    using char_type         = charT;
    using traits_type       = traits;
    using int_type          = typename traits::int_type;
    using streambuf_type    = basic_streambuf<charT,traits>;
    using istream_type      = basic_istream<charT,traits>;

    class proxy;                          // exposition only

    constexpr istreambuf_iterator() noexcept;
    istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
    ~istreambuf_iterator() = default;
    istreambuf_iterator(istream_type& s) noexcept;
    istreambuf_iterator(streambuf_type* s) noexcept;
    istreambuf_iterator(const proxy& p) noexcept;
    charT operator*() const;
    istreambuf_iterator& operator++();
    proxy operator++(int);
    bool equal(const istreambuf_iterator& b) const;
  private:
    streambuf_type* sbuf_;                // exposition only
  };

  template <class charT, class traits>
    bool operator==(const istreambuf_iterator<charT,traits>& a,
            const istreambuf_iterator<charT,traits>& b);
  template <class charT, class traits>
    bool operator!=(const istreambuf_iterator<charT,traits>& a,
            const istreambuf_iterator<charT,traits>& b);
}

27.6.3.1 Class template istreambuf_­iterator​::​proxy [istreambuf.iterator.proxy]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class istreambuf_iterator<charT, traits>::proxy { // exposition only
    charT keep_;
    basic_streambuf<charT,traits>* sbuf_;
    proxy(charT c, basic_streambuf<charT,traits>* sbuf)
      : keep_(c), sbuf_(sbuf) { }
  public:
    charT operator*() { return keep_; }
  };
}
Class istreambuf_­iterator<charT,traits>​::​proxy is for exposition only.
An implementation is permitted to provide equivalent functionality without providing a class with this name.
Class istreambuf_­iterator<charT, traits>​::​proxy provides a temporary placeholder as the return value of the post-increment operator (operator++).
It keeps the character pointed to by the previous value of the iterator for some possible future access to get the character.

27.6.3.2 istreambuf_­iterator constructors [istreambuf.iterator.cons]

For each istreambuf_­iterator constructor in this section, an end-of-stream iterator is constructed if and only if the exposition-only member sbuf_­ is initialized with a null pointer value.
constexpr istreambuf_iterator() noexcept;
Effects: Initializes sbuf_­ with nullptr.
istreambuf_iterator(istream_type& s) noexcept;
Effects: Initializes sbuf_­ with s.rdbuf().
istreambuf_iterator(streambuf_type* s) noexcept;
Effects: Initializes sbuf_­ with s.
istreambuf_iterator(const proxy& p) noexcept;
Effects: Initializes sbuf_­ with p.sbuf_­.

27.6.3.3 istreambuf_­iterator operations [istreambuf.iterator.ops]

charT operator*() const
Returns: The character obtained via the streambuf member sbuf_­->sgetc().
istreambuf_iterator& operator++();
Effects: As if by sbuf_­->sbumpc().
Returns: *this.
proxy operator++(int);
Returns: proxy(sbuf_­->sbumpc(), sbuf_­).
bool equal(const istreambuf_iterator& b) const;
Returns: true if and only if both iterators are at end-of-stream, or neither is at end-of-stream, regardless of what streambuf object they use.
template <class charT, class traits> bool operator==(const istreambuf_iterator<charT,traits>& a, const istreambuf_iterator<charT,traits>& b);
Returns: a.equal(b).
template <class charT, class traits> bool operator!=(const istreambuf_iterator<charT,traits>& a, const istreambuf_iterator<charT,traits>& b);
Returns: !a.equal(b).

27.6.4 Class template ostreambuf_­iterator [ostreambuf.iterator]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class ostreambuf_iterator {
  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using char_type         = charT;
    using traits_type       = traits;
    using streambuf_type    = basic_streambuf<charT,traits>;
    using ostream_type      = basic_ostream<charT,traits>;

    ostreambuf_iterator(ostream_type& s) noexcept;
    ostreambuf_iterator(streambuf_type* s) noexcept;
    ostreambuf_iterator& operator=(charT c);

    ostreambuf_iterator& operator*();
    ostreambuf_iterator& operator++();
    ostreambuf_iterator& operator++(int);
    bool failed() const noexcept;

  private:
    streambuf_type* sbuf_;                // exposition only
  };
}
The class template ostreambuf_­iterator writes successive characters onto the output stream from which it was constructed.
It is not possible to get a character value out of the output iterator.

27.6.4.1 ostreambuf_­iterator constructors [ostreambuf.iter.cons]

ostreambuf_iterator(ostream_type& s) noexcept;
Requires: s.rdbuf() shall not be a null pointer.
Effects: Initializes sbuf_­ with s.rdbuf().
ostreambuf_iterator(streambuf_type* s) noexcept;
Requires: s shall not be a null pointer.
Effects: Initializes sbuf_­ with s.

27.6.4.2 ostreambuf_­iterator operations [ostreambuf.iter.ops]

ostreambuf_iterator& operator=(charT c);
Effects: If failed() yields false, calls sbuf_­->sputc(c); otherwise has no effect.
Returns: *this.
ostreambuf_iterator& operator*();
Returns: *this.
ostreambuf_iterator& operator++(); ostreambuf_iterator& operator++(int);
Returns: *this.
bool failed() const noexcept;
Returns: true if in any prior use of member operator=, the call to sbuf_­->sputc() returned traits​::​eof(); or false otherwise.

27.7 Range access [iterator.range]

In addition to being available via inclusion of the <iterator> header, the function templates in [iterator.range] are available when any of the following headers are included: <array>, <deque>, <forward_­list>, <list>, <map>, <regex>, <set>, <string>, <string_­view>, <unordered_­map>, <unordered_­set>, and <vector>.
template <class C> constexpr auto begin(C& c) -> decltype(c.begin()); template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());
Returns: c.begin().
template <class C> constexpr auto end(C& c) -> decltype(c.end()); template <class C> constexpr auto end(const C& c) -> decltype(c.end());
Returns: c.end().
template <class T, size_t N> constexpr T* begin(T (&array)[N]) noexcept;
Returns: array.
template <class T, size_t N> constexpr T* end(T (&array)[N]) noexcept;
Returns: array + N.
template <class C> constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c))) -> decltype(std::begin(c));
Returns: std​::​begin(c).
template <class C> constexpr auto cend(const C& c) noexcept(noexcept(std::end(c))) -> decltype(std::end(c));
Returns: std​::​end(c).
template <class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin()); template <class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());
Returns: c.rbegin().
template <class C> constexpr auto rend(C& c) -> decltype(c.rend()); template <class C> constexpr auto rend(const C& c) -> decltype(c.rend());
Returns: c.rend().
template <class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]);
Returns: reverse_­iterator<T*>(array + N).
template <class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]);
Returns: reverse_­iterator<T*>(array).
template <class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
Returns: reverse_­iterator<const E*>(il.end()).
template <class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);
Returns: reverse_­iterator<const E*>(il.begin()).
template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
Returns: std​::​rbegin(c).
template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));
Returns: std​::​rend(c).

27.8 Container access [iterator.container]

In addition to being available via inclusion of the <iterator> header, the function templates in [iterator.container] are available when any of the following headers are included: <array>, <deque>, <forward_­list>, <list>, <map>, <regex>, <set>, <string>, <unordered_­map>, <unordered_­set>, and <vector>.
template <class C> constexpr auto size(const C& c) -> decltype(c.size());
Returns: c.size().
template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept;
Returns: N.
template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());
Returns: c.empty().
template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;
Returns: false.
template <class E> constexpr bool empty(initializer_list<E> il) noexcept;
Returns: il.size() == 0.
template <class C> constexpr auto data(C& c) -> decltype(c.data()); template <class C> constexpr auto data(const C& c) -> decltype(c.data());
Returns: c.data().
template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;
Returns: array.
template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
Returns: il.begin().

28 Algorithms library [algorithms]

28.1 General [algorithms.general]

This Clause describes components that C++ programs may use to perform algorithmic operations on containers (Clause [containers]) and other sequences.
The following subclauses describe components for non-modifying sequence operations, modifying sequence operations, sorting and related operations, and algorithms from the ISO C library, as summarized in Table 95.
Table 95 — Algorithms library summary
Subclause
Header(s)
Non-modifying sequence operations
Mutating sequence operations
<algorithm>
Sorting and related operations
C library algorithms
<cstdlib>

28.2 Header <algorithm> synopsis [algorithm.syn]

#include <initializer_list>

namespace std {
  // [alg.nonmodifying], non-modifying sequence operations
  // [alg.all_of], all of
  template <class InputIterator, class Predicate>
    bool all_of(InputIterator first, InputIterator last, Predicate pred);
  template <class ExecutionPolicy, class ForwardIterator, class Predicate>
    bool all_of(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                ForwardIterator first, ForwardIterator last, Predicate pred);

  // [alg.any_of], any of
  template <class InputIterator, class Predicate>
    bool any_of(InputIterator first, InputIterator last, Predicate pred);
  template <class ExecutionPolicy, class ForwardIterator, class Predicate>
    bool any_of(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                ForwardIterator first, ForwardIterator last, Predicate pred);

  // [alg.none_of], none of
  template <class InputIterator, class Predicate>
    bool none_of(InputIterator first, InputIterator last, Predicate pred);
  template <class ExecutionPolicy, class ForwardIterator, class Predicate>
    bool none_of(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                 ForwardIterator first, ForwardIterator last, Predicate pred);

  // [alg.foreach], for each
  template<class InputIterator, class Function>
    Function for_each(InputIterator first, InputIterator last, Function f);
  template<class ExecutionPolicy, class ForwardIterator, class Function>
    void for_each(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                  ForwardIterator first, ForwardIterator last, Function f);
  template<class InputIterator, class Size, class Function>
    InputIterator for_each_n(InputIterator first, Size n, Function f);
  template<class ExecutionPolicy, class ForwardIterator, class Size, class Function>
    ForwardIterator for_each_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                               ForwardIterator first, Size n, Function f);

  // [alg.find], find
  template<class InputIterator, class T>
    InputIterator find(InputIterator first, InputIterator last,
                       const T& value);
  template<class ExecutionPolicy, class ForwardIterator, class T>
    ForwardIterator find(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                         ForwardIterator first, ForwardIterator last,
                         const T& value);
  template<class InputIterator, class Predicate>
    InputIterator find_if(InputIterator first, InputIterator last,
                          Predicate pred);
  template<class ExecutionPolicy, class ForwardIterator, class Predicate>
    ForwardIterator find_if(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                            ForwardIterator first, ForwardIterator last,
                            Predicate pred);
  template<class InputIterator, class Predicate>
    InputIterator find_if_not(InputIterator first, InputIterator last,
                              Predicate pred);
  template<class ExecutionPolicy, class ForwardIterator, class Predicate>
    ForwardIterator find_if_not(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                ForwardIterator first, ForwardIterator last,
                                Predicate pred);

  // [alg.find.end], find end
  template<class ForwardIterator1, class ForwardIterator2>
    ForwardIterator1
      find_end(ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
    ForwardIterator1
      find_end(ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2,
               BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator1
      find_end(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ExecutionPolicy, class ForwardIterator1,
           class ForwardIterator2, class BinaryPredicate>
    ForwardIterator1
      find_end(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2,
               BinaryPredicate pred);

  // [alg.find.first.of], find first
  template<class InputIterator, class ForwardIterator>
    InputIterator
      find_first_of(InputIterator first1, InputIterator last1,
                    ForwardIterator first2, ForwardIterator last2);
  template<class InputIterator, class ForwardIterator, class BinaryPredicate>
    InputIterator
      find_first_of(InputIterator first1, InputIterator last1,
                    ForwardIterator first2, ForwardIterator last2,
                    BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator1
      find_first_of(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                    ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ExecutionPolicy, class ForwardIterator1,
           class ForwardIterator2, class BinaryPredicate>
    ForwardIterator1
      find_first_of(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                    ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2, ForwardIterator2 last2,
                    BinaryPredicate pred);

  // [alg.adjacent.find], adjacent find
  template<class ForwardIterator>
    ForwardIterator adjacent_find(ForwardIterator first,
                                  ForwardIterator last);
  template<class ForwardIterator, class BinaryPredicate>
    ForwardIterator adjacent_find(ForwardIterator first,
                                  ForwardIterator last,
                                  BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator>
    ForwardIterator adjacent_find(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                  ForwardIterator first,
                                  ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class BinaryPredicate>
    ForwardIterator adjacent_find(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                  ForwardIterator first,
                                  ForwardIterator last,
                                  BinaryPredicate pred);

  // [alg.count], count
  template<class InputIterator, class T>
    typename iterator_traits<InputIterator>::difference_type
      count(InputIterator first, InputIterator last, const T& value);
  template<class ExecutionPolicy, class ForwardIterator, class T>
    typename iterator_traits<ForwardIterator>::difference_type
      count(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
            ForwardIterator first, ForwardIterator last, const T& value);
  template<class InputIterator, class Predicate>
    typename iterator_traits<InputIterator>::difference_type
      count_if(InputIterator first, InputIterator last, Predicate pred);
  template<class ExecutionPolicy, class ForwardIterator, class Predicate>
    typename iterator_traits<ForwardIterator>::difference_type
      count_if(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
            ForwardIterator first, ForwardIterator last, Predicate pred);

  // [mismatch], mismatch
  template<class InputIterator1, class InputIterator2>
    pair<InputIterator1, InputIterator2>
      mismatch(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2);
  template<class InputIterator1, class InputIterator2, class BinaryPredicate>
    pair<InputIterator1, InputIterator2>
      mismatch(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, BinaryPredicate pred);
  template<class InputIterator1, class InputIterator2>
    pair<InputIterator1, InputIterator2>
      mismatch(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, InputIterator2 last2);
  template<class InputIterator1, class InputIterator2, class BinaryPredicate>
    pair<InputIterator1, InputIterator2>
      mismatch(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, InputIterator2 last2,
               BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    pair<ForwardIterator1, ForwardIterator2>
      mismatch(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryPredicate>
    pair<ForwardIterator1, ForwardIterator2>
      mismatch(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    pair<ForwardIterator1, ForwardIterator2>
      mismatch(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryPredicate>
    pair<ForwardIterator1, ForwardIterator2>
      mismatch(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2,
               BinaryPredicate pred);

  // [alg.equal], equal
  template<class InputIterator1, class InputIterator2>
    bool equal(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2);
  template<class InputIterator1, class InputIterator2, class BinaryPredicate>
    bool equal(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, BinaryPredicate pred);
  template<class InputIterator1, class InputIterator2>
    bool equal(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, InputIterator2 last2);
  template<class InputIterator1, class InputIterator2, class BinaryPredicate>
    bool equal(InputIterator1 first1, InputIterator1 last1,
               InputIterator2 first2, InputIterator2 last2,
               BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    bool equal(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryPredicate>
    bool equal(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    bool equal(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryPredicate>
    bool equal(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
               ForwardIterator1 first1, ForwardIterator1 last1,
               ForwardIterator2 first2, ForwardIterator2 last2,
               BinaryPredicate pred);

  // [alg.is_permutation], is permutation
  template<class ForwardIterator1, class ForwardIterator2>
    bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2);
  template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
    bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, BinaryPredicate pred);

  template<class ForwardIterator1, class ForwardIterator2>
    bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, ForwardIterator2 last2);

  template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
    bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, ForwardIterator2 last2,
                        BinaryPredicate pred);

  // [alg.search], search
  template<class ForwardIterator1, class ForwardIterator2>
    ForwardIterator1 search(
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
    ForwardIterator1 search(
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator1 search(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryPredicate>
    ForwardIterator1 search(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      BinaryPredicate pred);
  template<class ForwardIterator, class Size, class T>
    ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                             Size count, const T& value);
  template<class ForwardIterator, class Size, class T, class BinaryPredicate>
    ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                             Size count, const T& value,
                             BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator, class Size, class T>
    ForwardIterator search_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                             ForwardIterator first, ForwardIterator last,
                             Size count, const T& value);
  template<class ExecutionPolicy, class ForwardIterator, class Size, class T,
           class BinaryPredicate>
    ForwardIterator search_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                             ForwardIterator first, ForwardIterator last,
                             Size count, const T& value,
                             BinaryPredicate pred);

  template <class ForwardIterator, class Searcher>
    ForwardIterator search(ForwardIterator first, ForwardIterator last,
                           const Searcher& searcher);

  // [alg.modifying.operations], modifying sequence operations
  // [alg.copy], copy
  template<class InputIterator, class OutputIterator>
    OutputIterator copy(InputIterator first, InputIterator last,
                        OutputIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                          ForwardIterator1 first, ForwardIterator1 last,
                          ForwardIterator2 result);
  template<class InputIterator, class Size, class OutputIterator>
    OutputIterator copy_n(InputIterator first, Size n,
                          OutputIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class Size,
           class ForwardIterator2>
    ForwardIterator2 copy_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                            ForwardIterator1 first, Size n,
                            ForwardIterator2 result);
  template<class InputIterator, class OutputIterator, class Predicate>
    OutputIterator copy_if(InputIterator first, InputIterator last,
                           OutputIterator result, Predicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class Predicate>
    ForwardIterator2 copy_if(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                             ForwardIterator1 first, ForwardIterator1 last,
                             ForwardIterator2 result, Predicate pred);
  template<class BidirectionalIterator1, class BidirectionalIterator2>
    BidirectionalIterator2 copy_backward(
      BidirectionalIterator1 first, BidirectionalIterator1 last,
      BidirectionalIterator2 result);

  // [alg.move], move
  template<class InputIterator, class OutputIterator>
    OutputIterator move(InputIterator first, InputIterator last,
                        OutputIterator result);
  template<class ExecutionPolicy, class ForwardIterator1,
           class ForwardIterator2>
    ForwardIterator2 move(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                          ForwardIterator1 first, ForwardIterator1 last,
                          ForwardIterator2 result);
  template<class BidirectionalIterator1, class BidirectionalIterator2>
    BidirectionalIterator2 move_backward(
      BidirectionalIterator1 first, BidirectionalIterator1 last,
      BidirectionalIterator2 result);

  // [alg.swap], swap
  template<class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
                                 ForwardIterator2 first2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                 ForwardIterator1 first1, ForwardIterator1 last1,
                                 ForwardIterator2 first2);
  template<class ForwardIterator1, class ForwardIterator2>
    void iter_swap(ForwardIterator1 a, ForwardIterator2 b);

  // [alg.transform], transform
  template<class InputIterator, class OutputIterator, class UnaryOperation>
    OutputIterator transform(InputIterator first, InputIterator last,
                             OutputIterator result, UnaryOperation op);
  template<class InputIterator1, class InputIterator2, class OutputIterator,
           class BinaryOperation>
    OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, OutputIterator result,
                             BinaryOperation binary_op);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class UnaryOperation>
    ForwardIterator2 transform(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                               ForwardIterator1 first, ForwardIterator1 last,
                               ForwardIterator2 result, UnaryOperation op);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator, class BinaryOperation>
    ForwardIterator transform(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                              ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2, ForwardIterator result,
                              BinaryOperation binary_op);

  // [alg.replace], replace
  template<class ForwardIterator, class T>
    void replace(ForwardIterator first, ForwardIterator last,
                 const T& old_value, const T& new_value);
  template<class ExecutionPolicy, class ForwardIterator, class T>
    void replace(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                 ForwardIterator first, ForwardIterator last,
                 const T& old_value, const T& new_value);
  template<class ForwardIterator, class Predicate, class T>
    void replace_if(ForwardIterator first, ForwardIterator last,
                    Predicate pred, const T& new_value);
  template<class ExecutionPolicy, class ForwardIterator, class Predicate, class T>
    void replace_if(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                    ForwardIterator first, ForwardIterator last,
                    Predicate pred, const T& new_value);
  template<class InputIterator, class OutputIterator, class T>
    OutputIterator replace_copy(InputIterator first, InputIterator last,
                                OutputIterator result,
                                const T& old_value, const T& new_value);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T>
    ForwardIterator2 replace_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                  ForwardIterator1 first, ForwardIterator1 last,
                                  ForwardIterator2 result,
                                  const T& old_value, const T& new_value);
  template<class InputIterator, class OutputIterator, class Predicate, class T>
    OutputIterator replace_copy_if(InputIterator first, InputIterator last,
                                   OutputIterator result,
                                   Predicate pred, const T& new_value);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class Predicate, class T>
    ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                     ForwardIterator1 first, ForwardIterator1 last,
                                     ForwardIterator2 result,
                                     Predicate pred, const T& new_value);

  // [alg.fill], fill
  template<class ForwardIterator, class T>
    void fill(ForwardIterator first, ForwardIterator last, const T& value);
  template<class ExecutionPolicy, class ForwardIterator,
           class T>
    void fill(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
              ForwardIterator first, ForwardIterator last, const T& value);
  template<class OutputIterator, class Size, class T>
    OutputIterator fill_n(OutputIterator first, Size n, const T& value);
  template<class ExecutionPolicy, class ForwardIterator,
           class Size, class T>
    ForwardIterator fill_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                          ForwardIterator first, Size n, const T& value);

  // [alg.generate], generate
  template<class ForwardIterator, class Generator>
    void generate(ForwardIterator first, ForwardIterator last,
                  Generator gen);
  template<class ExecutionPolicy, class ForwardIterator, class Generator>
    void generate(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                  ForwardIterator first, ForwardIterator last,
                  Generator gen);
  template<class OutputIterator, class Size, class Generator>
    OutputIterator generate_n(OutputIterator first, Size n, Generator gen);
  template<class ExecutionPolicy, class ForwardIterator, class Size, class Generator>
    ForwardIterator generate_n(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                               ForwardIterator first, Size n, Generator gen);

  // [alg.remove], remove
  template<class ForwardIterator, class T>
    ForwardIterator remove(ForwardIterator first, ForwardIterator last,
                           const T& value);
  template<class ExecutionPolicy, class ForwardIterator, class T>
    ForwardIterator remove(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                           ForwardIterator first, ForwardIterator last,
                           const T& value);
  template<class ForwardIterator, class Predicate>
    ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
                              Predicate pred);
  template<class ExecutionPolicy, class ForwardIterator, class Predicate>
    ForwardIterator remove_if(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                              ForwardIterator first, ForwardIterator last,
                              Predicate pred);
  template<class InputIterator, class OutputIterator, class T>
    OutputIterator remove_copy(InputIterator first, InputIterator last,
                               OutputIterator result, const T& value);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class T>
    ForwardIterator2 remove_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                 ForwardIterator1 first, ForwardIterator1 last,
                                 ForwardIterator2 result, const T& value);
  template<class InputIterator, class OutputIterator, class Predicate>
    OutputIterator remove_copy_if(InputIterator first, InputIterator last,
                                  OutputIterator result, Predicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class Predicate>
    ForwardIterator2 remove_copy_if(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator1 first, ForwardIterator1 last,
                                    ForwardIterator2 result, Predicate pred);

  // [alg.unique], unique
  template<class ForwardIterator>
    ForwardIterator unique(ForwardIterator first, ForwardIterator last);
  template<class ForwardIterator, class BinaryPredicate>
    ForwardIterator unique(ForwardIterator first, ForwardIterator last,
                           BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator>
    ForwardIterator unique(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                           ForwardIterator first, ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class BinaryPredicate>
    ForwardIterator unique(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                           ForwardIterator first, ForwardIterator last,
                           BinaryPredicate pred);
  template<class InputIterator, class OutputIterator>
    OutputIterator unique_copy(InputIterator first, InputIterator last,
                               OutputIterator result);
  template<class InputIterator, class OutputIterator, class BinaryPredicate>
    OutputIterator unique_copy(InputIterator first, InputIterator last,
                               OutputIterator result, BinaryPredicate pred);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 unique_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                 ForwardIterator1 first, ForwardIterator1 last,
                                 ForwardIterator2 result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryPredicate>
    ForwardIterator2 unique_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                 ForwardIterator1 first, ForwardIterator1 last,
                                 ForwardIterator2 result, BinaryPredicate pred);

  // [alg.reverse], reverse
  template<class BidirectionalIterator>
    void reverse(BidirectionalIterator first, BidirectionalIterator last);
  template<class ExecutionPolicy, class BidirectionalIterator>
    void reverse(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                 BidirectionalIterator first, BidirectionalIterator last);
  template<class BidirectionalIterator, class OutputIterator>
    OutputIterator reverse_copy(BidirectionalIterator first,
                                BidirectionalIterator last,
                                OutputIterator result);
  template<class ExecutionPolicy, class BidirectionalIterator, class ForwardIterator>
    ForwardIterator reverse_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                 BidirectionalIterator first,
                                 BidirectionalIterator last,
                                 ForwardIterator result);

  // [alg.rotate], rotate
  template<class ForwardIterator>
    ForwardIterator rotate(ForwardIterator first,
                           ForwardIterator middle,
                           ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator>
    ForwardIterator rotate(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                           ForwardIterator first,
                           ForwardIterator middle,
                           ForwardIterator last);
  template<class ForwardIterator, class OutputIterator>
    OutputIterator rotate_copy(
      ForwardIterator first, ForwardIterator middle,
      ForwardIterator last, OutputIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 rotate_copy(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first, ForwardIterator1 middle,
      ForwardIterator1 last, ForwardIterator2 result);

  // [alg.random.sample], sample
  template<class PopulationIterator, class SampleIterator,
           class Distance, class UniformRandomBitGenerator>
    SampleIterator sample(PopulationIterator first, PopulationIterator last,
                          SampleIterator out, Distance n,
                          UniformRandomBitGenerator&& g);

  // [alg.random.shuffle], shuffle
  template<class RandomAccessIterator, class UniformRandomBitGenerator>
    void shuffle(RandomAccessIterator first,
                 RandomAccessIterator last,
                 UniformRandomBitGenerator&& g);

  // [alg.partitions], partitions
  template <class InputIterator, class Predicate>
    bool is_partitioned(InputIterator first, InputIterator last, Predicate pred);
  template <class ExecutionPolicy, class ForwardIterator, class Predicate>
    bool is_partitioned(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                        ForwardIterator first, ForwardIterator last, Predicate pred);

  template<class ForwardIterator, class Predicate>
    ForwardIterator partition(ForwardIterator first,
                              ForwardIterator last,
                              Predicate pred);
  template<class ExecutionPolicy, class ForwardIterator, class Predicate>
    ForwardIterator partition(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                              ForwardIterator first,
                              ForwardIterator last,
                              Predicate pred);
  template<class BidirectionalIterator, class Predicate>
    BidirectionalIterator stable_partition(BidirectionalIterator first,
                                           BidirectionalIterator last,
                                           Predicate pred);
  template<class ExecutionPolicy, class BidirectionalIterator, class Predicate>
    BidirectionalIterator stable_partition(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                           BidirectionalIterator first,
                                           BidirectionalIterator last,
                                           Predicate pred);
  template <class InputIterator, class OutputIterator1,
            class OutputIterator2, class Predicate>
    pair<OutputIterator1, OutputIterator2>
      partition_copy(InputIterator first, InputIterator last,
                     OutputIterator1 out_true, OutputIterator2 out_false,
                     Predicate pred);
  template <class ExecutionPolicy, class ForwardIterator, class ForwardIterator1,
            class ForwardIterator2, class Predicate>
    pair<ForwardIterator1, ForwardIterator2>
      partition_copy(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                     ForwardIterator first, ForwardIterator last,
                     ForwardIterator1 out_true, ForwardIterator2 out_false,
                     Predicate pred);
  template<class ForwardIterator, class Predicate>
    ForwardIterator partition_point(ForwardIterator first,
                                    ForwardIterator last,
                                    Predicate pred);

  // [alg.sorting], sorting and related operations
  // [alg.sort], sorting
  template<class RandomAccessIterator>
    void sort(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void sort(RandomAccessIterator first, RandomAccessIterator last,
              Compare comp);
  template<class ExecutionPolicy, class RandomAccessIterator>
    void sort(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
              RandomAccessIterator first, RandomAccessIterator last);
  template<class ExecutionPolicy, class RandomAccessIterator, class Compare>
    void sort(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
              RandomAccessIterator first, RandomAccessIterator last,
              Compare comp);

  template<class RandomAccessIterator>
    void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void stable_sort(RandomAccessIterator first, RandomAccessIterator last,
                     Compare comp);
  template<class ExecutionPolicy, class RandomAccessIterator>
    void stable_sort(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                     RandomAccessIterator first, RandomAccessIterator last);
  template<class ExecutionPolicy, class RandomAccessIterator, class Compare>
    void stable_sort(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                     RandomAccessIterator first, RandomAccessIterator last,
                     Compare comp);

  template<class RandomAccessIterator>
    void partial_sort(RandomAccessIterator first,
                      RandomAccessIterator middle,
                      RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void partial_sort(RandomAccessIterator first,
                      RandomAccessIterator middle,
                      RandomAccessIterator last, Compare comp);
  template<class ExecutionPolicy, class RandomAccessIterator>
    void partial_sort(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                      RandomAccessIterator first,
                      RandomAccessIterator middle,
                      RandomAccessIterator last);
  template<class ExecutionPolicy, class RandomAccessIterator, class Compare>
    void partial_sort(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                      RandomAccessIterator first,
                      RandomAccessIterator middle,
                      RandomAccessIterator last, Compare comp);
  template<class InputIterator, class RandomAccessIterator>
    RandomAccessIterator partial_sort_copy(
      InputIterator first, InputIterator last,
      RandomAccessIterator result_first,
      RandomAccessIterator result_last);
  template<class InputIterator, class RandomAccessIterator, class Compare>
    RandomAccessIterator partial_sort_copy(
      InputIterator first, InputIterator last,
      RandomAccessIterator result_first,
      RandomAccessIterator result_last,
      Compare comp);
  template<class ExecutionPolicy, class ForwardIterator, class RandomAccessIterator>
    RandomAccessIterator partial_sort_copy(
      ExecutionPolicy&& exec,  // see [algorithms.parallel.overloads]
      ForwardIterator first, ForwardIterator last,
      RandomAccessIterator result_first,
      RandomAccessIterator result_last);
  template<class ExecutionPolicy, class ForwardIterator, class RandomAccessIterator,
           class Compare>
    RandomAccessIterator partial_sort_copy(
      ExecutionPolicy&& exec,  // see [algorithms.parallel.overloads]
      ForwardIterator first, ForwardIterator last,
      RandomAccessIterator result_first,
      RandomAccessIterator result_last,
      Compare comp);
  template<class ForwardIterator>
    bool is_sorted(ForwardIterator first, ForwardIterator last);
  template<class ForwardIterator, class Compare>
    bool is_sorted(ForwardIterator first, ForwardIterator last,
                   Compare comp);
  template<class ExecutionPolicy, class ForwardIterator>
    bool is_sorted(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                   ForwardIterator first, ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class Compare>
    bool is_sorted(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                   ForwardIterator first, ForwardIterator last,
                   Compare comp);
  template<class ForwardIterator>
    ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last);
  template<class ForwardIterator, class Compare>
    ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last,
                                    Compare comp);
  template<class ExecutionPolicy, class ForwardIterator>
    ForwardIterator is_sorted_until(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator first, ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class Compare>
    ForwardIterator is_sorted_until(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator first, ForwardIterator last,
                                    Compare comp);

  // [alg.nth.element], Nth element
  template<class RandomAccessIterator>
    void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                     RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                     RandomAccessIterator last, Compare comp);
  template<class ExecutionPolicy, class RandomAccessIterator>
    void nth_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                     RandomAccessIterator first, RandomAccessIterator nth,
                     RandomAccessIterator last);
  template<class ExecutionPolicy, class RandomAccessIterator, class Compare>
    void nth_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                     RandomAccessIterator first, RandomAccessIterator nth,
                     RandomAccessIterator last, Compare comp);

  // [alg.binary.search], binary search
  template<class ForwardIterator, class T>
    ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
                                const T& value);
  template<class ForwardIterator, class T, class Compare>
    ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
                                const T& value, Compare comp);

  template<class ForwardIterator, class T>
    ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
                                const T& value);
  template<class ForwardIterator, class T, class Compare>
    ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
                                const T& value, Compare comp);

  template<class ForwardIterator, class T>
    pair<ForwardIterator, ForwardIterator>
      equal_range(ForwardIterator first, ForwardIterator last,
                  const T& value);
  template<class ForwardIterator, class T, class Compare>
    pair<ForwardIterator, ForwardIterator>
      equal_range(ForwardIterator first, ForwardIterator last,
                  const T& value, Compare comp);

  template<class ForwardIterator, class T>
    bool binary_search(ForwardIterator first, ForwardIterator last,
                       const T& value);
  template<class ForwardIterator, class T, class Compare>
    bool binary_search(ForwardIterator first, ForwardIterator last,
                       const T& value, Compare comp);

  // [alg.merge], merge
  template<class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result);
  template<class InputIterator1, class InputIterator2, class OutputIterator,
           class Compare>
    OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result, Compare comp);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator>
    ForwardIterator merge(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                         ForwardIterator1 first1, ForwardIterator1 last1,
                         ForwardIterator2 first2, ForwardIterator2 last2,
                         ForwardIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator, class Compare>
    ForwardIterator merge(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                         ForwardIterator1 first1, ForwardIterator1 last1,
                         ForwardIterator2 first2, ForwardIterator2 last2,
                         ForwardIterator result, Compare comp);

  template<class BidirectionalIterator>
    void inplace_merge(BidirectionalIterator first,
                       BidirectionalIterator middle,
                       BidirectionalIterator last);
  template<class BidirectionalIterator, class Compare>
    void inplace_merge(BidirectionalIterator first,
                       BidirectionalIterator middle,
                       BidirectionalIterator last, Compare comp);
  template<class ExecutionPolicy, class BidirectionalIterator>
    void inplace_merge(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                       BidirectionalIterator first,
                       BidirectionalIterator middle,
                       BidirectionalIterator last);
  template<class ExecutionPolicy, class BidirectionalIterator, class Compare>
    void inplace_merge(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                       BidirectionalIterator first,
                       BidirectionalIterator middle,
                       BidirectionalIterator last, Compare comp);

  // [alg.set.operations], set operations
  template<class InputIterator1, class InputIterator2>
    bool includes(InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, InputIterator2 last2);
  template<class InputIterator1, class InputIterator2, class Compare>
    bool includes(InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, InputIterator2 last2, Compare comp);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    bool includes(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                  ForwardIterator1 first1, ForwardIterator1 last1,
                  ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class Compare>
    bool includes(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                  ForwardIterator1 first1, ForwardIterator1 last1,
                  ForwardIterator2 first2, ForwardIterator2 last2, Compare comp);

  template<class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             OutputIterator result);
  template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
    OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             OutputIterator result, Compare comp);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator>
    ForwardIterator set_union(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                             ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2, ForwardIterator2 last2,
                             ForwardIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator, class Compare>
    ForwardIterator set_union(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                             ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2, ForwardIterator2 last2,
                             ForwardIterator result, Compare comp);

  template<class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_intersection(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2,
      OutputIterator result);
  template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
    OutputIterator set_intersection(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2,
      OutputIterator result, Compare comp);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator>
    ForwardIterator set_intersection(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      ForwardIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator, class Compare>
    ForwardIterator set_intersection(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      ForwardIterator result, Compare comp);

  template<class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_difference(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2,
      OutputIterator result);
  template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
    OutputIterator set_difference(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2,
      OutputIterator result, Compare comp);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator>
    ForwardIterator set_difference(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      ForwardIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator, class Compare>
    ForwardIterator set_difference(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      ForwardIterator result, Compare comp);

  template<class InputIterator1, class InputIterator2, class OutputIterator>
    OutputIterator set_symmetric_difference(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2,
      OutputIterator result);
  template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
    OutputIterator set_symmetric_difference(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2,
      OutputIterator result, Compare comp);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator>
    ForwardIterator set_symmetric_difference(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      ForwardIterator result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class ForwardIterator, class Compare>
    ForwardIterator set_symmetric_difference(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      ForwardIterator result, Compare comp);

  // [alg.heap.operations], heap operations
  template<class RandomAccessIterator>
    void push_heap(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void push_heap(RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp);

  template<class RandomAccessIterator>
    void pop_heap(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
                  Compare comp);

  template<class RandomAccessIterator>
    void make_heap(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void make_heap(RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp);

  template<class RandomAccessIterator>
    void sort_heap(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
                   Compare comp);

  template<class RandomAccessIterator>
    bool is_heap(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
  template<class ExecutionPolicy, class RandomAccessIterator>
    bool is_heap(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                 RandomAccessIterator first, RandomAccessIterator last);
  template<class ExecutionPolicy, class RandomAccessIterator, class Compare>
    bool is_heap(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                 RandomAccessIterator first, RandomAccessIterator last, Compare comp);
  template<class RandomAccessIterator>
    RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last);
  template<class RandomAccessIterator, class Compare>
    RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last,
                                       Compare comp);
  template<class ExecutionPolicy, class RandomAccessIterator>
    RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       RandomAccessIterator first, RandomAccessIterator last);
  template<class ExecutionPolicy, class RandomAccessIterator, class Compare>
    RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                       RandomAccessIterator first, RandomAccessIterator last,
                                       Compare comp);

  // [alg.min.max], minimum and maximum
  template<class T> constexpr const T& min(const T& a, const T& b);
  template<class T, class Compare>
    constexpr const T& min(const T& a, const T& b, Compare comp);
  template<class T>
    constexpr T min(initializer_list<T> t);
  template<class T, class Compare>
    constexpr T min(initializer_list<T> t, Compare comp);

  template<class T> constexpr const T& max(const T& a, const T& b);
  template<class T, class Compare>
    constexpr const T& max(const T& a, const T& b, Compare comp);
  template<class T>
    constexpr T max(initializer_list<T> t);
  template<class T, class Compare>
    constexpr T max(initializer_list<T> t, Compare comp);

  template<class T> constexpr pair<const T&, const T&> minmax(const T& a, const T& b);
  template<class T, class Compare>
    constexpr pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp);
  template<class T>
    constexpr pair<T, T> minmax(initializer_list<T> t);
  template<class T, class Compare>
    constexpr pair<T, T> minmax(initializer_list<T> t, Compare comp);

  template<class ForwardIterator>
    constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last);
  template<class ForwardIterator, class Compare>
    constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
                                          Compare comp);
  template<class ExecutionPolicy, class ForwardIterator>
    ForwardIterator min_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                ForwardIterator first, ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class Compare>
    ForwardIterator min_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                ForwardIterator first, ForwardIterator last,
                                Compare comp);
  template<class ForwardIterator>
    constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last);
  template<class ForwardIterator, class Compare>
    constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
                                          Compare comp);
  template<class ExecutionPolicy, class ForwardIterator>
    ForwardIterator max_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                ForwardIterator first, ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class Compare>
    ForwardIterator max_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                ForwardIterator first, ForwardIterator last,
                                Compare comp);
  template<class ForwardIterator>
    constexpr pair<ForwardIterator, ForwardIterator>
      minmax_element(ForwardIterator first, ForwardIterator last);
  template<class ForwardIterator, class Compare>
    constexpr pair<ForwardIterator, ForwardIterator>
      minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);
  template<class ExecutionPolicy, class ForwardIterator>
    pair<ForwardIterator, ForwardIterator>
      minmax_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                     ForwardIterator first, ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class Compare>
    pair<ForwardIterator, ForwardIterator>
      minmax_element(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                     ForwardIterator first, ForwardIterator last, Compare comp);

  // [alg.clamp], bounded value
  template<class T>
    constexpr const T& clamp(const T& v, const T& lo, const T& hi);
  template<class T, class Compare>
    constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp);

  // [alg.lex.comparison], lexicographical comparison
  template<class InputIterator1, class InputIterator2>
    bool lexicographical_compare(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2);
  template<class InputIterator1, class InputIterator2, class Compare>
    bool lexicographical_compare(
      InputIterator1 first1, InputIterator1 last1,
      InputIterator2 first2, InputIterator2 last2,
      Compare comp);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    bool lexicographical_compare(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class Compare>
    bool lexicographical_compare(
      ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
      ForwardIterator1 first1, ForwardIterator1 last1,
      ForwardIterator2 first2, ForwardIterator2 last2,
      Compare comp);

  // [alg.permutation.generators], permutations
  template<class BidirectionalIterator>
    bool next_permutation(BidirectionalIterator first,
                          BidirectionalIterator last);
  template<class BidirectionalIterator, class Compare>
    bool next_permutation(BidirectionalIterator first,
                          BidirectionalIterator last, Compare comp);
  template<class BidirectionalIterator>
    bool prev_permutation(BidirectionalIterator first,
                          BidirectionalIterator last);
  template<class BidirectionalIterator, class Compare>
    bool prev_permutation(BidirectionalIterator first,
                          BidirectionalIterator last, Compare comp);
}

28.3 Algorithms requirements [algorithms.requirements]

All of the algorithms are separated from the particular implementations of data structures and are parameterized by iterator types.
Because of this, they can work with program-defined data structures, as long as these data structures have iterator types satisfying the assumptions on the algorithms.
For purposes of determining the existence of data races, algorithms shall not modify objects referenced through an iterator argument unless the specification requires such modification.
Throughout this Clause, the names of template parameters are used to express type requirements.
  • If an algorithm's template parameter is named InputIterator, InputIterator1, or InputIterator2, the template argument shall satisfy the requirements of an input iterator ([input.iterators]).
  • If an algorithm's template parameter is named OutputIterator, OutputIterator1, or OutputIterator2, the template argument shall satisfy the requirements of an output iterator ([output.iterators]).
  • If an algorithm's template parameter is named ForwardIterator, ForwardIterator1, or ForwardIterator2, the template argument shall satisfy the requirements of a forward iterator ([forward.iterators]).
  • If an algorithm's template parameter is named BidirectionalIterator, BidirectionalIterator1, or BidirectionalIterator2, the template argument shall satisfy the requirements of a bidirectional iterator ([bidirectional.iterators]).
  • If an algorithm's template parameter is named RandomAccessIterator, RandomAccessIterator1, or RandomAccessIterator2, the template argument shall satisfy the requirements of a random-access iterator ([random.access.iterators]).
If an algorithm's Effects: section says that a value pointed to by any iterator passed as an argument is modified, then that algorithm has an additional type requirement: The type of that argument shall satisfy the requirements of a mutable iterator ([iterator.requirements]).
[Note
:
This requirement does not affect arguments that are named OutputIterator, OutputIterator1, or OutputIterator2, because output iterators must always be mutable.
end note
]
Both in-place and copying versions are provided for certain algorithms.262
When such a version is provided for algorithm it is called algorithm_­copy.
Algorithms that take predicates end with the suffix _­if (which follows the suffix _­copy).
The Predicate parameter is used whenever an algorithm expects a function object ([function.objects]) that, when applied to the result of dereferencing the corresponding iterator, returns a value testable as true.
In other words, if an algorithm takes Predicate pred as its argument and first as its iterator argument, it should work correctly in the construct pred(*first) contextually converted to bool (Clause [conv]).
The function object pred shall not apply any non-constant function through the dereferenced iterator.
The BinaryPredicate parameter is used whenever an algorithm expects a function object that when applied to the result of dereferencing two corresponding iterators or to dereferencing an iterator and type T when T is part of the signature returns a value testable as true.
In other words, if an algorithm takes BinaryPredicate binary_­pred as its argument and first1 and first2 as its iterator arguments, it should work correctly in the construct binary_­pred(*first1, *first2) contextually converted to bool (Clause [conv]).
BinaryPredicate always takes the first iterator's value_­type as its first argument, that is, in those cases when T value is part of the signature, it should work correctly in the construct binary_­pred(*first1, value) contextually converted to bool (Clause [conv]).
binary_­pred shall not apply any non-constant function through the dereferenced iterators.
[Note
:
Unless otherwise specified, algorithms that take function objects as arguments are permitted to copy those function objects freely.
Programmers for whom object identity is important should consider using a wrapper class that points to a noncopied implementation object such as reference_­wrapper<T> ([refwrap]), or some equivalent solution.
end note
]
When the description of an algorithm gives an expression such as *first == value for a condition, the expression shall evaluate to either true or false in boolean contexts.
In the description of the algorithms operators + and - are used for some of the iterator categories for which they do not have to be defined.
In these cases the semantics of a+n is the same as that of
X tmp = a;
advance(tmp, n);
return tmp;
and that of b-a is the same as of
return distance(a, b);
The decision whether to include a copying version was usually based on complexity considerations.
When the cost of doing the operation dominates the cost of copy, the copying version is not included.
For example, sort_­copy is not included because the cost of sorting is much more significant, and users might as well do copy followed by sort.

28.4 Parallel algorithms [algorithms.parallel]

This section describes components that C++ programs may use to perform operations on containers and other sequences in parallel.

28.4.1 Terms and definitions [algorithms.parallel.defns]

A parallel algorithm is a function template listed in this International Standard with a template parameter named ExecutionPolicy.
Parallel algorithms access objects indirectly accessible via their arguments by invoking the following functions:
  • All operations of the categories of the iterators that the algorithm is instantiated with.
  • Operations on those sequence elements that are required by its specification.
  • User-provided function objects to be applied during the execution of the algorithm, if required by the specification.
  • Operations on those function objects required by the specification.
    [Note
    : end note
    ]
These functions are herein called element access functions.
[Example
:
The sort function may invoke the following element access functions:
  • Operations of the random-access iterator of the actual template argument (as per [random.access.iterators]), as implied by the name of the template parameter RandomAccessIterator.
  • The swap function on the elements of the sequence (as per the preconditions specified in [sort]).
  • The user-provided Compare function object.
end example
]

28.4.2 Requirements on user-provided function objects [algorithms.parallel.user]

Unless otherwise specified, function objects passed into parallel algorithms as objects of type Predicate, BinaryPredicate, Compare, UnaryOperation, BinaryOperation, BinaryOperation1, BinaryOperation2, and the operators used by the analogous overloads to these parallel algorithms that could be formed by the invocation with the specified default predicate or operation (where applicable) shall not directly or indirectly modify objects via their arguments, nor shall they rely on the identity of the provided objects.

28.4.3 Effect of execution policies on algorithm execution [algorithms.parallel.exec]

Parallel algorithms have template parameters named ExecutionPolicy ([execpol]) which describe the manner in which the execution of these algorithms may be parallelized and the manner in which they apply the element access functions.
Unless otherwise stated, implementations may make arbitrary copies of elements (with type T) from sequences where is_­trivially_­copy_­constructible_­v<T> and is_­trivially_­destructible_­v<T> are true.
[Note
:
This implies that user-supplied function objects should not rely on object identity of arguments for such input sequences.
Users for whom the object identity of the arguments to these function objects is important should consider using a wrapping iterator that returns a non-copied implementation object such as reference_­wrapper<T> ([refwrap]) or some equivalent solution.
end note
]
The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution​::​sequenced_­policy all occur in the calling thread of execution.
[Note
:
The invocations are not interleaved; see [intro.execution].
end note
]
The invocations of element access functions in parallel algorithms invoked with an execution policy object of type execution​::​parallel_­policy are permitted to execute in either the invoking thread of execution or in a thread of execution implicitly created by the library to support parallel algorithm execution.
If the threads of execution created by thread ([thread.thread.class]) provide concurrent forward progress guarantees ([intro.progress]), then a thread of execution implicitly created by the library will provide parallel forward progress guarantees; otherwise, the provided forward progress guarantee is implementation-defined.
Any such invocations executing in the same thread of execution are indeterminately sequenced with respect to each other.
[Note
:
It is the caller's responsibility to ensure that the invocation does not introduce data races or deadlocks.
end note
]
[Example
:
int a[] = {0,1};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
  v.push_back(i*2+1); // incorrect: data race
});
The program above has a data race because of the unsynchronized access to the container v.
end example
]
[Example
:
std::atomic<int> x{0};
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
  x.fetch_add(1, std::memory_order_relaxed);
  // spin wait for another iteration to change the value of x
  while (x.load(std::memory_order_relaxed) == 1) { } // incorrect: assumes execution order
});
The above example depends on the order of execution of the iterations, and will not terminate if both iterations are executed sequentially on the same thread of execution.
end example
]
[Example
:
int x = 0;
std::mutex m;
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
  std::lock_guard<mutex> guard(m);
  ++x;
});
The above example synchronizes access to object x ensuring that it is incremented correctly.
end example
]
The invocations of element access functions in parallel algorithms invoked with an execution policy of type execution​::​parallel_­unsequenced_­policy are permitted to execute in an unordered fashion in unspecified threads of execution, and unsequenced with respect to one another within each thread of execution.
These threads of execution are either the invoking thread of execution or threads of execution implicitly created by the library; the latter will provide weakly parallel forward progress guarantees.
[Note
:
This means that multiple function object invocations may be interleaved on a single thread of execution, which overrides the usual guarantee from [intro.execution] that function executions do not interleave with one another.
end note
]
Since execution​::​parallel_­unsequenced_­policy allows the execution of element access functions to be interleaved on a single thread of execution, blocking synchronization, including the use of mutexes, risks deadlock.
Thus, the synchronization with execution​::​parallel_­unsequenced_­policy is restricted as follows: A standard library function is vectorization-unsafe if it is specified to synchronize with another function invocation, or another function invocation is specified to synchronize with it, and if it is not a memory allocation or deallocation function.
Vectorization-unsafe standard library functions may not be invoked by user code called from execution​::​parallel_­unsequenced_­policy algorithms.
[Note
:
Implementations must ensure that internal synchronization inside standard library functions does not prevent forward progress when those functions are executed by threads of execution with weakly parallel forward progress guarantees.
end note
]
[Example
:
int x = 0;
std::mutex m;
int a[] = {1,2};
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) {
  std::lock_guard<mutex> guard(m); // incorrect: lock_­guard constructor calls m.lock()
  ++x;
});
The above program may result in two consecutive calls to m.lock() on the same thread of execution (which may deadlock), because the applications of the function object are not guaranteed to run on different threads of execution.
end example
]
[Note
:
The semantics of the execution​::​parallel_­policy or the execution​::​parallel_­unsequenced_­policy invocation allow the implementation to fall back to sequential execution if the system cannot parallelize an algorithm invocation due to lack of resources.
end note
]
If an invocation of a parallel algorithm uses threads of execution implicitly created by the library, then the invoking thread of execution will either
  • temporarily block with forward progress guarantee delegation ([intro.progress]) on the completion of these library-managed threads of execution, or
  • eventually execute an element access function;
the thread of execution will continue to do so until the algorithm is finished.
[Note
:
In blocking with forward progress guarantee delegation in this context, a thread of execution created by the library is considered to have finished execution as soon as it has finished the execution of the particular element access function that the invoking thread of execution logically depends on.
end note
]
The semantics of parallel algorithms invoked with an execution policy object of implementation-defined type are implementation-defined.

28.4.4 Parallel algorithm exceptions [algorithms.parallel.exceptions]

During the execution of a parallel algorithm, if temporary memory resources are required for parallelization and none are available, the algorithm throws a bad_­alloc exception.
During the execution of a parallel algorithm, if the invocation of an element access function exits via an uncaught exception, the behavior is determined by the ExecutionPolicy.

28.4.5 ExecutionPolicy algorithm overloads [algorithms.parallel.overloads]

Parallel algorithms are algorithm overloads.
Each parallel algorithm overload has an additional template type parameter named ExecutionPolicy, which is the first template parameter.
Additionally, each parallel algorithm overload has an additional function parameter of type ExecutionPolicy&&, which is the first function parameter.
[Note
:
Not all algorithms have parallel algorithm overloads.
end note
]
Unless otherwise specified, the semantics of ExecutionPolicy algorithm overloads are identical to their overloads without.
Unless otherwise specified, the complexity requirements of ExecutionPolicy algorithm overloads are relaxed from the complexity requirements of the overloads without as follows: when the guarantee says “at most expr” or “exactly expr” and does not specify the number of assignments or swaps, and expr is not already expressed with notation, the complexity of the algorithm shall be .
Parallel algorithms shall not participate in overload resolution unless is_­execution_­policy_­v<decay_­t<ExecutionPolicy>> is true.

28.5 Non-modifying sequence operations [alg.nonmodifying]

28.5.1 All of [alg.all_of]

template <class InputIterator, class Predicate> bool all_of(InputIterator first, InputIterator last, Predicate pred); template <class ExecutionPolicy, class ForwardIterator, class Predicate> bool all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Returns: true if [first, last) is empty or if pred(*i) is true for every iterator i in the range [first, last), and false otherwise.
Complexity: At most last - first applications of the predicate.

28.5.2 Any of [alg.any_of]

template <class InputIterator, class Predicate> bool any_of(InputIterator first, InputIterator last, Predicate pred); template <class ExecutionPolicy, class ForwardIterator, class Predicate> bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Returns: false if [first, last) is empty or if there is no iterator i in the range [first, last) such that pred(*i) is true, and true otherwise.
Complexity: At most last - first applications of the predicate.

28.5.3 None of [alg.none_of]

template <class InputIterator, class Predicate> bool none_of(InputIterator first, InputIterator last, Predicate pred); template <class ExecutionPolicy, class ForwardIterator, class Predicate> bool none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Returns: true if [first, last) is empty or if pred(*i) is false for every iterator i in the range [first, last), and false otherwise.
Complexity: At most last - first applications of the predicate.

28.5.4 For each [alg.foreach]

template<class InputIterator, class Function> Function for_each(InputIterator first, InputIterator last, Function f);
Requires: Function shall meet the requirements of MoveConstructible (Table 23).
[Note
:
Function need not meet the requirements of CopyConstructible (Table 24).
end note
]
Effects: Applies f to the result of dereferencing every iterator in the range [first, last), starting from first and proceeding to last - 1.
[Note
:
If the type of first satisfies the requirements of a mutable iterator, f may apply non-constant functions through the dereferenced iterator.
end note
]
Returns: f.
Complexity: Applies f exactly last - first times.
Remarks: If f returns a result, the result is ignored.
template<class ExecutionPolicy, class ForwardIterator, class Function> void for_each(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Function f);
Requires: Function shall meet the requirements of CopyConstructible.
Effects: Applies f to the result of dereferencing every iterator in the range [first, last).
[Note
:
If the type of first satisfies the requirements of a mutable iterator, f may apply non-constant functions through the dereferenced iterator.
end note
]
Complexity: Applies f exactly last - first times.
Remarks: If f returns a result, the result is ignored.
Implementations do not have the freedom granted under [algorithms.parallel.exec] to make arbitrary copies of elements from the input sequence.
[Note
:
Does not return a copy of its Function parameter, since parallelization may not permit efficient state accumulation.
end note
]
template<class InputIterator, class Size, class Function> InputIterator for_each_n(InputIterator first, Size n, Function f);
Requires: Function shall meet the requirements of MoveConstructible
[Note
:
Function need not meet the requirements of CopyConstructible.
end note
]
Requires: n >= 0.
Effects: Applies f to the result of dereferencing every iterator in the range [first, first + n) in order.
[Note
:
If the type of first satisfies the requirements of a mutable iterator, f may apply non-constant functions through the dereferenced iterator.
end note
]
Returns: first + n.
Remarks: If f returns a result, the result is ignored.
template<class ExecutionPolicy, class ForwardIterator, class Size, class Function> ForwardIterator for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, Function f);
Requires: Function shall meet the requirements of CopyConstructible.
Requires: n >= 0.
Effects: Applies f to the result of dereferencing every iterator in the range [first, first + n).
[Note
:
If the type of first satisfies the requirements of a mutable iterator, f may apply non-constant functions through the dereferenced iterator.
end note
]
Returns: first + n.
Remarks: If f returns a result, the result is ignored.
Implementations do not have the freedom granted under [algorithms.parallel.exec] to make arbitrary copies of elements from the input sequence.

28.5.5 Find [alg.find]

template<class InputIterator, class T> InputIterator find(InputIterator first, InputIterator last, const T& value); template<class ExecutionPolicy, class ForwardIterator, class T> ForwardIterator find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template<class InputIterator, class Predicate> InputIterator find_if(InputIterator first, InputIterator last, Predicate pred); template<class ExecutionPolicy, class ForwardIterator, class Predicate> ForwardIterator find_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); template<class InputIterator, class Predicate> InputIterator find_if_not(InputIterator first, InputIterator last, Predicate pred); template<class ExecutionPolicy, class ForwardIterator, class Predicate> ForwardIterator find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Returns: The first iterator i in the range [first, last) for which the following corresponding conditions hold: *i == value, pred(*i) != false, pred(*i) == false.
Returns last if no such iterator is found.
Complexity: At most last - first applications of the corresponding predicate.

28.5.6 Find end [alg.find.end]

template<class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_end(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_end(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
Effects: Finds a subsequence of equal values in a sequence.
Returns: The last iterator i in the range [first1, last1 - (last2 - first2)) such that for every non-negative integer n < (last2 - first2), the following corresponding conditions hold: *(i + n) == *(​first2 + n), pred(*(i + n), *(first2 + n)) != false.
Returns last1 if [first2, last2) is empty or if no such iterator is found.
Complexity: At most (last2 - first2) * (last1 - first1 - (last2 - first2) + 1) applications of the corresponding predicate.

28.5.7 Find first [alg.find.first.of]

template<class InputIterator, class ForwardIterator> InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator1 find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class InputIterator, class ForwardIterator, class BinaryPredicate> InputIterator find_first_of(InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
Effects: Finds an element that matches one of a set of values.
Returns: The first iterator i in the range [first1, last1) such that for some iterator j in the range [first2, last2) the following conditions hold: *i == *j, pred(*i,*j) != false.
Returns last1 if [first2, last2) is empty or if no such iterator is found.
Complexity: At most (last1-first1) * (last2-first2) applications of the corresponding predicate.

28.5.8 Adjacent find [alg.adjacent.find]

template<class ForwardIterator> ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> ForwardIterator adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template<class ForwardIterator, class BinaryPredicate> ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator, class BinaryPredicate> ForwardIterator adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
Returns: The first iterator i such that both i and i + 1 are in the range [first, last) for which the following corresponding conditions hold: *i == *(i + 1), pred(*i, *(i + 1)) != false.
Returns last if no such iterator is found.
Complexity: For the overloads with no ExecutionPolicy, exactly min((i - first) + 1, (last - first) - 1) applications of the corresponding predicate, where i is adjacent_­find's return value.
For the overloads with an ExecutionPolicy, applications of the corresponding predicate.

28.5.9 Count [alg.count]

template<class InputIterator, class T> typename iterator_traits<InputIterator>::difference_type count(InputIterator first, InputIterator last, const T& value); template<class ExecutionPolicy, class ForwardIterator, class T> typename iterator_traits<ForwardIterator>::difference_type count(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template<class InputIterator, class Predicate> typename iterator_traits<InputIterator>::difference_type count_if(InputIterator first, InputIterator last, Predicate pred); template<class ExecutionPolicy, class ForwardIterator, class Predicate> typename iterator_traits<ForwardIterator>::difference_type count_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Effects: Returns the number of iterators i in the range [first, last) for which the following corresponding conditions hold: *i == value, pred(*i) != false.
Complexity: Exactly last - first applications of the corresponding predicate.

28.5.10 Mismatch [mismatch]

template<class InputIterator1, class InputIterator2> pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> pair<ForwardIterator1, ForwardIterator2> mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template<class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> pair<ForwardIterator1, ForwardIterator2> mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); template<class InputIterator1, class InputIterator2> pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> pair<ForwardIterator1, ForwardIterator2> mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class InputIterator1, class InputIterator2, class BinaryPredicate> pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> pair<ForwardIterator1, ForwardIterator2> mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
Remarks: If last2 was not given in the argument list, it denotes first2 + (last1 - first1) below.
Returns: A pair of iterators first1 + n and first2 + n, where n is the smallest integer such that, respectively,
  • !(*(first1 + n) == *(first2 + n)) or
  • pred(*(first1 + n), *(first2 + n)) == false,
or min(last1 - first1, last2 - first2) if no such integer exists.
Complexity: At most min(last1 - first1, last2 - first2) applications of the corresponding predicate.

28.5.11 Equal [alg.equal]

template<class InputIterator1, class InputIterator2> bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> bool equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template<class InputIterator1, class InputIterator2, class BinaryPredicate> bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> bool equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); template<class InputIterator1, class InputIterator2> bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> bool equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class InputIterator1, class InputIterator2, class BinaryPredicate> bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> bool equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
Remarks: If last2 was not given in the argument list, it denotes first2 + (last1 - first1) below.
Returns: If last1 - first1 != last2 - first2, return false.
Otherwise return true if for every iterator i in the range [first1, last1) the following corresponding conditions hold: *i == *(first2 + (i - first1)), pred(*i, *(first2 + (i - first1))) != false.
Otherwise, returns false.
Complexity:
  • For the overloads with no ExecutionPolicy,
    • if InputIterator1 and InputIterator2 meet the requirements of random access iterators ([random.access.iterators]) and last1 - first1 != last2 - first2, then no applications of the corresponding predicate; otherwise,
    • at most applications of the corresponding predicate.
  • For the overloads with no ExecutionPolicy,
    • if ForwardIterator1 and ForwardIterator2 meet the requirements of random access iterators and last1 - first1 != last2 - first2, then no applications of the corresponding predicate; otherwise,
    • applications of the corresponding predicate.

28.5.12 Is permutation [alg.is_permutation]

template<class ForwardIterator1, class ForwardIterator2> bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); template<class ForwardIterator1, class ForwardIterator2> bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
Requires: ForwardIterator1 and ForwardIterator2 shall have the same value type.
The comparison function shall be an equivalence relation.
Remarks: If last2 was not given in the argument list, it denotes first2 + (last1 - first1) below.
Returns: If last1 - first1 != last2 - first2, return false.
Otherwise return true if there exists a permutation of the elements in the range [first2, first2 + (last1 - first1)), beginning with ForwardIterator2 begin, such that equal(first1, last1, begin) returns true or equal(first1, last1, begin, pred) returns true; otherwise, returns false.
Complexity: No applications of the corresponding predicate if ForwardIterator1 and ForwardIterator2 meet the requirements of random access iterators and last1 - first1 != last2 - first2.
Otherwise, exactly last1 - first1 applications of the corresponding predicate if equal(​first1, last1, first2, last2) would return true if pred was not given in the argument list or equal(first1, last1, first2, last2, pred) would return true if pred was given in the argument list; otherwise, at worst , where N has the value last1 - first1.

28.5.13 Search [alg.search]

template<class ForwardIterator1, class ForwardIterator2> ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator1 search(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 search(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
Effects: Finds a subsequence of equal values in a sequence.
Returns: The first iterator i in the range [first1, last1 - (last2-first2)) such that for every non-negative integer n less than last2 - first2 the following corresponding conditions hold: *(i + n) == *(first2 + n), pred(*(i + n), *(first2 + n)) != false.
Returns first1 if [first2, last2) is empty, otherwise returns last1 if no such iterator is found.
Complexity: At most (last1 - first1) * (last2 - first2) applications of the corresponding predicate.
template<class ForwardIterator, class Size, class T> ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value); template<class ForwardIterator, class Size, class T, class BinaryPredicate> ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator, class Size, class T> ForwardIterator search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value); template<class ExecutionPolicy, class ForwardIterator, class Size, class T, class BinaryPredicate> ForwardIterator search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred);
Requires: The type Size shall be convertible to integral type ([conv.integral], [class.conv]).
Effects: Finds a subsequence of equal values in a sequence.
Returns: The first iterator i in the range [first, last-count) such that for every non-negative integer n less than count the following corresponding conditions hold: *(i + n) == value, pred(*(i + n),value) != false.
Returns last if no such iterator is found.
Complexity: At most last - first applications of the corresponding predicate.
template<class ForwardIterator, class Searcher> ForwardIterator search(ForwardIterator first, ForwardIterator last, const Searcher& searcher);
Effects: Equivalent to: return searcher(first, last).first;
Remarks: Searcher need not meet the CopyConstructible requirements.

28.6 Mutating sequence operations [alg.modifying.operations]

28.6.1 Copy [alg.copy]

template<class InputIterator, class OutputIterator> OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result);
Requires: result shall not be in the range [first, last).
Effects: Copies elements in the range [first, last) into the range [result, result + (last - first)) starting from first and proceeding to last.
For each non-negative integer n < (last - first), performs *(result + n) = *(first + n).
Returns: result + (last - first).
Complexity: Exactly last - first assignments.
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 copy(ExecutionPolicy&& policy, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result);
Requires: The ranges [first, last) and [result, result + (last - first)) shall not overlap.
Effects: Copies elements in the range [first, last) into the range [result, result + (last - first)).
For each non-negative integer n < (last - first), performs *(result + n) = *(first + n).
Returns: result + (last - first).
Complexity: Exactly last - first assignments.
template<class InputIterator, class Size, class OutputIterator> OutputIterator copy_n(InputIterator first, Size n, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class Size, class ForwardIterator2> ForwardIterator2 copy_n(ExecutionPolicy&& exec, ForwardIterator1 first, Size n, ForwardIterator2 result);
Effects: For each non-negative integer , performs *(result + i) = *(first + i).
Returns: result + n.
Complexity: Exactly n assignments.
template<class InputIterator, class OutputIterator, class Predicate> OutputIterator copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Predicate> ForwardIterator2 copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred);
Requires: The ranges [first, last) and [result, result + (last - first)) shall not overlap.
[Note
:
For the overload with an ExecutionPolicy, there may be a performance cost if iterator_­traits<ForwardIterator1>​::​value_­type is not MoveConstructible (Table 23).
end note
]
Effects: Copies all of the elements referred to by the iterator i in the range [first, last) for which pred(*i) is true.
Returns: The end of the resulting range.
Complexity: Exactly last - first applications of the corresponding predicate.
Remarks: Stable ([algorithm.stable]).
template<class BidirectionalIterator1, class BidirectionalIterator2> BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result);
Requires: result shall not be in the range (first, last].
Effects: Copies elements in the range [first, last) into the range [result - (last-first), result) starting from last - 1 and proceeding to first.263
For each positive integer n <= (last - first), performs *(result - n) = *(last - n).
Returns: result - (last - first).
Complexity: Exactly last - first assignments.
copy_­backward should be used instead of copy when last is in the range [result - (last - first), result).

28.6.2 Move [alg.move]

template<class InputIterator, class OutputIterator> OutputIterator move(InputIterator first, InputIterator last, OutputIterator result);
Requires: result shall not be in the range [first, last).
Effects: Moves elements in the range [first, last) into the range [result, result + (last - first)) starting from first and proceeding to last.
For each non-negative integer n < (last-first), performs *(result + n) = std​::​move(*(first + n)).
Returns: result + (last - first).
Complexity: Exactly last - first move assignments.
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 move(ExecutionPolicy&& policy, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result);
Requires: The ranges [first, last) and [result, result + (last - first)) shall not overlap.
Effects: Moves elements in the range [first, last) into the range [result, result + (last - first)).
For each non-negative integer n < (last - first), performs *(result + n) = std​::​​move(*(first + n)).
Returns: result + (last - first).
Complexity: Exactly last - first assignments.
template<class BidirectionalIterator1, class BidirectionalIterator2> BidirectionalIterator2 move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result);
Requires: result shall not be in the range (first, last].
Effects: Moves elements in the range [first, last) into the range [result - (last-first), result) starting from last - 1 and proceeding to first.264
For each positive integer n <= (last - first), performs *(result - n) = std​::​move(*(last - n)).
Returns: result - (last - first).
Complexity: Exactly last - first assignments.
move_­backward should be used instead of move when last is in the range [result - (last - first), result).

28.6.3 Swap [alg.swap]

template<class ForwardIterator1, class ForwardIterator2> ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);
Requires: The two ranges [first1, last1) and [first2, first2 + (last1 - first1)) shall not overlap.
*(first1 + n) shall be swappable with ([swappable.requirements]) *(first2 + n).
Effects: For each non-negative integer n < (last1 - first1) performs: swap(*(first1 + n), ​*(first2 + n)).
Returns: first2 + (last1 - first1).
Complexity: Exactly last1 - first1 swaps.
template<class ForwardIterator1, class ForwardIterator2> void iter_swap(ForwardIterator1 a, ForwardIterator2 b);
Requires: a and b shall be dereferenceable.
*a shall be swappable with ([swappable.requirements]) *b.
Effects: As if by swap(*a, *b).

28.6.4 Transform [alg.transform]

template<class InputIterator, class OutputIterator, class UnaryOperation> OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class UnaryOperation> ForwardIterator2 transform(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, UnaryOperation op); template<class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class BinaryOperation> ForwardIterator transform(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator result, BinaryOperation binary_op);
Requires: op and binary_­op shall not invalidate iterators or subranges, or modify elements in the ranges
  • [first1, last1],
  • [first2, first2 + (last1 - first1)], and
  • [result, result + (last1 - first1)].265
Effects: Assigns through every iterator i in the range [result, result + (last1 - first1)) a new corresponding value equal to op(*(first1 + (i - result))) or binary_­op(*(first1 + (i - result)), *(first2 + (i - result))).
Returns: result + (last1 - first1).
Complexity: Exactly last1 - first1 applications of op or binary_­op.
This requirement also applies to the overload with an ExecutionPolicy .
Remarks: result may be equal to first in case of unary transform, or to first1 or first2 in case of binary transform.
The use of fully closed ranges is intentional.

28.6.5 Replace [alg.replace]

template<class ForwardIterator, class T> void replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); template<class ExecutionPolicy, class ForwardIterator, class T> void replace(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); template<class ForwardIterator, class Predicate, class T> void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value); template<class ExecutionPolicy, class ForwardIterator, class Predicate, class T> void replace_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value);
Requires: The expression *first = new_­value shall be valid.
Effects: Substitutes elements referred by the iterator i in the range [first, last) with new_­value, when the following corresponding conditions hold: *i == old_­value, pred(*i) != false.
Complexity: Exactly last - first applications of the corresponding predicate.
template<class InputIterator, class OutputIterator, class T> OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T> ForwardIterator2 replace_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& old_value, const T& new_value); template<class InputIterator, class OutputIterator, class Predicate, class T> OutputIterator replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Predicate, class T> ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred, const T& new_value);
Requires: The results of the expressions *first and new_­value shall be writable ([iterator.requirements.general]) to the result output iterator.
The ranges [first, last) and [result, result + (last - first)) shall not overlap.
Effects: Assigns to every iterator i in the range [result, result + (last - first)) either new_­value or *​(first + (i - result)) depending on whether the following corresponding conditions hold:
*(first + (i - result)) == old_value
pred(*(first + (i - result))) != false
Returns: result + (last - first).
Complexity: Exactly last - first applications of the corresponding predicate.

28.6.6 Fill [alg.fill]

template<class ForwardIterator, class T> void fill(ForwardIterator first, ForwardIterator last, const T& value); template<class ExecutionPolicy, class ForwardIterator, class T> void fill(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template<class OutputIterator, class Size, class T> OutputIterator fill_n(OutputIterator first, Size n, const T& value); template<class ExecutionPolicy, class ForwardIterator, class Size, class T> ForwardIterator fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value);
Requires: The expression value shall be writable ([iterator.requirements.general]) to the output iterator.
The type Size shall be convertible to an integral type ([conv.integral], [class.conv]).
Effects: The fill algorithms assign value through all the iterators in the range [first, last).
The fill_­n algorithms assign value through all the iterators in the range [first, first + n) if n is positive, otherwise they do nothing.
Returns: fill_­n returns first + n for non-negative values of n and first for negative values.
Complexity: Exactly last - first, n, or 0 assignments, respectively.

28.6.7 Generate [alg.generate]

template<class ForwardIterator, class Generator> void generate(ForwardIterator first, ForwardIterator last, Generator gen); template<class ExecutionPolicy, class ForwardIterator, class Generator> void generate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Generator gen); template<class OutputIterator, class Size, class Generator> OutputIterator generate_n(OutputIterator first, Size n, Generator gen); template<class ExecutionPolicy, class ForwardIterator, class Size, class Generator> ForwardIterator generate_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, Generator gen);
Requires: gen takes no arguments, Size shall be convertible to an integral type ([conv.integral], [class.conv]).
Effects: The generate algorithms invoke the function object gen and assign the return value of gen through all the iterators in the range [first, last).
The generate_­n algorithms invoke the function object gen and assign the return value of gen through all the iterators in the range [first, first + n) if n is positive, otherwise they do nothing.
Returns: generate_­n returns first + n for non-negative values of n and first for negative values.
Complexity: Exactly last - first, n, or 0 invocations of gen and assignments, respectively.

28.6.8 Remove [alg.remove]

template<class ForwardIterator, class T> ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& value); template<class ExecutionPolicy, class ForwardIterator, class T> ForwardIterator remove(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); template<class ForwardIterator, class Predicate> ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, Predicate pred); template<class ExecutionPolicy, class ForwardIterator, class Predicate> ForwardIterator remove_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Requires: The type of *first shall satisfy the MoveAssignable requirements (Table 25).
Effects: Eliminates all the elements referred to by iterator i in the range [first, last) for which the following corresponding conditions hold: *i == value, pred(*i) != false.
Returns: The end of the resulting range.
Remarks: Stable ([algorithm.stable]).
Complexity: Exactly last - first applications of the corresponding predicate.
[Note
:
Each element in the range [ret, last), where ret is the returned value, has a valid but unspecified state, because the algorithms can eliminate elements by moving from elements that were originally in that range.
end note
]
template<class InputIterator, class OutputIterator, class T> OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T> ForwardIterator2 remove_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& value); template<class InputIterator, class OutputIterator, class Predicate> OutputIterator remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Predicate> ForwardIterator2 remove_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred);
Requires: The ranges [first, last) and [result, result + (last - first)) shall not overlap.
The expression *result = *first shall be valid.
[Note
:
For the overloads with an ExecutionPolicy, there may be a performance cost if iterator_­traits<ForwardIterator1>​::​value_­type is not MoveConstructible (Table 23).
end note
]
Effects: Copies all the elements referred to by the iterator i in the range [first, last) for which the following corresponding conditions do not hold: *i == value, pred(*i) != false.
Returns: The end of the resulting range.
Complexity: Exactly last - first applications of the corresponding predicate.
Remarks: Stable ([algorithm.stable]).

28.6.9 Unique [alg.unique]

template<class ForwardIterator> ForwardIterator unique(ForwardIterator first, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> ForwardIterator unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template<class ForwardIterator, class BinaryPredicate> ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator, class BinaryPredicate> ForwardIterator unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
Requires: The comparison function shall be an equivalence relation.
The type of *first shall satisfy the MoveAssignable requirements (Table 25).
Effects: For a nonempty range, eliminates all but the first element from every consecutive group of equivalent elements referred to by the iterator i in the range [first + 1, last) for which the following conditions hold: *(i - 1) == *i or pred(*(i - 1), *i) != false.
Returns: The end of the resulting range.
Complexity: For nonempty ranges, exactly (last - first) - 1 applications of the corresponding predicate.
template<class InputIterator, class OutputIterator> OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template<class InputIterator, class OutputIterator, class BinaryPredicate> OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator2 unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred);
Requires:
  • The comparison function shall be an equivalence relation.
  • The ranges [first, last) and [result, result+(last-first)) shall not overlap.
  • The expression *result = *first shall be valid.
  • For the overloads with no ExecutionPolicy, let T be the value type of InputIterator.
    If InputIterator meets the forward iterator requirements, then there are no additional requirements for T.
    Otherwise, if OutputIterator meets the forward iterator requirements and its value type is the same as T, then T shall be CopyAssignable (Table 26).
    Otherwise, T shall be both CopyConstructible (Table 24) and CopyAssignable.
    [Note
    :
    For the overloads with an ExecutionPolicy, there may be a performance cost if the value type of ForwardIterator1 is not both CopyConstructible and CopyAssignable.
    end note
    ]
Effects: Copies only the first element from every consecutive group of equal elements referred to by the iterator i in the range [first, last) for which the following corresponding conditions hold: *i == *(i - 1) or pred(*i, *(i - 1)) != false.
Returns: The end of the resulting range.
Complexity: For nonempty ranges, exactly last - first - 1 applications of the corresponding predicate.

28.6.10 Reverse [alg.reverse]

template<class BidirectionalIterator> void reverse(BidirectionalIterator first, BidirectionalIterator last); template<class ExecutionPolicy, class BidirectionalIterator> void reverse(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last);
Requires: *first shall be swappable ([swappable.requirements]).
Effects: For each non-negative integer i < (last - first) / 2, applies iter_­swap to all pairs of iterators first + i, (last - i) - 1.
Requires: BidirectionalIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
Complexity: Exactly (last - first)/2 swaps.
template<class BidirectionalIterator, class OutputIterator> OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result); template<class ExecutionPolicy, class BidirectionalIterator, class ForwardIterator> ForwardIterator reverse_copy(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, ForwardIterator result);
Requires: The ranges [first, last) and [result, result + (last - first)) shall not overlap.
Effects: Copies the range [first, last) to the range [result, result + (last - first)) such that for every non-negative integer i < (last - first) the following assignment takes place: *(result + (last - first) - 1 - i) = *(first + i).
Returns: result + (last - first).
Complexity: Exactly last - first assignments.

28.6.11 Rotate [alg.rotate]

template<class ForwardIterator> ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> ForwardIterator rotate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator middle, ForwardIterator last);
Requires: [first, middle) and [middle, last) shall be valid ranges.
ForwardIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and the requirements of MoveAssignable (Table 25).
Effects: For each non-negative integer i < (last - first), places the element from the position first + i into position first + (i + (last - middle)) % (last - first).
Returns: first + (last - middle).
Remarks: This is a left rotate.
Complexity: At most last - first swaps.
template<class ForwardIterator, class OutputIterator> OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 rotate_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, ForwardIterator2 result);
Requires: The ranges [first, last) and [result, result + (last - first)) shall not overlap.
Effects: Copies the range [first, last) to the range [result, result + (last - first)) such that for each non-negative integer i < (last - first) the following assignment takes place: *(result + i) = *(first + (i + (middle - first)) % (last - first)).
Returns: result + (last - first).
Complexity: Exactly last - first assignments.

28.6.12 Sample [alg.random.sample]

template<class PopulationIterator, class SampleIterator, class Distance, class UniformRandomBitGenerator> SampleIterator sample(PopulationIterator first, PopulationIterator last, SampleIterator out, Distance n, UniformRandomBitGenerator&& g);
Requires:
Effects: Copies min(last - first, n) elements (the sample) from [first, last) (the population) to out such that each possible sample has equal probability of appearance.
[Note
:
Algorithms that obtain such effects include selection sampling and reservoir sampling.
end note
]
Returns: The end of the resulting sample range.
Complexity: .
Remarks:
  • Stable if and only if PopulationIterator satisfies the requirements of a forward iterator.
  • To the extent that the implementation of this function makes use of random numbers, the object g shall serve as the implementation's source of randomness.

28.6.13 Shuffle [alg.random.shuffle]

template<class RandomAccessIterator, class UniformRandomBitGenerator> void shuffle(RandomAccessIterator first, RandomAccessIterator last, UniformRandomBitGenerator&& g);
Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type remove_­reference_­t<UniformRandomBitGenerator> shall meet the requirements of a uniform random bit generator ([rand.req.urng]) type whose return type is convertible to iterator_­traits<RandomAccessIterator>​::​difference_­type.
Effects: Permutes the elements in the range [first, last) such that each possible permutation of those elements has equal probability of appearance.
Complexity: Exactly (last - first) - 1 swaps.
Remarks: To the extent that the implementation of this function makes use of random numbers, the object g shall serve as the implementation's source of randomness.

28.7 Sorting and related operations [alg.sorting]

All the operations in [alg.sorting] have two versions: one that takes a function object of type Compare and one that uses an operator<.
Compare is a function object type ([function.objects]).
The return value of the function call operation applied to an object of type Compare, when contextually converted to bool (Clause [conv]), yields true if the first argument of the call is less than the second, and false otherwise.
Compare comp is used throughout for algorithms assuming an ordering relation.
It is assumed that comp will not apply any non-constant function through the dereferenced iterator.
For all algorithms that take Compare, there is a version that uses operator< instead.
That is, comp(*i, *j) != false defaults to *i < *j != false.
For algorithms other than those described in [alg.binary.search], comp shall induce a strict weak ordering on the values.
The term strict refers to the requirement of an irreflexive relation (!comp(x, x) for all x), and the term weak to requirements that are not as strong as those for a total ordering, but stronger than those for a partial ordering.
If we define equiv(a, b) as !comp(a, b) && !comp(b, a), then the requirements are that comp and equiv both be transitive relations:
  • comp(a, b) && comp(b, c) implies comp(a, c)
  • equiv(a, b) && equiv(b, c) implies equiv(a, c)
[Note
:
Under these conditions, it can be shown that
  • equiv is an equivalence relation
  • comp induces a well-defined relation on the equivalence classes determined by equiv
  • The induced relation is a strict total ordering.
end note
]
A sequence is sorted with respect to a comparator comp if for every iterator i pointing to the sequence and every non-negative integer n such that i + n is a valid iterator pointing to an element of the sequence, comp(*(i + n), *i) == false.
A sequence [start, finish) is partitioned with respect to an expression f(e) if there exists an integer n such that for all 0 <= i < (finish - start), f(*(start + i)) is true if and only if i < n.
In the descriptions of the functions that deal with ordering relationships we frequently use a notion of equivalence to describe concepts such as stability.
The equivalence to which we refer is not necessarily an operator==, but an equivalence relation induced by the strict weak ordering.
That is, two elements a and b are considered equivalent if and only if !(a < b) && !(b < a).

28.7.1 Sorting [alg.sort]

28.7.1.1 sort [sort]

template<class RandomAccessIterator> void sort(RandomAccessIterator first, RandomAccessIterator last); template<class ExecutionPolicy, class RandomAccessIterator> void sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<class ExecutionPolicy, class RandomAccessIterator, class Compare> void sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Sorts the elements in the range [first, last).
Complexity: comparisons, where .

28.7.1.2 stable_­sort [stable.sort]

template<class RandomAccessIterator> void stable_sort(RandomAccessIterator first, RandomAccessIterator last); template<class ExecutionPolicy, class RandomAccessIterator> void stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<class ExecutionPolicy, class RandomAccessIterator, class Compare> void stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Sorts the elements in the range [first, last).
Complexity: At most comparisons, where , but only comparisons if there is enough extra memory.
Remarks: Stable ([algorithm.stable]).

28.7.1.3 partial_­sort [partial.sort]

template<class RandomAccessIterator> void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); template<class ExecutionPolicy, class RandomAccessIterator> void partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); template<class ExecutionPolicy, class RandomAccessIterator, class Compare> void partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp);
Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Places the first middle - first sorted elements from the range [first, last) into the range [first, middle).
The rest of the elements in the range [middle, last) are placed in an unspecified order.
Complexity: Approximately (last - first) * log(middle - first) comparisons.

28.7.1.4 partial_­sort_­copy [partial.sort.copy]

template<class InputIterator, class RandomAccessIterator> RandomAccessIterator partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last); template<class ExecutionPolicy, class ForwardIterator, class RandomAccessIterator> RandomAccessIterator partial_sort_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last); template<class InputIterator, class RandomAccessIterator, class Compare> RandomAccessIterator partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp); template<class ExecutionPolicy, class ForwardIterator, class RandomAccessIterator, class Compare> RandomAccessIterator partial_sort_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp);
Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *result_­first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Places the first min(last - first, result_­last - result_­first) sorted elements into the range [result_­first, result_­first + min(last - first, result_­last - result_­first)).
Returns: The smaller of: result_­last or result_­first + (last - first).
Complexity: Approximately (last - first) * log(min(last - first, result_­last - result_­first)) comparisons.

28.7.1.5 is_­sorted [is.sorted]

template<class ForwardIterator> bool is_sorted(ForwardIterator first, ForwardIterator last);
Returns: is_­sorted_­until(first, last) == last
template<class ExecutionPolicy, class ForwardIterator> bool is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last);
Returns: is_­sorted_­until(std​::​forward<ExecutionPolicy>(exec), first, last) == last
template<class ForwardIterator, class Compare> bool is_sorted(ForwardIterator first, ForwardIterator last, Compare comp);
Returns: is_­sorted_­until(first, last, comp) == last
template<class ExecutionPolicy, class ForwardIterator, class Compare> bool is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp);
Returns:
is_sorted_until(std::forward<ExecutionPolicy>(exec), first, last, comp) == last
template<class ForwardIterator> ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> ForwardIterator is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template<class ForwardIterator, class Compare> ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp); template<class ExecutionPolicy, class ForwardIterator, class Compare> ForwardIterator is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp);
Returns: If (last - first) < 2, returns last.
Otherwise, returns the last iterator i in [first, last] for which the range [first, i) is sorted.
Complexity: Linear.

28.7.2 Nth element [alg.nth.element]

template<class RandomAccessIterator> void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); template<class ExecutionPolicy, class RandomAccessIterator> void nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); template<class ExecutionPolicy, class RandomAccessIterator, class Compare> void nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);
Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: After nth_­element the element in the position pointed to by nth is the element that would be in that position if the whole range were sorted, unless nth == last.
Also for every iterator i in the range [first, nth) and every iterator j in the range [nth, last) it holds that: !(*j < *i) or comp(*j, *i) == false.
Complexity: For the overloads with no ExecutionPolicy, linear on average.
For the overloads with an ExecutionPolicy, applications of the predicate, and swaps, where .

28.7.3 Binary search [alg.binary.search]

All of the algorithms in this section are versions of binary search and assume that the sequence being searched is partitioned with respect to an expression formed by binding the search key to an argument of the implied or explicit comparison function.
They work on non-random access iterators minimizing the number of comparisons, which will be logarithmic for all types of iterators.
They are especially appropriate for random access iterators, because these algorithms do a logarithmic number of steps through the data structure.
For non-random access iterators they execute a linear number of steps.

28.7.3.1 lower_­bound [lower.bound]

template<class ForwardIterator, class T> ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value); template<class ForwardIterator, class T, class Compare> ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
Requires: The elements e of [first, last) shall be partitioned with respect to the expression e < value or comp(e, value).
Returns: The furthermost iterator i in the range [first, last] such that for every iterator j in the range [first, i) the following corresponding conditions hold: *j < value or comp(*j, value) != false.
Complexity: At most comparisons.

28.7.3.2 upper_­bound [upper.bound]

template<class ForwardIterator, class T> ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value); template<class ForwardIterator, class T, class Compare> ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
Requires: The elements e of [first, last) shall be partitioned with respect to the expression !(value < e) or !comp(​value, e).
Returns: The furthermost iterator i in the range [first, last] such that for every iterator j in the range [first, i) the following corresponding conditions hold: !(value < *j) or comp(value, *j) == false.
Complexity: At most comparisons.

28.7.3.3 equal_­range [equal.range]

template<class ForwardIterator, class T> pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, const T& value); template<class ForwardIterator, class T, class Compare> pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
Requires: The elements e of [first, last) shall be partitioned with respect to the expressions e < value and !(value < e) or comp(e, value) and !comp(value, e).
Also, for all elements e of [first, last), e < value shall imply !(value < e) or comp(e, value) shall imply !comp(value, e).
Returns:
make_pair(lower_bound(first, last, value),
          upper_bound(first, last, value))
or
make_pair(lower_bound(first, last, value, comp),
          upper_bound(first, last, value, comp))
Complexity: At most comparisons.

28.7.3.4 binary_­search [binary.search]

template<class ForwardIterator, class T> bool binary_search(ForwardIterator first, ForwardIterator last, const T& value); template<class ForwardIterator, class T, class Compare> bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
Requires: The elements e of [first, last) are partitioned with respect to the expressions e < value and !(value < e) or comp(e, value) and !comp(value, e).
Also, for all elements e of [first, last), e < value implies !(value < e) or comp(e, value) implies !comp(value, e).
Returns: true if there is an iterator i in the range [first, last) that satisfies the corresponding conditions: !(*i < value) && !(value < *i) or comp(*i, value) == false && comp(value, *i) == false.
Complexity: At most comparisons.

28.7.4 Partitions [alg.partitions]

template <class InputIterator, class Predicate> bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); template <class ExecutionPolicy, class ForwardIterator, class Predicate> bool is_partitioned(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Requires: For the overload with no ExecutionPolicy, InputIterator's value type shall be convertible to Predicate's argument type.
For the overload with an ExecutionPolicy, ForwardIterator's value type shall be convertible to Predicate's argument type.
Returns: true if [first, last) is empty or if [first, last) is partitioned by pred, i.e. if all elements that satisfy pred appear before those that do not.
Complexity: Linear.
At most last - first applications of pred.
template<class ForwardIterator, class Predicate> ForwardIterator partition(ForwardIterator first, ForwardIterator last, Predicate pred); template<class ExecutionPolicy, class ForwardIterator, class Predicate> ForwardIterator partition(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred);
Requires: ForwardIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
Effects: Places all the elements in the range [first, last) that satisfy pred before all the elements that do not satisfy it.
Returns: An iterator i such that for every iterator j in the range [first, i) pred(*j) != false, and for every iterator k in the range [i, last), pred(*k) == false.
Complexity: Let :
  • For the overload with no ExecutionPolicy, exactly N applications of the predicate.
    At most swaps if ForwardIterator meets the BidirectionalIterator requirements and at most N swaps otherwise.
  • For the overload with an ExecutionPolicy, swaps and applications of the predicate.
template<class BidirectionalIterator, class Predicate> BidirectionalIterator stable_partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred); template<class ExecutionPolicy, class BidirectionalIterator, class Predicate> BidirectionalIterator stable_partition(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, Predicate pred);
Requires: BidirectionalIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Places all the elements in the range [first, last) that satisfy pred before all the elements that do not satisfy it.
Returns: An iterator i such that for every iterator j in the range [first, i), pred(*j) != false, and for every iterator k in the range [i, last), pred(*k) == false.
The relative order of the elements in both groups is preserved.
Complexity: Let N = last - first:
  • For the overload with no ExecutionPolicy, at most swaps, but only swaps if there is enough extra memory.
    Exactly N applications of the predicate.
  • For the overload with an ExecutionPolicy, swaps and applications of the predicate.
template <class InputIterator, class OutputIterator1, class OutputIterator2, class Predicate> pair<OutputIterator1, OutputIterator2> partition_copy(InputIterator first, InputIterator last, OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); template <class ExecutionPolicy, class ForwardIterator, class ForwardIterator1, class ForwardIterator2, class Predicate> pair<ForwardIterator1, ForwardIterator2> partition_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred);
Requires:
  • For the overload with no ExecutionPolicy, InputIterator's value type shall be CopyAssignable (Table 26), and shall be writable ([iterator.requirements.general]) to the out_­true and out_­false OutputIterators, and shall be convertible to Predicate's argument type.
  • For the overload with an ExecutionPolicy, ForwardIterator's value type shall be CopyAssignable, and shall be writable to the out_­true and out_­false ForwardIterators, and shall be convertible to Predicate's argument type.
    [Note
    :
    There may be a performance cost if ForwardIterator's value type is not CopyConstructible.
    end note
    ]
  • For both overloads, the input range shall not overlap with either of the output ranges.
Effects: For each iterator i in [first, last), copies *i to the output range beginning with out_­true if pred(*i) is true, or to the output range beginning with out_­false otherwise.
Returns: A pair p such that p.first is the end of the output range beginning at out_­true and p.second is the end of the output range beginning at out_­false.
Complexity: Exactly last - first applications of pred.
template<class ForwardIterator, class Predicate> ForwardIterator partition_point(ForwardIterator first, ForwardIterator last, Predicate pred);
Requires: ForwardIterator's value type shall be convertible to Predicate's argument type.
[first, last) shall be partitioned by pred, i.e. all elements that satisfy pred shall appear before those that do not.
Returns: An iterator mid such that all_­of(first, mid, pred) and none_­of(mid, last, pred) are both true.
Complexity: applications of pred.

28.7.5 Merge [alg.merge]

template<class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> ForwardIterator merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> ForwardIterator merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp);
Requires: The ranges [first1, last1) and [first2, last2) shall be sorted with respect to operator< or comp.
The resulting range shall not overlap with either of the original ranges.
Effects: Copies all the elements of the two ranges [first1, last1) and [first2, last2) into the range [result, result_­last), where result_­last is result + (last1 - first1) + (last2 - first2), such that the resulting range satisfies is_­sorted(result, result_­last) or is_­sorted(result, result_­last, comp), respectively.
Returns: result + (last1 - first1) + (last2 - first2).
Complexity: Let :
  • For the overloads with no ExecutionPolicy, at most comparisons.
  • For the overloads with an ExecutionPolicy, comparisons.
Remarks: Stable ([algorithm.stable]).
template<class BidirectionalIterator> void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); template<class ExecutionPolicy, class BidirectionalIterator> void inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); template<class BidirectionalIterator, class Compare> void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); template<class ExecutionPolicy, class BidirectionalIterator, class Compare> void inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);
Requires: The ranges [first, middle) and [middle, last) shall be sorted with respect to operator< or comp.
BidirectionalIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Merges two sorted consecutive ranges [first, middle) and [middle, last), putting the result of the merge into the range [first, last).
The resulting range will be in non-decreasing order; that is, for every iterator i in [first, last) other than first, the condition *i < *(i - 1) or, respectively, comp(*i, *(i - 1)) will be false.
Complexity: Let :
  • For the overloads with no ExecutionPolicy, if enough additional memory is available, exactly comparisons.
  • For the overloads with no ExecutionPolicy if no additional memory is available, comparisons.
  • For the overloads with an ExecutionPolicy, comparisons.
Remarks: Stable ([algorithm.stable]).

28.7.6 Set operations on sorted structures [alg.set.operations]

This section defines all the basic set operations on sorted structures.
They also work with multisets ([multiset]) containing multiple copies of equivalent elements.
The semantics of the set operations are generalized to multisets in a standard way by defining set_­union() to contain the maximum number of occurrences of every element, set_­intersection() to contain the minimum, and so on.

28.7.6.1 includes [includes]

template<class InputIterator1, class InputIterator2> bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> bool includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class InputIterator1, class InputIterator2, class Compare> bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare> bool includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp);
Returns: true if [first2, last2) is empty or if every element in the range [first2, last2) is contained in the range [first1, last1).
Returns false otherwise.
Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.

28.7.6.2 set_­union [set.union]

template<class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> ForwardIterator set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> ForwardIterator set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp);
Requires: The resulting range shall not overlap with either of the original ranges.
Effects: Constructs a sorted union of the elements from the two ranges; that is, the set of elements that are present in one or both of the ranges.
Returns: The end of the constructed range.
Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
Remarks: If [first1, last1) contains m elements that are equivalent to each other and [first2, last2) contains n elements that are equivalent to them, then all m elements from the first range shall be copied to the output range, in order, and then elements from the second range shall be copied to the output range, in order.

28.7.6.3 set_­intersection [set.intersection]

template<class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> ForwardIterator set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> ForwardIterator set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp);
Requires: The resulting range shall not overlap with either of the original ranges.
Effects: Constructs a sorted intersection of the elements from the two ranges; that is, the set of elements that are present in both of the ranges.
Returns: The end of the constructed range.
Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
Remarks: If [first1, last1) contains m elements that are equivalent to each other and [first2, last2) contains n elements that are equivalent to them, the first elements shall be copied from the first range to the output range, in order.

28.7.6.4 set_­difference [set.difference]

template<class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> ForwardIterator set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> ForwardIterator set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp);
Requires: The resulting range shall not overlap with either of the original ranges.
Effects: Copies the elements of the range [first1, last1) which are not present in the range [first2, last2) to the range beginning at result.
The elements in the constructed range are sorted.
Returns: The end of the constructed range.
Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
Remarks: If [first1, last1) contains m elements that are equivalent to each other and [first2, last2) contains n elements that are equivalent to them, the last elements from [first1, last1) shall be copied to the output range.

28.7.6.5 set_­symmetric_­difference [set.symmetric.difference]

template<class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> ForwardIterator set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result); template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> ForwardIterator set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp);
Requires: The resulting range shall not overlap with either of the original ranges.
Effects: Copies the elements of the range [first1, last1) that are not present in the range [first2, last2), and the elements of the range [first2, last2) that are not present in the range [first1, last1) to the range beginning at result.
The elements in the constructed range are sorted.
Returns: The end of the constructed range.
Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
Remarks: If [first1, last1) contains m elements that are equivalent to each other and [first2, last2) contains n elements that are equivalent to them, then of those elements shall be copied to the output range: the last of these elements from [first1, last1) if , and the last of these elements from [first2, last2) if .

28.7.7 Heap operations [alg.heap.operations]

A heap is a particular organization of elements in a range between two random access iterators [a, b) such that:
  • With N = b - a, for all i, , comp(a[], a[i]) is false.
  • *a may be removed by pop_­heap(), or a new element added by push_­heap(), in time.
These properties make heaps useful as priority queues.
make_­heap() converts a range into a heap and sort_­heap() turns a heap into a sorted sequence.

28.7.7.1 push_­heap [push.heap]

template<class RandomAccessIterator> void push_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Requires: The range [first, last - 1) shall be a valid heap.
The type of *first shall satisfy the MoveConstructible requirements (Table 23) and the MoveAssignable requirements (Table 25).
Effects: Places the value in the location last - 1 into the resulting heap [first, last).
Complexity: At most comparisons.

28.7.7.2 pop_­heap [pop.heap]

template<class RandomAccessIterator> void pop_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Requires: The range [first, last) shall be a valid non-empty heap.
RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Swaps the value in the location first with the value in the location last - 1 and makes [first, last - 1) into a heap.
Complexity: At most comparisons.

28.7.7.3 make_­heap [make.heap]

template<class RandomAccessIterator> void make_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Requires: The type of *first shall satisfy the MoveConstructible requirements (Table 23) and the MoveAssignable requirements (Table 25).
Effects: Constructs a heap out of the range [first, last).
Complexity: At most comparisons.

28.7.7.4 sort_­heap [sort.heap]

template<class RandomAccessIterator> void sort_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Requires: The range [first, last) shall be a valid heap.
RandomAccessIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
The type of *first shall satisfy the requirements of MoveConstructible (Table 23) and of MoveAssignable (Table 25).
Effects: Sorts elements in the heap [first, last).
Complexity: At most comparisons, where .

28.7.7.5 is_­heap [is.heap]

template<class RandomAccessIterator> bool is_heap(RandomAccessIterator first, RandomAccessIterator last);
Returns: is_­heap_­until(first, last) == last
template<class ExecutionPolicy, class RandomAccessIterator> bool is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last);
Returns: is_­heap_­until(std​::​forward<ExecutionPolicy>(exec), first, last) == last
template<class RandomAccessIterator, class Compare> bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Returns: is_­heap_­until(first, last, comp) == last
template<class ExecutionPolicy, class RandomAccessIterator, class Compare> bool is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Returns:
is_heap_until(std::forward<ExecutionPolicy>(exec), first, last, comp) == last
template<class RandomAccessIterator> RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last); template<class ExecutionPolicy, class RandomAccessIterator> RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<class ExecutionPolicy, class RandomAccessIterator, class Compare> RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp);
Returns: If (last - first) < 2, returns last.
Otherwise, returns the last iterator i in [first, last] for which the range [first, i) is a heap.
Complexity: Linear.

28.7.8 Minimum and maximum [alg.min.max]

template<class T> constexpr const T& min(const T& a, const T& b); template<class T, class Compare> constexpr const T& min(const T& a, const T& b, Compare comp);
Requires: For the first form, type T shall be LessThanComparable (Table 21).
Returns: The smaller value.
Remarks: Returns the first argument when the arguments are equivalent.
Complexity: Exactly one comparison.
template<class T> constexpr T min(initializer_list<T> t); template<class T, class Compare> constexpr T min(initializer_list<T> t, Compare comp);
Requires: T shall be CopyConstructible and t.size() > 0.
For the first form, type T shall be LessThanComparable.
Returns: The smallest value in the initializer_list.
Remarks: Returns a copy of the leftmost argument when several arguments are equivalent to the smallest.
Complexity: Exactly t.size() - 1 comparisons.
template<class T> constexpr const T& max(const T& a, const T& b); template<class T, class Compare> constexpr const T& max(const T& a, const T& b, Compare comp);
Requires: For the first form, type T shall be LessThanComparable (Table 21).
Returns: The larger value.
Remarks: Returns the first argument when the arguments are equivalent.
Complexity: Exactly one comparison.
template<class T> constexpr T max(initializer_list<T> t); template<class T, class Compare> constexpr T max(initializer_list<T> t, Compare comp);
Requires: T shall be CopyConstructible and t.size() > 0.
For the first form, type T shall be LessThanComparable.
Returns: The largest value in the initializer_list.
Remarks: Returns a copy of the leftmost argument when several arguments are equivalent to the largest.
Complexity: Exactly t.size() - 1 comparisons.
template<class T> constexpr pair<const T&, const T&> minmax(const T& a, const T& b); template<class T, class Compare> constexpr pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp);
Requires: For the first form, type T shall be LessThanComparable (Table 21).
Returns: pair<const T&, const T&>(b, a) if b is smaller than a, and pair<const T&, const T&>(a, b) otherwise.
Remarks: Returns pair<const T&, const T&>(a, b) when the arguments are equivalent.
Complexity: Exactly one comparison.
template<class T> constexpr pair<T, T> minmax(initializer_list<T> t); template<class T, class Compare> constexpr pair<T, T> minmax(initializer_list<T> t, Compare comp);
Requires: T shall be CopyConstructible and t.size() > 0.
For the first form, type T shall be LessThanComparable.
Returns: pair<T, T>(x, y), where x has the smallest and y has the largest value in the initializer list.
Remarks: x is a copy of the leftmost argument when several arguments are equivalent to the smallest.
y is a copy of the rightmost argument when several arguments are equivalent to the largest.
Complexity: At most applications of the corresponding predicate.
template<class ForwardIterator> constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> ForwardIterator min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template<class ForwardIterator, class Compare> constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, Compare comp); template<class ExecutionPolicy, class ForwardIterator, class Compare> ForwardIterator min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp);
Returns: The first iterator i in the range [first, last) such that for every iterator j in the range [first, last) the following corresponding conditions hold: !(*j < *i) or comp(*j, *i) == false.
Returns last if first == last.
Complexity: Exactly applications of the corresponding comparisons.
template<class ForwardIterator> constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> ForwardIterator max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template<class ForwardIterator, class Compare> constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, Compare comp); template<class ExecutionPolicy, class ForwardIterator, class Compare> ForwardIterator max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp);
Returns: The first iterator i in the range [first, last) such that for every iterator j in the range [first, last) the following corresponding conditions hold: !(*i < *j) or comp(*i, *j) == false.
Returns last if first == last.
Complexity: Exactly applications of the corresponding comparisons.
template<class ForwardIterator> constexpr pair<ForwardIterator, ForwardIterator> minmax_element(ForwardIterator first, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> pair<ForwardIterator, ForwardIterator> minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template<class ForwardIterator, class Compare> constexpr pair<ForwardIterator, ForwardIterator> minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); template<class ExecutionPolicy, class ForwardIterator, class Compare> pair<ForwardIterator, ForwardIterator> minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp);
Returns: make_­pair(first, first) if [first, last) is empty, otherwise make_­pair(m, M), where m is the first iterator in [first, last) such that no iterator in the range refers to a smaller element, and where M is the last iterator266 in [first, last) such that no iterator in the range refers to a larger element.
Complexity: At most applications of the corresponding predicate, where N is last - first.
This behavior intentionally differs from max_­element().

28.7.9 Bounded value [alg.clamp]

template<class T> constexpr const T& clamp(const T& v, const T& lo, const T& hi); template<class T, class Compare> constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp);
Requires: The value of lo shall be no greater than hi.
For the first form, type T shall be LessThanComparable (Table 21).
Returns: lo if v is less than lo, hi if hi is less than v, otherwise v.
[Note
:
If NaN is avoided, T can be a floating-point type.
end note
]
Complexity: At most two comparisons.

28.7.10 Lexicographical comparison [alg.lex.comparison]

template<class InputIterator1, class InputIterator2> bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> bool lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class InputIterator1, class InputIterator2, class Compare> bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare> bool lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp);
Returns: true if the sequence of elements defined by the range [first1, last1) is lexicographically less than the sequence of elements defined by the range [first2, last2) and false otherwise.
Complexity: At most applications of the corresponding comparison.
Remarks: If two sequences have the same number of elements and their corresponding elements (if any) are equivalent, then neither sequence is lexicographically less than the other.
If one sequence is a prefix of the other, then the shorter sequence is lexicographically less than the longer sequence.
Otherwise, the lexicographical comparison of the sequences yields the same result as the comparison of the first corresponding pair of elements that are not equivalent.
[Example
:
The following sample implementation satisfies these requirements:
for ( ; first1 != last1 && first2 != last2 ; ++first1, (void) ++first2) {
  if (*first1 < *first2) return true;
  if (*first2 < *first1) return false;
}
return first1 == last1 && first2 != last2;
end example
]
[Note
:
An empty sequence is lexicographically less than any non-empty sequence, but not less than any empty sequence.
end note
]

28.7.11 Permutation generators [alg.permutation.generators]

template<class BidirectionalIterator> bool next_permutation(BidirectionalIterator first, BidirectionalIterator last); template<class BidirectionalIterator, class Compare> bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
Requires: BidirectionalIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
Effects: Takes a sequence defined by the range [first, last) and transforms it into the next permutation.
The next permutation is found by assuming that the set of all permutations is lexicographically sorted with respect to operator< or comp.
Returns: true if such a permutation exists.
Otherwise, it transforms the sequence into the smallest permutation, that is, the ascendingly sorted one, and returns false.
Complexity: At most (last - first) / 2 swaps.
template<class BidirectionalIterator> bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last); template<class BidirectionalIterator, class Compare> bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
Requires: BidirectionalIterator shall satisfy the requirements of ValueSwappable ([swappable.requirements]).
Effects: Takes a sequence defined by the range [first, last) and transforms it into the previous permutation.
The previous permutation is found by assuming that the set of all permutations is lexicographically sorted with respect to operator< or comp.
Returns: true if such a permutation exists.
Otherwise, it transforms the sequence into the largest permutation, that is, the descendingly sorted one, and returns false.
Complexity: At most (last - first) / 2 swaps.

28.8 C library algorithms [alg.c.library]

[Note
:
The header <cstdlib> ([cstdlib.syn]) declares the functions described in this subclause.
end note
]
void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, c-compare-pred* compar); void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, compare-pred* compar); void qsort(void* base, size_t nmemb, size_t size, c-compare-pred* compar); void qsort(void* base, size_t nmemb, size_t size, compare-pred* compar);
Effects: These functions have the semantics specified in the C standard library.
Remarks: The behavior is undefined unless the objects in the array pointed to by base are of trivial type.
Throws: Any exception thrown by compar() ([res.on.exception.handling]).
See also: ISO C 7.
22.
5.

29 Numerics library [numerics]

29.1 General [numerics.general]

This Clause describes components that C++ programs may use to perform seminumerical operations.
The following subclauses describe components for complex number types, random number generation, numeric (n-at-a-time) arrays, generalized numeric algorithms, and mathematical functions for floating-point types, as summarized in Table 96.
Table 96 — Numerics library summary
Subclause
Header(s)
Definitions
Requirements
Floating-point environment
<cfenv>
Complex numbers
<complex>
Random number generation
<random>
Numeric arrays
<valarray>
Generalized numeric operations
<numeric>
Mathematical functions for
<cmath>
floating-point types
<cstdlib>

29.2 Definitions [numerics.defns]

Define GENERALIZED_­NONCOMMUTATIVE_­SUM(op, a1, ..., aN) as follows:
  • a1 when N is 1, otherwise
  • op(GENERALIZED_­NONCOMMUTATIVE_­SUM(op, a1, ..., aK),
    op(GENERALIZED_­NONCOMMUTATIVE_­SUM(op, aM, ..., aN)) for any K where .
Define GENERALIZED_­SUM(op, a1, ..., aN) as GENERALIZED_­NONCOMMUTATIVE_­SUM(op, b1, ..., bN), where b1, ..., bN may be any permutation of a1, ..., aN.

29.3 Numeric type requirements [numeric.requirements]

The complex and valarray components are parameterized by the type of information they contain and manipulate.
A C++ program shall instantiate these components only with a type T that satisfies the following requirements:267
  • T is not an abstract class (it has no pure virtual member functions);
  • T is not a reference type;
  • T is not cv-qualified;
  • If T is a class, it has a public default constructor;
  • If T is a class, it has a public copy constructor with the signature T​::​T(const T&)
  • If T is a class, it has a public destructor;
  • If T is a class, it has a public assignment operator whose signature is either T& T​::​operator=(const T&) or T& T​::​operator=(T)
  • If T is a class, its assignment operator, copy and default constructors, and destructor shall correspond to each other in the following sense:
    • Initialization of raw storage using the copy constructor on the value of T(), however obtained, is semantically equivalent to value-initialization of the same raw storage.
    • Initialization of raw storage using the default constructor, followed by assignment, is semantically equivalent to initialization of raw storage using the copy constructor.
    • Destruction of an object, followed by initialization of its raw storage using the copy constructor, is semantically equivalent to assignment to the original object.
    [Note
    :
    This rule states, in part, that there shall not be any subtle differences in the semantics of initialization versus assignment.
    This gives an implementation considerable flexibility in how arrays are initialized.
    [Example
    :
    An implementation is allowed to initialize a valarray by allocating storage using the new operator (which implies a call to the default constructor for each element) and then assigning each element its value.
    Or the implementation can allocate raw storage and use the copy constructor to initialize each element.
    end example
    ]
    If the distinction between initialization and assignment is important for a class, or if it fails to satisfy any of the other conditions listed above, the programmer should use vector ([vector]) instead of valarray for that class.
    end note
    ]
  • If T is a class, it does not overload unary operator&.
If any operation on T throws an exception the effects are undefined.
In addition, many member and related functions of valarray<T> can be successfully instantiated and will exhibit well-defined behavior if and only if T satisfies additional requirements specified for each such member or related function.
[Example
:
It is valid to instantiate valarray<complex>, but operator>() will not be successfully instantiated for valarray<complex> operands, since complex does not have any ordering operators.
end example
]
In other words, value types.
These include arithmetic types, pointers, the library class complex, and instantiations of valarray for value types.

29.4 The floating-point environment [cfenv]

29.4.1 Header <cfenv> synopsis [cfenv.syn]

#define FE_ALL_EXCEPT see below
#define FE_DIVBYZERO see below
#define FE_INEXACT see below
#define FE_INVALID see below
#define FE_OVERFLOW see below
#define FE_UNDERFLOW see below

#define FE_DOWNWARD see below
#define FE_TONEAREST see below
#define FE_TOWARDZERO see below
#define FE_UPWARD see below

#define FE_DFL_ENV see below

namespace std {
  // types
  using fenv_t    = object type;
  using fexcept_t = integer type;

  // functions
  int feclearexcept(int except);
  int fegetexceptflag(fexcept_t* pflag, int except);
  int feraiseexcept(int except);
  int fesetexceptflag(const fexcept_t* pflag, int except);
  int fetestexcept(int except);

  int fegetround();
  int fesetround(int mode);

  int fegetenv(fenv_t* penv);
  int feholdexcept(fenv_t* penv);
  int fesetenv(const fenv_t* penv);
  int feupdateenv(const fenv_t* penv);
}
The contents and meaning of the header <cfenv> are the same as the C standard library header <fenv.h>.
[Note
:
This International Standard does not require an implementation to support the FENV_­ACCESS pragma; it is implementation-defined ([cpp.pragma]) whether the pragma is supported.
As a consequence, it is implementation-defined whether these functions can be used to test floating-point status flags, set floating-point control modes, or run under non-default mode settings.
If the pragma is used to enable control over the floating-point environment, this International Standard does not specify the effect on floating-point evaluation in constant expressions.
end note
]
The floating-point environment has thread storage duration ([basic.stc.thread]).
The initial state for a thread's floating-point environment is the state of the floating-point environment of the thread that constructs the corresponding thread object ([thread.thread.class]) at the time it constructed the object.
[Note
:
That is, the child thread gets the floating-point state of the parent thread at the time of the child's creation.
end note
]
A separate floating-point environment shall be maintained for each thread.
Each function accesses the environment corresponding to its calling thread.
See also: ISO C 7.
6

29.5 Complex numbers [complex.numbers]

The header <complex> defines a class template, and numerous functions for representing and manipulating complex numbers.
The effect of instantiating the template complex for any type other than float, double, or long double is unspecified.
The specializations complex<float>, complex<double>, and complex<long double> are literal types ([basic.types]).
If the result of a function is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
If z is an lvalue expression of type cv complex<T> then:
  • the expression reinterpret_­cast<cv T(&)[2]>(z) shall be well-formed,
  • reinterpret_­cast<cv T(&)[2]>(z)[0] shall designate the real part of z, and
  • reinterpret_­cast<cv T(&)[2]>(z)[1] shall designate the imaginary part of z.
Moreover, if a is an expression of type cv complex<T>* and the expression a[i] is well-defined for an integer expression i, then:
  • reinterpret_­cast<cv T*>(a)[2*i] shall designate the real part of a[i], and
  • reinterpret_­cast<cv T*>(a)[2*i + 1] shall designate the imaginary part of a[i].

29.5.1 Header <complex> synopsis [complex.syn]

namespace std {
  template<class T> class complex;
  template<> class complex<float>;
  template<> class complex<double>;
  template<> class complex<long double>;

  // [complex.ops], operators
  template<class T>
    complex<T> operator+(const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator+(const complex<T>&, const T&);
  template<class T> complex<T> operator+(const T&, const complex<T>&);

  template<class T> complex<T> operator-(
    const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&, const T&);
  template<class T> complex<T> operator-(const T&, const complex<T>&);

  template<class T> complex<T> operator*(
    const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator*(const complex<T>&, const T&);
  template<class T> complex<T> operator*(const T&, const complex<T>&);

  template<class T> complex<T> operator/(
    const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator/(const complex<T>&, const T&);
  template<class T> complex<T> operator/(const T&, const complex<T>&);

  template<class T> complex<T> operator+(const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&);

  template<class T> constexpr bool operator==(
    const complex<T>&, const complex<T>&);
  template<class T> constexpr bool operator==(const complex<T>&, const T&);
  template<class T> constexpr bool operator==(const T&, const complex<T>&);

  template<class T> constexpr bool operator!=(const complex<T>&, const complex<T>&);
  template<class T> constexpr bool operator!=(const complex<T>&, const T&);
  template<class T> constexpr bool operator!=(const T&, const complex<T>&);

  template<class T, class charT, class traits>
  basic_istream<charT, traits>&
  operator>>(basic_istream<charT, traits>&, complex<T>&);

  template<class T, class charT, class traits>
  basic_ostream<charT, traits>&
  operator<<(basic_ostream<charT, traits>&, const complex<T>&);

  // [complex.value.ops], values
  template<class T> constexpr T real(const complex<T>&);
  template<class T> constexpr T imag(const complex<T>&);

  template<class T> T abs(const complex<T>&);
  template<class T> T arg(const complex<T>&);
  template<class T> T norm(const complex<T>&);

  template<class T> complex<T> conj(const complex<T>&);
  template<class T> complex<T> proj(const complex<T>&);
  template<class T> complex<T> polar(const T&, const T& = 0);

  // [complex.transcendentals], transcendentals
  template<class T> complex<T> acos(const complex<T>&);
  template<class T> complex<T> asin(const complex<T>&);
  template<class T> complex<T> atan(const complex<T>&);

  template<class T> complex<T> acosh(const complex<T>&);
  template<class T> complex<T> asinh(const complex<T>&);
  template<class T> complex<T> atanh(const complex<T>&);

  template<class T> complex<T> cos  (const complex<T>&);
  template<class T> complex<T> cosh (const complex<T>&);
  template<class T> complex<T> exp  (const complex<T>&);
  template<class T> complex<T> log  (const complex<T>&);
  template<class T> complex<T> log10(const complex<T>&);

  template<class T> complex<T> pow  (const complex<T>&, const T&);
  template<class T> complex<T> pow  (const complex<T>&, const complex<T>&);
  template<class T> complex<T> pow  (const T&, const complex<T>&);

  template<class T> complex<T> sin  (const complex<T>&);
  template<class T> complex<T> sinh (const complex<T>&);
  template<class T> complex<T> sqrt (const complex<T>&);
  template<class T> complex<T> tan  (const complex<T>&);
  template<class T> complex<T> tanh (const complex<T>&);

  // [complex.literals], complex literals
  inline namespace literals {
    inline namespace complex_literals {
      constexpr complex<long double> operator""il(long double);
      constexpr complex<long double> operator""il(unsigned long long);
      constexpr complex<double> operator""i(long double);
      constexpr complex<double> operator""i(unsigned long long);
      constexpr complex<float> operator""if(long double);
      constexpr complex<float> operator""if(unsigned long long);
    }
  }
}

29.5.2 Class template complex [complex]

namespace std {
  template<class T>
  class complex {
  public:
    using value_type = T;

    constexpr complex(const T& re = T(), const T& im = T());
    constexpr complex(const complex&);
    template<class X> constexpr complex(const complex<X>&);

    constexpr T real() const;
    void real(T);
    constexpr T imag() const;
    void imag(T);

    complex<T>& operator= (const T&);
    complex<T>& operator+=(const T&);
    complex<T>& operator-=(const T&);
    complex<T>& operator*=(const T&);
    complex<T>& operator/=(const T&);

    complex& operator=(const complex&);
    template<class X> complex<T>& operator= (const complex<X>&);
    template<class X> complex<T>& operator+=(const complex<X>&);
    template<class X> complex<T>& operator-=(const complex<X>&);
    template<class X> complex<T>& operator*=(const complex<X>&);
    template<class X> complex<T>& operator/=(const complex<X>&);
  };
}
The class complex describes an object that can store the Cartesian components, real() and imag(), of a complex number.

29.5.3 complex specializations [complex.special]

namespace std {
  template<> class complex<float> {
  public:
    using value_type = float;

    constexpr complex(float re = 0.0f, float im = 0.0f);
    constexpr explicit complex(const complex<double>&);
    constexpr explicit complex(const complex<long double>&);

    constexpr float real() const;
    void real(float);
    constexpr float imag() const;
    void imag(float);

    complex<float>& operator= (float);
    complex<float>& operator+=(float);
    complex<float>& operator-=(float);
    complex<float>& operator*=(float);
    complex<float>& operator/=(float);

    complex<float>& operator=(const complex<float>&);
    template<class X> complex<float>& operator= (const complex<X>&);
    template<class X> complex<float>& operator+=(const complex<X>&);
    template<class X> complex<float>& operator-=(const complex<X>&);
    template<class X> complex<float>& operator*=(const complex<X>&);
    template<class X> complex<float>& operator/=(const complex<X>&);
  };

  template<> class complex<double> {
  public:
    using value_type = double;

    constexpr complex(double re = 0.0, double im = 0.0);
    constexpr complex(const complex<float>&);
    constexpr explicit complex(const complex<long double>&);

    constexpr double real() const;
    void real(double);
    constexpr double imag() const;
    void imag(double);

    complex<double>& operator= (double);
    complex<double>& operator+=(double);
    complex<double>& operator-=(double);
    complex<double>& operator*=(double);
    complex<double>& operator/=(double);

    complex<double>& operator=(const complex<double>&);
    template<class X> complex<double>& operator= (const complex<X>&);
    template<class X> complex<double>& operator+=(const complex<X>&);
    template<class X> complex<double>& operator-=(const complex<X>&);
    template<class X> complex<double>& operator*=(const complex<X>&);
    template<class X> complex<double>& operator/=(const complex<X>&);
  };

  template<> class complex<long double> {
  public:
    using value_type = long double;

    constexpr complex(long double re = 0.0L, long double im = 0.0L);
    constexpr complex(const complex<float>&);
    constexpr complex(const complex<double>&);

    constexpr long double real() const;
    void real(long double);
    constexpr long double imag() const;
    void imag(long double);

    complex<long double>& operator=(const complex<long double>&);
    complex<long double>& operator= (long double);
    complex<long double>& operator+=(long double);
    complex<long double>& operator-=(long double);
    complex<long double>& operator*=(long double);
    complex<long double>& operator/=(long double);

    template<class X> complex<long double>& operator= (const complex<X>&);
    template<class X> complex<long double>& operator+=(const complex<X>&);
    template<class X> complex<long double>& operator-=(const complex<X>&);
    template<class X> complex<long double>& operator*=(const complex<X>&);
    template<class X> complex<long double>& operator/=(const complex<X>&);
  };
}

29.5.4 complex member functions [complex.members]

template<class T> constexpr complex(const T& re = T(), const T& im = T());
Effects: Constructs an object of class complex.
Postconditions: real() == re && imag() == im.
constexpr T real() const;
Returns: The value of the real component.
void real(T val);
Effects: Assigns val to the real component.
constexpr T imag() const;
Returns: The value of the imaginary component.
void imag(T val);
Effects: Assigns val to the imaginary component.

29.5.5 complex member operators [complex.member.ops]

complex<T>& operator+=(const T& rhs);
Effects: Adds the scalar value rhs to the real part of the complex value *this and stores the result in the real part of *this, leaving the imaginary part unchanged.
Returns: *this.
complex<T>& operator-=(const T& rhs);
Effects: Subtracts the scalar value rhs from the real part of the complex value *this and stores the result in the real part of *this, leaving the imaginary part unchanged.
Returns: *this.
complex<T>& operator*=(const T& rhs);
Effects: Multiplies the scalar value rhs by the complex value *this and stores the result in *this.
Returns: *this.
complex<T>& operator/=(const T& rhs);
Effects: Divides the scalar value rhs into the complex value *this and stores the result in *this.
Returns: *this.
template<class X> complex<T>& operator+=(const complex<X>& rhs);
Effects: Adds the complex value rhs to the complex value *this and stores the sum in *this.
Returns: *this.
template<class X> complex<T>& operator-=(const complex<X>& rhs);
Effects: Subtracts the complex value rhs from the complex value *this and stores the difference in *this.
Returns: *this.
template<class X> complex<T>& operator*=(const complex<X>& rhs);
Effects: Multiplies the complex value rhs by the complex value *this and stores the product in *this.
Returns: *this.
template<class X> complex<T>& operator/=(const complex<X>& rhs);
Effects: Divides the complex value rhs into the complex value *this and stores the quotient in *this.
Returns: *this.

29.5.6 complex non-member operations [complex.ops]

template<class T> complex<T> operator+(const complex<T>& lhs);
Returns: complex<T>(lhs).
Remarks: unary operator.
template<class T> complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator+(const complex<T>& lhs, const T& rhs); template<class T> complex<T> operator+(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) += rhs.
template<class T> complex<T> operator-(const complex<T>& lhs);
Returns: complex<T>(-lhs.real(),-lhs.imag()).
Remarks: unary operator.
template<class T> complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator-(const complex<T>& lhs, const T& rhs); template<class T> complex<T> operator-(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) -= rhs.
template<class T> complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator*(const complex<T>& lhs, const T& rhs); template<class T> complex<T> operator*(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) *= rhs.
template<class T> complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator/(const complex<T>& lhs, const T& rhs); template<class T> complex<T> operator/(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) /= rhs.
template<class T> constexpr bool operator==(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr bool operator==(const complex<T>& lhs, const T& rhs); template<class T> constexpr bool operator==(const T& lhs, const complex<T>& rhs);
Returns: lhs.real() == rhs.real() && lhs.imag() == rhs.imag().
Remarks: The imaginary part is assumed to be T(), or 0.
0, for the T arguments.
template<class T> constexpr bool operator!=(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr bool operator!=(const complex<T>& lhs, const T& rhs); template<class T> constexpr bool operator!=(const T& lhs, const complex<T>& rhs);
Returns: rhs.real() != lhs.real() || rhs.imag() != lhs.imag().
template<class T, class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, complex<T>& x);
Requires: The input values shall be convertible to T.
Effects: Extracts a complex number x of the form: u, (u), or (u,v), where u is the real part and v is the imaginary part ([istream.formatted]).
If bad input is encountered, calls is.setstate(ios_­base​::​failbit) (which may throw ios​::​failure ([iostate.flags])).
Returns: is.
Remarks: This extraction is performed as a series of simpler extractions.
Therefore, the skipping of whitespace is specified to be the same for each of the simpler extractions.
template<class T, class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);
Effects: Inserts the complex number x onto the stream o as if it were implemented as follows:
basic_ostringstream<charT, traits> s;
s.flags(o.flags());
s.imbue(o.getloc());
s.precision(o.precision());
s << '(' << x.real() << "," << x.imag() << ')';
return o << s.str();
[Note
:
In a locale in which comma is used as a decimal point character, the use of comma as a field separator can be ambiguous.
Inserting showpoint into the output stream forces all outputs to show an explicit decimal point character; as a result, all inserted sequences of complex numbers can be extracted unambiguously.
end note
]

29.5.7 complex value operations [complex.value.ops]

template<class T> constexpr T real(const complex<T>& x);
Returns: x.real().
template<class T> constexpr T imag(const complex<T>& x);
Returns: x.imag().
template<class T> T abs(const complex<T>& x);
Returns: The magnitude of x.
template<class T> T arg(const complex<T>& x);
Returns: The phase angle of x, or atan2(imag(x), real(x)).
template<class T> T norm(const complex<T>& x);
Returns: The squared magnitude of x.
template<class T> complex<T> conj(const complex<T>& x);
Returns: The complex conjugate of x.
template<class T> complex<T> proj(const complex<T>& x);
Returns: The projection of x onto the Riemann sphere.
Remarks: Behaves the same as the C function cproj, defined in 7.
3.
9.
4.
template<class T> complex<T> polar(const T& rho, const T& theta = 0);
Requires: rho shall be non-negative and non-NaN.
theta shall be finite.
Returns: The complex value corresponding to a complex number whose magnitude is rho and whose phase angle is theta.

29.5.8 complex transcendentals [complex.transcendentals]

template<class T> complex<T> acos(const complex<T>& x);
Returns: The complex arc cosine of x.
Remarks: Behaves the same as C function cacos, defined in 7.
3.
5.
1.
template<class T> complex<T> asin(const complex<T>& x);
Returns: The complex arc sine of x.
Remarks: Behaves the same as C function casin, defined in 7.
3.
5.
2.
template<class T> complex<T> atan(const complex<T>& x);
Returns: The complex arc tangent of x.
Remarks: Behaves the same as C function catan, defined in 7.
3.
5.
3.
template<class T> complex<T> acosh(const complex<T>& x);
Returns: The complex arc hyperbolic cosine of x.
Remarks: Behaves the same as C function cacosh, defined in 7.
3.
6.
1.
template<class T> complex<T> asinh(const complex<T>& x);
Returns: The complex arc hyperbolic sine of x.
Remarks: Behaves the same as C function casinh, defined in 7.
3.
6.
2.
template<class T> complex<T> atanh(const complex<T>& x);
Returns: The complex arc hyperbolic tangent of x.
Remarks: Behaves the same as C function catanh, defined in 7.
3.
6.
3.
template<class T> complex<T> cos(const complex<T>& x);
Returns: The complex cosine of x.
template<class T> complex<T> cosh(const complex<T>& x);
Returns: The complex hyperbolic cosine of x.
template<class T> complex<T> exp(const complex<T>& x);
Returns: The complex base-e exponential of x.
template<class T> complex<T> log(const complex<T>& x);
Returns: The complex natural (base-e) logarithm of x.
For all x, imag(log(x)) lies in the interval [, π], and when x is a negative real number, imag(log(x)) is π.
Remarks: The branch cuts are along the negative real axis.
template<class T> complex<T> log10(const complex<T>& x);
Returns: The complex common (base-10) logarithm of x, defined as log(x) / log(10).
Remarks: The branch cuts are along the negative real axis.
template<class T> complex<T> pow(const complex<T>& x, const complex<T>& y); template<class T> complex<T> pow(const complex<T>& x, const T& y); template<class T> complex<T> pow(const T& x, const complex<T>& y);
Returns: The complex power of base x raised to the y power, defined as exp(y * log(x)).
The value returned for pow(0, 0) is implementation-defined.
Remarks: The branch cuts are along the negative real axis.
template<class T> complex<T> sin(const complex<T>& x);
Returns: The complex sine of x.
template<class T> complex<T> sinh(const complex<T>& x);
Returns: The complex hyperbolic sine of x.
template<class T> complex<T> sqrt(const complex<T>& x);
Returns: The complex square root of x, in the range of the right half-plane.
If the argument is a negative real number, the value returned lies on the positive imaginary axis.
Remarks: The branch cuts are along the negative real axis.
template<class T> complex<T> tan(const complex<T>& x);
Returns: The complex tangent of x.
template<class T> complex<T> tanh(const complex<T>& x);
Returns: The complex hyperbolic tangent of x.

29.5.9 Additional overloads [cmplx.over]

The following function templates shall have additional overloads:
arg                   norm
conj                  proj
imag                  real
The additional overloads shall be sufficient to ensure:
  1. 1.
    If the argument has type long double, then it is effectively cast to complex<long double>.
  2. 2.
    Otherwise, if the argument has type double or an integer type, then it is effectively cast to complex<​double>.
  3. 3.
    Otherwise, if the argument has type float, then it is effectively cast to complex<float>.
Function template pow shall have additional overloads sufficient to ensure, for a call with at least one argument of type complex<T>:
  1. 1.
    If either argument has type complex<long double> or type long double, then both arguments are effectively cast to complex<long double>.
  2. 2.
    Otherwise, if either argument has type complex<double>, double, or an integer type, then both arguments are effectively cast to complex<double>.
  3. 3.
    Otherwise, if either argument has type complex<float> or float, then both arguments are effectively cast to complex<float>.

29.5.10 Suffixes for complex number literals [complex.literals]

This section describes literal suffixes for constructing complex number literals.
The suffixes i, il, and if create complex numbers of the types complex<double>, complex<long double>, and complex<float> respectively, with their imaginary part denoted by the given literal number and the real part being zero.
constexpr complex<long double> operator""il(long double d); constexpr complex<long double> operator""il(unsigned long long d);
Returns: complex<long double>{0.0L, static_­cast<long double>(d)}.
constexpr complex<double> operator""i(long double d); constexpr complex<double> operator""i(unsigned long long d);
Returns: complex<double>{0.0, static_­cast<double>(d)}.
constexpr complex<float> operator""if(long double d); constexpr complex<float> operator""if(unsigned long long d);
Returns: complex<float>{0.0f, static_­cast<float>(d)}.

29.6 Random number generation [rand]

This subclause defines a facility for generating (pseudo-)random numbers.
In addition to a few utilities, four categories of entities are described: uniform random bit generators, random number engines, random number engine adaptors, and random number distributions.
These categorizations are applicable to types that satisfy the corresponding requirements, to objects instantiated from such types, and to templates producing such types when instantiated.
[Note
:
These entities are specified in such a way as to permit the binding of any uniform random bit generator object e as the argument to any random number distribution object d, thus producing a zero-argument function object such as given by bind(d,e).
end note
]
Each of the entities specified via this subclause has an associated arithmetic type ([basic.fundamental]) identified as result_­type.
With T as the result_­type thus associated with such an entity, that entity is characterized:
  1. a)
    as boolean or equivalently as boolean-valued, if T is bool;
  2. b)
    otherwise as integral or equivalently as integer-valued, if numeric_­limits<T>​::​is_­integer is true;
  3. c)
    otherwise as floating or equivalently as real-valued.
If integer-valued, an entity may optionally be further characterized as signed or unsigned, according to numericlimits<T>​::​issigned.
Unless otherwise specified, all descriptions of calculations in this subclause use mathematical real numbers.
Throughout this subclause, the operators bitand , bitor , and xor denote the respective conventional bitwise operations.
Further:
  1. a)
    the operator rshift denotes a bitwise right shift with zero-valued bits appearing in the high bits of the result, and
  2. b)
    the operator denotes a bitwise left shift with zero-valued bits appearing in the low bits of the result, and whose result is always taken modulo .

29.6.1 Requirements [rand.req]

29.6.1.1 General requirements [rand.req.genl]

Throughout this subclause [rand], the effect of instantiating a template:
  1. a)
    that has a template type parameter named Sseq is undefined unless the corresponding template argument is cv-unqualified and satisfies the requirements of seed sequence ([rand.req.seedseq]).
  2. b)
    that has a template type parameter named URBG is undefined unless the corresponding template argument is cv-unqualified and satisfies the requirements of uniform random bit generator ([rand.req.urng]).
  3. c)
    that has a template type parameter named Engine is undefined unless the corresponding template argument is cv-unqualified and satisfies the requirements of random number engine ([rand.req.eng]).
  4. d)
    that has a template type parameter named RealType is undefined unless the corresponding template argument is cv-unqualified and is one of float, double, or long double.
  5. e)
    that has a template type parameter named IntType is undefined unless the corresponding template argument is cv-unqualified and is one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long.
  6. f)
    that has a template type parameter named UIntType is undefined unless the corresponding template argument is cv-unqualified and is one of unsigned short, unsigned int, unsigned long, or unsigned long long.
Throughout this subclause [rand], phrases of the form “x is an iterator of a specific kind” shall be interpreted as equivalent to the more formal requirement that “x is a value of a type satisfying the requirements of the specified iterator type”.
Throughout this subclause [rand], any constructor that can be called with a single argument and that satisfies a requirement specified in this subclause shall be declared explicit.

29.6.1.2 Seed sequence requirements [rand.req.seedseq]

A seed sequence is an object that consumes a sequence of integer-valued data and produces a requested number of unsigned integer values i, , based on the consumed data.
[Note
:
Such an object provides a mechanism to avoid replication of streams of random variates.
This can be useful, for example, in applications requiring large numbers of random number engines.
end note
]
A class S satisfies the requirements of a seed sequence if the expressions shown in Table 97 are valid and have the indicated semantics, and if S also satisfies all other requirements of this section [rand.req.seedseq].
In that Table and throughout this section:
  1. a)
    T is the type named by S's associated result_­type;
  2. b)
    q is a value of S and r is a possibly const value of S;
  3. c)
    ib and ie are input iterators with an unsigned integer value_­type of at least 32 bits;
  4. d)
    rb and re are mutable random access iterators with an unsigned integer value_­type of at least 32 bits;
  5. e)
    ob is an output iterator; and
  6. f)
    il is a value of initializer_­list<T>.
Table 97 — Seed sequence requirements
Expression
Return type
Pre/post-condition
Complexity
S​::​result_­type
T
T is an unsigned integer type ([basic.fundamental]) of at least 32 bits.
compile-time
S()
Creates a seed sequence with the same initial state as all other default-constructed seed sequences of type S.
constant
S(ib,ie)
Creates a seed sequence having internal state that depends on some or all of the bits of the supplied sequence .
S(il)
Same as S(il.begin(), il.end()).
same as S(il.begin(), il.end())
q.generate(rb,re)
void
Does nothing if rb == re.
Otherwise, fills the supplied sequence with 32-bit quantities that depend on the sequence supplied to the constructor and possibly also depend on the history of generate's previous invocations.
r.size()
size_­t
The number of 32-bit units that would be copied by a call to r.param.
constant
r.param(ob)
void
Copies to the given destination a sequence of 32-bit units that can be provided to the constructor of a second object of type S, and that would reproduce in that second object a state indistinguishable from the state of the first object.

29.6.1.3 Uniform random bit generator requirements [rand.req.urng]

A uniform random bit generator g of type G is a function object returning unsigned integer values such that each value in the range of possible results has (ideally) equal probability of being returned.
[Note
:
The degree to which g's results approximate the ideal is often determined statistically.
end note
]
A class G satisfies the requirements of a uniform random bit generator if the expressions shown in Table 98 are valid and have the indicated semantics, and if G also satisfies all other requirements of this section [rand.req.urng].
In that Table and throughout this section:
  1. a)
    T is the type named by G's associated result_­type, and
  2. b)
    g is a value of G.
Table 98 — Uniform random bit generator requirements
Expression
Return type
Pre/post-condition
Complexity
G​::​result_­type
T
T is an unsigned integer type ([basic.fundamental]).
compile-time
g()
T
Returns a value in the closed interval [G​::​min(), G​::​max()].
amortized constant
G​::​min()
T
Denotes the least value potentially returned by operator().
compile-time
G​::​max()
T
Denotes the greatest value potentially returned by operator().
compile-time
The following relation shall hold: G​::​min() < G​::​max().

29.6.1.4 Random number engine requirements [rand.req.eng]

A random number engine (commonly shortened to engine) e of type E is a uniform random bit generator that additionally meets the requirements (e.g., for seeding and for input/output) specified in this section.
At any given time, e has a state e for some integer .
Upon construction, e has an initial state e.
An engine's state may be established via a constructor, a seed function, assignment, or a suitable operator>>.
E's specification shall define:
  1. a)
    the size of E's state in multiples of the size of result_­type, given as an integral constant expression;
  2. b)
    the transition algorithm TA by which e's state e is advanced to its successor state e; and
  3. c)
    the generation algorithm GA by which an engine's state is mapped to a value of type result_­type.
A class E that satisfies the requirements of a uniform random bit generator ([rand.req.urng]) also satisfies the requirements of a random number engine if the expressions shown in Table 99 are valid and have the indicated semantics, and if E also satisfies all other requirements of this section [rand.req.eng].
In that Table and throughout this section:
  1. a)
    T is the type named by E's associated result_­type;
  2. b)
    e is a value of E, v is an lvalue of E, x and y are (possibly const) values of E;
  3. c)
    s is a value of T;
  4. d)
    q is an lvalue satisfying the requirements of a seed sequence ([rand.req.seedseq]);
  5. e)
    z is a value of type unsigned long long;
  6. f)
    os is an lvalue of the type of some class template specialization basic_­ostream<charT, traits>; and
  7. g)
    is is an lvalue of the type of some class template specialization basic_­istream<charT, traits>;
where charT and traits are constrained according to Clause [strings] and Clause [input.output].
Table 99 — Random number engine requirements
Expression
Return type
Pre/post-condition
Complexity
E()
Creates an engine with the same initial state as all other default-constructed engines of type E.
E(x)
Creates an engine that compares equal to x.
E(s)
Creates an engine with initial state determined by s.
E(q)268
Creates an engine with an initial state that depends on a sequence produced by one call to q.generate.
same as complexity of q.generate called on a sequence whose length is size of state
e.seed()
void
Postconditions: e == E().
same as E()
e.seed(s)
void
Postconditions: e == E(s).
same as E(s)
e.seed(q)
void
Postconditions: e == E(q).
same as E(q)
e()
T
Advances e's state e to e e) and returns GA(e).
per Table 98
e.discard(z) 269
void
Advances e's state e to by any means equivalent to z consecutive calls e().
no worse than the complexity of z consecutive calls e()
x == y
bool
This operator is an equivalence relation.
With and as the infinite sequences of values that would be generated by repeated future calls to x() and y(), respectively, returns true if ; else returns false.
x != y
bool
!(x == y).
os << x
reference to the type of os
With os.fmtflags set to ios_­base​::​dec|ios_­base​::​left and the fill character set to the space character, writes to os the textual representation of x's current state.
In the output, adjacent numbers are separated by one or more space characters.
Postconditions: The os.fmtflags and fill character are unchanged.
is >> v
reference to the type of is
With is.fmtflags set to ios_­base​::​dec, sets v's state as determined by reading its textual representation from is.
If bad input is encountered, ensures that v's state is unchanged by the operation and calls is.setstate(ios​::​failbit) (which may throw ios​::​failure ([iostate.flags])).
If a textual representation written via os << x was subsequently read via is >> v, then x == v provided that there have been no intervening invocations of x or of v.
Requires: is provides a textual representation that was previously written using an output stream whose imbued locale was the same as that of is, and whose type's template specialization arguments charT and traits were respectively the same as those of is.
Postconditions: The is.fmtflags are unchanged.
E shall meet the requirements of CopyConstructible (Table 24) and CopyAssignable (Table 26) types.
These operations shall each be of complexity no worse than .
This constructor (as well as the subsequent corresponding seed() function) may be particularly useful to applications requiring a large number of independent random sequences.
This operation is common in user code, and can often be implemented in an engine-specific manner so as to provide significant performance improvements over an equivalent naive loop that makes z consecutive calls e().

29.6.1.5 Random number engine adaptor requirements [rand.req.adapt]

A random number engine adaptor (commonly shortened to adaptor) a of type A is a random number engine that takes values produced by some other random number engine, and applies an algorithm to those values in order to deliver a sequence of values with different randomness properties.
An engine b of type B adapted in this way is termed a base engine in this context.
The expression a.base() shall be valid and shall return a const reference to a's base engine.
The requirements of a random number engine type shall be interpreted as follows with respect to a random number engine adaptor type.
A::A();
Effects: The base engine is initialized as if by its default constructor.
bool operator==(const A& a1, const A& a2);
Returns: true if a1's base engine is equal to a2's base engine.
Otherwise returns false.
A::A(result_type s);
Effects: The base engine is initialized with s.
template<class Sseq> A::A(Sseq& q);
Effects: The base engine is initialized with q.
void seed();
Effects: With b as the base engine, invokes b.seed().
void seed(result_type s);
Effects: With b as the base engine, invokes b.seed(s).
template<class Sseq> void seed(Sseq& q);
Effects: With b as the base engine, invokes b.seed(q).
A shall also satisfy the following additional requirements:
  1. a)
    The complexity of each function shall not exceed the complexity of the corresponding function applied to the base engine.
  2. b)
    The state of A shall include the state of its base engine.
    The size of A's state shall be no less than the size of the base engine.
  3. c)
    Copying A's state (e.g., during copy construction or copy assignment) shall include copying the state of the base engine of A.
  4. d)
    The textual representation of A shall include the textual representation of its base engine.

29.6.1.6 Random number distribution requirements [rand.req.dist]

A random number distribution (commonly shortened to distribution) d of type D is a function object returning values that are distributed according to an associated mathematical probability density function p(z) or according to an associated discrete probability function .
A distribution's specification identifies its associated probability function p(z) or .
An associated probability function is typically expressed using certain externally-supplied quantities known as the parameters of the distribution.
Such distribution parameters are identified in this context by writing, for example, or , to name specific parameters, or by writing, for example, p(z|{p}) or , to denote a distribution's parameters p taken as a whole.
A class D satisfies the requirements of a random number distribution if the expressions shown in Table 100 are valid and have the indicated semantics, and if D and its associated types also satisfy all other requirements of this section [rand.req.dist].
In that Table and throughout this section,
  1. a)
    T is the type named by D's associated result_­type;
  2. b)
    P is the type named by D's associated param_­type;
  3. c)
    d is a value of D, and x and y are (possibly const) values of D;
  4. d)
    glb and lub are values of T respectively corresponding to the greatest lower bound and the least upper bound on the values potentially returned by d's operator(), as determined by the current values of d's parameters;
  5. e)
    p is a (possibly const) value of P;
  6. f)
    g, g1, and g2 are lvalues of a type satisfying the requirements of a uniform random bit generator ([rand.req.urng]);
  7. g)
    os is an lvalue of the type of some class template specialization basic_­ostream<charT, traits>; and
  8. h)
    is is an lvalue of the type of some class template specialization basic_­istream<charT, traits>;
where charT and traits are constrained according to Clauses [strings] and [input.output].
Table 100 — Random number distribution requirements
Expression
Return type
Pre/post-condition
Complexity
D​::​result_­type
T
T is an arithmetic type ([basic.fundamental]).
compile-time
D​::​param_­type
P
compile-time
D()
Creates a distribution whose behavior is indistinguishable from that of any other newly default-constructed distribution of type D.
constant
D(p)
Creates a distribution whose behavior is indistinguishable from that of a distribution newly constructed directly from the values used to construct p.
same as p's construction
d.reset()
void
Subsequent uses of d do not depend on values produced by any engine prior to invoking reset.
constant
x.param()
P
Returns a value p such that D(p).param() == p.
no worse than the complexity of D(p)
d.param(p)
void
Postconditions: d.param() == p.
no worse than the complexity of D(p)
d(g)
T
With , the sequence of numbers returned by successive invocations with the same object g is randomly distributed according to the associated p(z|{p}) or function.
amortized constant number of invocations of g
d(g,p)
T
The sequence of numbers returned by successive invocations with the same objects g and p is randomly distributed according to the associated p(z|{p}) or function.
amortized constant number of invocations of g
x.min()
T
Returns glb.
constant
x.max()
T
Returns lub.
constant
x == y
bool
This operator is an equivalence relation.
Returns true if x.param() == y.param() and , where and are the infinite sequences of values that would be generated, respectively, by repeated future calls to x(g1) and y(g2) whenever g1 == g2.
Otherwise returns false.
constant
x != y
bool
!(x == y).
same as x == y.
os << x
reference to the type of os
Writes to os a textual representation for the parameters and the additional internal data of x.
Postconditions: The os.fmtflags and fill character are unchanged.
is >> d
reference to the type of is
Restores from is the parameters and additional internal data of the lvalue d.
If bad input is encountered, ensures that d is unchanged by the operation and calls is.setstate(ios​::​failbit) (which may throw ios​::​failure ([iostate.flags])).
Requires: is provides a textual representation that was previously written using an os whose imbued locale and whose type's template specialization arguments charT and traits were the same as those of is.
Postconditions: The is.fmtflags are unchanged.
D shall satisfy the requirements of CopyConstructible (Table 24) and CopyAssignable (Table 26) types.
The sequence of numbers produced by repeated invocations of d(g) shall be independent of any invocation of os << d or of any const member function of D between any of the invocations d(g).
If a textual representation is written using os << x and that representation is restored into the same or a different object y of the same type using is >> y, repeated invocations of y(g) shall produce the same sequence of numbers as would repeated invocations of x(g).
It is unspecified whether D​::​param_­type is declared as a (nested) class or via a typedef.
In this subclause [rand], declarations of D​::​param_­type are in the form of typedefs for convenience of exposition only.
P shall satisfy the requirements of CopyConstructible (Table 24), CopyAssignable (Table 26), and EqualityComparable (Table 20) types.
For each of the constructors of D taking arguments corresponding to parameters of the distribution, P shall have a corresponding constructor subject to the same requirements and taking arguments identical in number, type, and default values.
Moreover, for each of the member functions of D that return values corresponding to parameters of the distribution, P shall have a corresponding member function with the identical name, type, and semantics.
P shall have a declaration of the form
using distribution_type =  D;

29.6.2 Header <random> synopsis [rand.synopsis]

#include <initializer_list>

namespace std {
  // [rand.eng.lcong], class template linear_­congruential_­engine
  template<class UIntType, UIntType a, UIntType c, UIntType m>
    class linear_congruential_engine;

  // [rand.eng.mers], class template mersenne_­twister_­engine
  template<class UIntType, size_t w, size_t n, size_t m, size_t r,
           UIntType a, size_t u, UIntType d, size_t s,
           UIntType b, size_t t,
           UIntType c, size_t l, UIntType f>
    class mersenne_twister_engine;

  // [rand.eng.sub], class template subtract_­with_­carry_­engine
  template<class UIntType, size_t w, size_t s, size_t r>
    class subtract_with_carry_engine;

  // [rand.adapt.disc], class template discard_­block_­engine
  template<class Engine, size_t p, size_t r>
    class discard_block_engine;

  // [rand.adapt.ibits], class template independent_­bits_­engine
  template<class Engine, size_t w, class UIntType>
    class independent_bits_engine;

  // [rand.adapt.shuf], class template shuffle_­order_­engine
  template<class Engine, size_t k>
    class shuffle_order_engine;

  // [rand.predef], engines and engine adaptors with predefined parameters
  using minstd_rand0  = see below;
  using minstd_rand   = see below;
  using mt19937       = see below;
  using mt19937_64    = see below;
  using ranlux24_base = see below;
  using ranlux48_base = see below;
  using ranlux24      = see below;
  using ranlux48      = see below;
  using knuth_b       = see below;

  using default_random_engine = see below;

  // [rand.device], class random_­device
  class random_device;

  // [rand.util.seedseq], class seed_­seq
  class seed_seq;

  // [rand.util.canonical], function template generate_­canonical
  template<class RealType, size_t bits, class URBG>
    RealType generate_canonical(URBG& g);

  // [rand.dist.uni.int], class template uniform_­int_­distribution
  template<class IntType = int>
    class uniform_int_distribution;

  // [rand.dist.uni.real], class template uniform_­real_­distribution
  template<class RealType = double>
    class uniform_real_distribution;

  // [rand.dist.bern.bernoulli], class bernoulli_­distribution
  class bernoulli_distribution;

  // [rand.dist.bern.bin], class template binomial_­distribution
  template<class IntType = int>
    class binomial_distribution;

  // [rand.dist.bern.geo], class template geometric_­distribution
  template<class IntType = int>
    class geometric_distribution;

  // [rand.dist.bern.negbin], class template negative_­binomial_­distribution
  template<class IntType = int>
    class negative_binomial_distribution;

  // [rand.dist.pois.poisson], class template poisson_­distribution
  template<class IntType = int>
    class poisson_distribution;

  // [rand.dist.pois.exp], class template exponential_­distribution
  template<class RealType = double>
    class exponential_distribution;

  // [rand.dist.pois.gamma], class template gamma_­distribution
  template<class RealType = double>
    class gamma_distribution;

  // [rand.dist.pois.weibull], class template weibull_­distribution
  template<class RealType = double>
    class weibull_distribution;

  // [rand.dist.pois.extreme], class template extreme_­value_­distribution
  template<class RealType = double>
    class extreme_value_distribution;

  // [rand.dist.norm.normal], class template normal_­distribution
  template<class RealType = double>
    class normal_distribution;

  // [rand.dist.norm.lognormal], class template lognormal_­distribution
  template<class RealType = double>
    class lognormal_distribution;

  // [rand.dist.norm.chisq], class template chi_­squared_­distribution
  template<class RealType = double>
    class chi_squared_distribution;

  // [rand.dist.norm.cauchy], class template cauchy_­distribution
  template<class RealType = double>
    class cauchy_distribution;

  // [rand.dist.norm.f], class template fisher_­f_­distribution
  template<class RealType = double>
    class fisher_f_distribution;

  // [rand.dist.norm.t], class template student_­t_­distribution
  template<class RealType = double>
    class student_t_distribution;

  // [rand.dist.samp.discrete], class template discrete_­distribution
  template<class IntType = int>
    class discrete_distribution;

  // [rand.dist.samp.pconst], class template piecewise_­constant_­distribution
  template<class RealType = double>
    class piecewise_constant_distribution;

  // [rand.dist.samp.plinear], class template piecewise_­linear_­distribution
  template<class RealType = double>
    class piecewise_linear_distribution;
}

29.6.3 Random number engine class templates [rand.eng]

Each type instantiated from a class template specified in this section [rand.eng] satisfies the requirements of a random number engine ([rand.req.eng]) type.
Except where specified otherwise, the complexity of each function specified in this section [rand.eng] is constant.
Except where specified otherwise, no function described in this section [rand.eng] throws an exception.
Every function described in this section [rand.eng] that has a function parameter q of type Sseq& for a template type parameter named Sseq that is different from type seed_­seq throws what and when the invocation of q.generate throws.
Descriptions are provided in this section [rand.eng] only for engine operations that are not described in [rand.req.eng] or for operations where there is additional semantic information.
In particular, declarations for copy constructors, for copy assignment operators, for streaming operators, and for equality and inequality operators are not shown in the synopses.
Each template specified in this section [rand.eng] requires one or more relationships, involving the value(s) of its non-type template parameter(s), to hold.
A program instantiating any of these templates is ill-formed if any such required relationship fails to hold.
For every random number engine and for every random number engine adaptor X defined in this subclause ([rand.eng]) and in subclause [rand.adapt]:
  • if the constructor
    template <class Sseq> explicit X(Sseq& q);
    is called with a type Sseq that does not qualify as a seed sequence, then this constructor shall not participate in overload resolution;
  • if the member function
    template <class Sseq> void seed(Sseq& q);
    is called with a type Sseq that does not qualify as a seed sequence, then this function shall not participate in overload resolution.
The extent to which an implementation determines that a type cannot be a seed sequence is unspecified, except that as a minimum a type shall not qualify as a seed sequence if it is implicitly convertible to X​::​result_­type.

29.6.3.1 Class template linear_­congruential_­engine [rand.eng.lcong]

A linear_­congruential_­engine random number engine produces unsigned integer random numbers.
The state x of a linear_­congruential_­engine object x is of size 1 and consists of a single integer.
The transition algorithm is a modular linear function of the form ; the generation algorithm is .
template<class UIntType, UIntType a, UIntType c, UIntType m>
  class linear_congruential_engine {
  public:
    // types
    using result_type = UIntType;

    // engine characteristics
    static constexpr result_type multiplier = a;
    static constexpr result_type increment = c;
    static constexpr result_type modulus = m;
    static constexpr result_type min() { return c == 0u ? 1u: 0u; }
    static constexpr result_type max() { return m - 1u; }
    static constexpr result_type default_seed = 1u;

    // constructors and seeding functions
    explicit linear_congruential_engine(result_type s = default_seed);
    template<class Sseq> explicit linear_congruential_engine(Sseq& q);
    void seed(result_type s = default_seed);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);
  };
If the template parameter m is 0, the modulus m used throughout this section [rand.eng.lcong] is numeric_­limits<result_­type>​::​max() plus 1.
[Note
:
m need not be representable as a value of type result_­type.
end note
]
If the template parameter m is not 0, the following relations shall hold: a < m and c < m.
The textual representation consists of the value of x.
explicit linear_congruential_engine(result_type s = default_seed);
Effects: Constructs a linear_­congruential_­engine object.
If is 0 and is 0, sets the engine's state to 1, otherwise sets the engine's state to .
template<class Sseq> explicit linear_congruential_engine(Sseq& q);
Effects: Constructs a linear_­congruential_­engine object.
With and a an array (or equivalent) of length , invokes q.generate(, ) and then computes .
If is 0 and S is 0, sets the engine's state to 1, else sets the engine's state to S.

29.6.3.2 Class template mersenne_­twister_­engine [rand.eng.mers]

A mersenne_­twister_­engine random number engine270 produces unsigned integer random numbers in the closed interval .
The state x of a mersenne_­twister_­engine object x is of size n and consists of a sequence X of n values of the type delivered by x; all subscripts applied to X are to be taken modulo n.
The transition algorithm employs a twisted generalized feedback shift register defined by shift values n and m, a twist value r, and a conditional xor-mask a.
To improve the uniformity of the result, the bits of the raw shift register are additionally tempered (i.e., scrambled) according to a bit-scrambling matrix defined by values and .
The state transition is performed as follows:
  1. a)
    Concatenate the upper bits of with the lower r bits of to obtain an unsigned integer value Y.
  2. b)
    With , set to .
The sequence X is initialized with the help of an initialization multiplier f.
The generation algorithm determines the unsigned integer values as follows, then delivers as its result:
  1. a)
    Let .
  2. b)
    Let .
  3. c)
    Let .
  4. d)
    Let .
template<class UIntType, size_t w, size_t n, size_t m, size_t r,
         UIntType a, size_t u, UIntType d, size_t s,
         UIntType b, size_t t,
         UIntType c, size_t l, UIntType f>
  class mersenne_twister_engine {
  public:
    // types
    using result_type = UIntType;

    // engine characteristics
    static constexpr size_t word_size = w;
    static constexpr size_t state_size = n;
    static constexpr size_t shift_size = m;
    static constexpr size_t mask_bits = r;
    static constexpr UIntType xor_mask = a;
    static constexpr size_t tempering_u = u;
    static constexpr UIntType tempering_d = d;
    static constexpr size_t tempering_s = s;
    static constexpr UIntType tempering_b = b;
    static constexpr size_t tempering_t = t;
    static constexpr UIntType tempering_c = c;
    static constexpr size_t tempering_l = l;
    static constexpr UIntType initialization_multiplier = f;
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return  ; }
    static constexpr result_type default_seed = 5489u;

    // constructors and seeding functions
    explicit mersenne_twister_engine(result_type value = default_seed);
    template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
    void seed(result_type value = default_seed);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);
  };
The following relations shall hold: 0 < m, m <= n, 2u < w, r <= w, u <= w, s <= w, t <= w, l <= w, w <= numeric_­limits<UIntType>​::​digits, a <= (1u<<w) - 1u, b <= (1u<<w) - 1u, c <= (1u<<w) - 1u, d <= (1u<<w) - 1u, and f <= (1u<<w) - 1u.
The textual representation of x consists of the values of , in that order.
explicit mersenne_twister_engine(result_type value = default_seed);
Effects: Constructs a mersenne_­twister_­engine object.
Sets to .
Then, iteratively for , sets to

Complexity: .
template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
Effects: Constructs a mersenne_­twister_­engine object.
With and a an array (or equivalent) of length , invokes q.generate(, ) and then, iteratively for , sets to .
Finally, if the most significant bits of are zero, and if each of the other resulting is 0, changes to .
The name of this engine refers, in part, to a property of its period: For properly-selected values of the parameters, the period is closely related to a large Mersenne prime number.

29.6.3.3 Class template subtract_­with_­carry_­engine [rand.eng.sub]

A subtract_­with_­carry_­engine random number engine produces unsigned integer random numbers.
The state x of a subtract_­with_­carry_­engine object x is of size , and consists of a sequence X of r integer values ; all subscripts applied to X are to be taken modulo r.
The state x additionally consists of an integer c (known as the carry) whose value is either 0 or 1.
The state transition is performed as follows:
  1. a)
    Let .
  2. b)
    Set to .
    Set c to 1 if , otherwise set c to 0.
[Note
:
This algorithm corresponds to a modular linear function of the form , where b is of the form and .
end note
]
The generation algorithm is given by , where y is the value produced as a result of advancing the engine's state as described above.
template<class UIntType, size_t w, size_t s, size_t r>
  class subtract_with_carry_engine {
  public:
    // types
    using result_type = UIntType;

    // engine characteristics
    static constexpr size_t word_size = w;
    static constexpr size_t short_lag = s;
    static constexpr size_t long_lag = r;
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return ; }
    static constexpr result_type default_seed = 19780503u;

    // constructors and seeding functions
    explicit subtract_with_carry_engine(result_type value = default_seed);
    template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
    void seed(result_type value = default_seed);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);
  };
The following relations shall hold: 0u < s, s < r, 0 < w, and w <= numeric_­limits<UIntType>​::​digits.
The textual representation consists of the values of , in that order, followed by c.
explicit subtract_with_carry_engine(result_type value = default_seed);
Effects: Constructs a subtract_­with_­carry_­engine object.
Sets the values of , in that order, as specified below.
If is then 0, sets c to 1; otherwise sets c to 0.
To set the values , first construct e, a linear_­congruential_­engine object, as if by the following definition:
linear_congruential_engine<result_type,
                          40014u,0u,2147483563u> e(value == 0u ? default_seed : value);
Then, to set each , obtain new values from successive invocations of e taken modulo .
Set to .
Complexity: Exactly invocations of e.
template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
Effects: Constructs a subtract_­with_­carry_­engine object.
With and a an array (or equivalent) of length , invokes q.generate(, ) and then, iteratively for , sets to .
If is then 0, sets c to 1; otherwise sets c to 0.

29.6.4 Random number engine adaptor class templates [rand.adapt]

29.6.4.1 In general [rand.adapt.general]

Each type instantiated from a class template specified in this section [rand.adapt] satisfies the requirements of a random number engine adaptor ([rand.req.adapt]) type.
Except where specified otherwise, the complexity of each function specified in this section [rand.adapt] is constant.
Except where specified otherwise, no function described in this section [rand.adapt] throws an exception.
Every function described in this section [rand.adapt] that has a function parameter q of type Sseq& for a template type parameter named Sseq that is different from type seed_­seq throws what and when the invocation of q.generate throws.
Descriptions are provided in this section [rand.adapt] only for adaptor operations that are not described in section [rand.req.adapt] or for operations where there is additional semantic information.
In particular, declarations for copy constructors, for copy assignment operators, for streaming operators, and for equality and inequality operators are not shown in the synopses.
Each template specified in this section [rand.adapt] requires one or more relationships, involving the value(s) of its non-type template parameter(s), to hold.
A program instantiating any of these templates is ill-formed if any such required relationship fails to hold.

29.6.4.2 Class template discard_­block_­engine [rand.adapt.disc]

A discard_­block_­engine random number engine adaptor produces random numbers selected from those produced by some base engine e.
The state x of a discard_­block_­engine engine adaptor object x consists of the state e of its base engine e and an additional integer n.
The size of the state is the size of e's state plus 1.
The transition algorithm discards all but values from each block of values delivered by e.
The state transition is performed as follows: If , advance the state of e from e to e and set n to 0.
In any case, then increment n and advance e's then-current state e to e.
The generation algorithm yields the value returned by the last invocation of e() while advancing e's state as described above.
template<class Engine, size_t p, size_t r>
  class discard_block_engine {
  public:
    // types
    using result_type = typename Engine::result_type;

    // engine characteristics
    static constexpr size_t block_size = p;
    static constexpr size_t used_block = r;
    static constexpr result_type min() { return Engine::min(); }
    static constexpr result_type max() { return Engine::max(); }

    // constructors and seeding functions
    discard_block_engine();
    explicit discard_block_engine(const Engine& e);
    explicit discard_block_engine(Engine&& e);
    explicit discard_block_engine(result_type s);
    template<class Sseq> explicit discard_block_engine(Sseq& q);
    void seed();
    void seed(result_type s);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);

    // property functions
    const Engine& base() const noexcept { return e; };

  private:
    Engine e;   // exposition only
    int n;      // exposition only
  };
The following relations shall hold: 0 < r and r <= p.
The textual representation consists of the textual representation of e followed by the value of n.
In addition to its behavior pursuant to section [rand.req.adapt], each constructor that is not a copy constructor sets n to 0.

29.6.4.3 Class template independent_­bits_­engine [rand.adapt.ibits]

An independent_­bits_­engine random number engine adaptor combines random numbers that are produced by some base engine e, so as to produce random numbers with a specified number of bits w.
The state x of an independent_­bits_­engine engine adaptor object x consists of the state e of its base engine e; the size of the state is the size of e's state.
The transition and generation algorithms are described in terms of the following integral constants:
  1. a)
    Let and .
  2. b)
    With n as determined below, let , , , and .
  3. c)
    Let if and only if the relation holds as a result.
    Otherwise let .
[Note
:
The relation always holds.
end note
]
The transition algorithm is carried out by invoking e() as often as needed to obtain values less than and values less than .
The generation algorithm uses the values produced while advancing the state as described above to yield a quantity S obtained as if by the following algorithm:
S = 0;
for (k = 0; ; k += 1)  {
 do u = e() - e.min(); while ();
 S = ;
}
for (k = ; ; k += 1)  {
 do u = e() - e.min(); while ();
 S = ;
}
template<class Engine, size_t w, class UIntType>
  class independent_bits_engine {
  public:
    // types
    using result_type = UIntType;

    // engine characteristics
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return ; }

    // constructors and seeding functions
    independent_bits_engine();
    explicit independent_bits_engine(const Engine& e);
    explicit independent_bits_engine(Engine&& e);
    explicit independent_bits_engine(result_type s);
    template<class Sseq> explicit independent_bits_engine(Sseq& q);
    void seed();
    void seed(result_type s);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);

    // property functions
    const Engine& base() const noexcept { return e; };

  private:
    Engine e;   // exposition only
  };
The following relations shall hold: 0 < w and w <= numeric_­limits<result_­type>​::​digits.
The textual representation consists of the textual representation of e.

29.6.4.4 Class template shuffle_­order_­engine [rand.adapt.shuf]

A shuffle_­order_­engine random number engine adaptor produces the same random numbers that are produced by some base engine e, but delivers them in a different sequence.
The state x of a shuffle_­order_­engine engine adaptor object x consists of the state e of its base engine e, an additional value Y of the type delivered by e, and an additional sequence V of k values also of the type delivered by e.
The size of the state is the size of e's state plus .
The transition algorithm permutes the values produced by e.
The state transition is performed as follows:
  1. a)
    Calculate an integer .
  2. b)
    Set Y to and then set to e().
The generation algorithm yields the last value of Y produced while advancing e's state as described above.
template<class Engine, size_t k>
  class shuffle_order_engine {
  public:
    // types
    using result_type = typename Engine::result_type;

    // engine characteristics
    static constexpr size_t table_size = k;
    static constexpr result_type min() { return Engine::min(); }
    static constexpr result_type max() { return Engine::max(); }

    // constructors and seeding functions
    shuffle_order_engine();
    explicit shuffle_order_engine(const Engine& e);
    explicit shuffle_order_engine(Engine&& e);
    explicit shuffle_order_engine(result_type s);
    template<class Sseq> explicit shuffle_order_engine(Sseq& q);
    void seed();
    void seed(result_type s);
    template<class Sseq> void seed(Sseq& q);

    // generating functions
    result_type operator()();
    void discard(unsigned long long z);

    // property functions
    const Engine& base() const noexcept { return e; };

  private:
    Engine e;           // exposition only
    result_type V[k];   // exposition only
    result_type Y;      // exposition only
  };
The following relation shall hold: 0 < k.
The textual representation consists of the textual representation of e, followed by the k values of V, followed by the value of Y.
In addition to its behavior pursuant to section [rand.req.adapt], each constructor that is not a copy constructor initializes and Y, in that order, with values returned by successive invocations of e().

29.6.5 Engines and engine adaptors with predefined parameters [rand.predef]

using minstd_rand0 = linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>;
Required behavior: The consecutive invocation of a default-constructed object of type minstd_­rand0 shall produce the value 1043618065.
using minstd_rand = linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>;
Required behavior: The consecutive invocation of a default-constructed object of type minstd_­rand shall produce the value 399268537.
using mt19937 = mersenne_twister_engine<uint_fast32_t, 32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>;
Required behavior: The consecutive invocation of a default-constructed object of type mt19937 shall produce the value 4123659995.
using mt19937_64 = mersenne_twister_engine<uint_fast64_t, 64,312,156,31,0xb5026f5aa96619e9,29, 0x5555555555555555,17, 0x71d67fffeda60000,37, 0xfff7eee000000000,43, 6364136223846793005>;
Required behavior: The consecutive invocation of a default-constructed object of type mt19937_­64 shall produce the value 9981545732273789042.
using ranlux24_base = subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>;
Required behavior: The consecutive invocation of a default-constructed object of type ranlux24_­base shall produce the value 7937952.
using ranlux48_base = subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>;
Required behavior: The consecutive invocation of a default-constructed object of type ranlux48_­base shall produce the value 61839128582725.
using ranlux24 = discard_block_engine<ranlux24_base, 223, 23>;
Required behavior: The consecutive invocation of a default-constructed object of type ranlux24 shall produce the value 9901578.
using ranlux48 = discard_block_engine<ranlux48_base, 389, 11>;
Required behavior: The consecutive invocation of a default-constructed object of type ranlux48 shall produce the value 249142670248501.
using knuth_b = shuffle_order_engine<minstd_rand0,256>;
Required behavior: The consecutive invocation of a default-constructed object of type knuth_­b shall produce the value 1112339016.
using default_random_engine = implementation-defined;
Remarks: The choice of engine type named by this typedef is implementation-defined.
[Note
:
The implementation may select this type on the basis of performance, size, quality, or any combination of such factors, so as to provide at least acceptable engine behavior for relatively casual, inexpert, and/or lightweight use.
Because different implementations may select different underlying engine types, code that uses this typedef need not generate identical sequences across implementations.
end note
]

29.6.6 Class random_­device [rand.device]

A random_­device uniform random bit generator produces nondeterministic random numbers.
If implementation limitations prevent generating nondeterministic random numbers, the implementation may employ a random number engine.
class random_device {
public:
  // types
  using result_type = unsigned int;

  // generator characteristics
  static constexpr result_type min() { return numeric_limits<result_type>::min(); }
  static constexpr result_type max() { return numeric_limits<result_type>::max(); }

  // constructors
  explicit random_device(const string& token = implementation-defined);

  // generating functions
  result_type operator()();

  // property functions
  double entropy() const noexcept;

  // no copy functions
  random_device(const random_device& ) = delete;
  void operator=(const random_device& ) = delete;
};
explicit random_device(const string& token = implementation-defined);
Effects: Constructs a random_­device nondeterministic uniform random bit generator object.
The semantics and default value of the token parameter are implementation-defined.271
Throws: A value of an implementation-defined type derived from exception if the random_­device could not be initialized.
double entropy() const noexcept;
Returns: If the implementation employs a random number engine, returns 0.0.
Otherwise, returns an entropy estimate272 for the random numbers returned by operator(), in the range min() to .
result_type operator()();
Returns: A nondeterministic random value, uniformly distributed between min() and max(), inclusive.
It is implementation-defined how these values are generated.
Throws: A value of an implementation-defined type derived from exception if a random number could not be obtained.
The parameter is intended to allow an implementation to differentiate between different sources of randomness.
If a device has n states whose respective probabilities are , the device entropy S is defined as
.

29.6.7 Utilities [rand.util]

29.6.7.1 Class seed_­seq [rand.util.seedseq]

class seed_seq {
public:
  // types
  using result_type = uint_least32_t;

  // constructors
  seed_seq();
  template<class T>
    seed_seq(initializer_list<T> il);
  template<class InputIterator>
    seed_seq(InputIterator begin, InputIterator end);

  // generating functions
  template<class RandomAccessIterator>
    void generate(RandomAccessIterator begin, RandomAccessIterator end);

  // property functions
  size_t size() const noexcept;
  template<class OutputIterator>
    void param(OutputIterator dest) const;

  // no copy functions
  seed_seq(const seed_seq& ) = delete;
  void operator=(const seed_seq& ) = delete;

private:
  vector<result_type> v;   // exposition only
};
seed_seq();
Effects: Constructs a seed_­seq object as if by default-constructing its member v.
Throws: Nothing.
template<class T> seed_seq(initializer_list<T> il);
Requires: T shall be an integer type.
Effects: Same as seed_­seq(il.begin(), il.end()).
template<class InputIterator> seed_seq(InputIterator begin, InputIterator end);
Requires: InputIterator shall satisfy the requirements of an input iterator (Table 90) type.
Moreover, iterator_­traits<InputIterator>​::​value_­type shall denote an integer type.
Effects: Constructs a seed_­seq object by the following algorithm:
for( InputIterator s = begin; s != end; ++s)
 v.push_back((*s));
template<class RandomAccessIterator> void generate(RandomAccessIterator begin, RandomAccessIterator end);
Requires: RandomAccessIterator shall meet the requirements of a mutable random access iterator ([random.access.iterators]).
Moreover, iterator_­traits<RandomAccessIterator>​::​value_­type shall denote an unsigned integer type capable of accommodating 32-bit quantities.
Effects: Does nothing if begin == end.
Otherwise, with and , fills the supplied range according to the following algorithm in which each operation is to be carried out modulo , each indexing operator applied to begin is to be taken modulo n, and T(x) is defined as :
  1. a)
    By way of initialization, set each element of the range to the value 0x8b8b8b8b.
    Additionally, for use in subsequent steps, let and let , where

  2. b)
    With m as the larger of and n, transform the elements of the range: iteratively for , calculate values

    and, in order, increment by , increment by , and set begin[k] to .

  3. c)
    Transform the elements of the range again, beginning where the previous step ended: iteratively for , calculate values

    and, in order, update by xoring it with , update by xoring it with , and set begin[k] to .

Throws: What and when RandomAccessIterator operations of begin and end throw.
size_t size() const noexcept;
Returns: The number of 32-bit units that would be returned by a call to param().
Complexity: Constant time.
template<class OutputIterator> void param(OutputIterator dest) const;
Requires: OutputIterator shall satisfy the requirements of an output iterator ([output.iterators]).
Moreover, the expression *dest = rt shall be valid for a value rt of type result_­type.
Effects: Copies the sequence of prepared 32-bit units to the given destination, as if by executing the following statement:
copy(v.begin(), v.end(), dest);
Throws: What and when OutputIterator operations of dest throw.

29.6.7.2 Function template generate_­canonical [rand.util.canonical]

Each function instantiated from the template described in this section [rand.util.canonical] maps the result of one or more invocations of a supplied uniform random bit generator g to one member of the specified RealType such that, if the values produced by g are uniformly distributed, the instantiation's results , , are distributed as uniformly as possible as specified below.
[Note
:
Obtaining a value in this way can be a useful step in the process of transforming a value generated by a uniform random bit generator into a value that can be delivered by a random number distribution.
end note
]
template<class RealType, size_t bits, class URBG> RealType generate_canonical(URBG& g);
Complexity: Exactly invocations of g, where b273 is the lesser of numeric_­limits<RealType>​::​digits and bits, and R is the value of .
Effects: Invokes g() k times to obtain values , respectively.
Calculates a quantity

using arithmetic of type RealType.

Returns: .
Throws: What and when g throws.
b is introduced to avoid any attempt to produce more bits of randomness than can be held in RealType.

29.6.8 Random number distribution class templates [rand.dist]

29.6.8.1 In general [rand.dist.general]

Each type instantiated from a class template specified in this section [rand.dist] satisfies the requirements of a random number distribution ([rand.req.dist]) type.
Descriptions are provided in this section [rand.dist] only for distribution operations that are not described in [rand.req.dist] or for operations where there is additional semantic information.
In particular, declarations for copy constructors, for copy assignment operators, for streaming operators, and for equality and inequality operators are not shown in the synopses.
The algorithms for producing each of the specified distributions are implementation-defined.
The value of each probability density function p(z) and of each discrete probability function specified in this section is 0 everywhere outside its stated domain.

29.6.8.2 Uniform distributions [rand.dist.uni]

29.6.8.2.1 Class template uniform_­int_­distribution [rand.dist.uni.int]

A uniform_­int_­distribution random number distribution produces random integers i, , distributed according to the constant discrete probability function

template<class IntType = int>
  class uniform_int_distribution {
  public:
    // types
    using result_type = IntType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit uniform_int_distribution(IntType a = 0, IntType b = numeric_limits<IntType>::max());
    explicit uniform_int_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    result_type a() const;
    result_type b() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit uniform_int_distribution(IntType a = 0, IntType b = numeric_limits<IntType>::max());
Requires: .
Effects: Constructs a uniform_­int_­distribution object; a and b correspond to the respective parameters of the distribution.
result_type a() const;
Returns: The value of the a parameter with which the object was constructed.
result_type b() const;
Returns: The value of the b parameter with which the object was constructed.

29.6.8.2.2 Class template uniform_­real_­distribution [rand.dist.uni.real]

A uniform_­real_­distribution random number distribution produces random numbers x, , distributed according to the constant probability density function

[Note
:
This implies that is undefined when a == b.
end note
]
template<class RealType = double>
  class uniform_real_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
    explicit uniform_real_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    result_type a() const;
    result_type b() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
Requires: and .
Effects: Constructs a uniform_­real_­distribution object; a and b correspond to the respective parameters of the distribution.
result_type a() const;
Returns: The value of the a parameter with which the object was constructed.
result_type b() const;
Returns: The value of the b parameter with which the object was constructed.

29.6.8.3 Bernoulli distributions [rand.dist.bern]

29.6.8.3.1 Class bernoulli_­distribution [rand.dist.bern.bernoulli]

A bernoulli_­distribution random number distribution produces bool values b distributed according to the discrete probability function

class bernoulli_distribution {
public:
  // types
  using result_type = bool;
  using param_type  = unspecified;

  // constructors and reset functions
  explicit bernoulli_distribution(double p = 0.5);
  explicit bernoulli_distribution(const param_type& parm);
  void reset();

  // generating functions
  template<class URBG>
    result_type operator()(URBG& g);
  template<class URBG>
    result_type operator()(URBG& g, const param_type& parm);

  // property functions
  double p() const;
  param_type param() const;
  void param(const param_type& parm);
  result_type min() const;
  result_type max() const;
};
explicit bernoulli_distribution(double p = 0.5);
Requires: .
Effects: Constructs a bernoulli_­distribution object; p corresponds to the parameter of the distribution.
double p() const;
Returns: The value of the p parameter with which the object was constructed.

29.6.8.3.2 Class template binomial_­distribution [rand.dist.bern.bin]

A binomial_­distribution random number distribution produces integer values distributed according to the discrete probability function

template<class IntType = int>
  class binomial_distribution {
  public:
    // types
    using result_type = IntType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit binomial_distribution(IntType t = 1, double p = 0.5);
    explicit binomial_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    IntType t() const;
    double p() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit binomial_distribution(IntType t = 1, double p = 0.5);
Requires: and .
Effects: Constructs a binomial_­distribution object; t and p correspond to the respective parameters of the distribution.
IntType t() const;
Returns: The value of the t parameter with which the object was constructed.
double p() const;
Returns: The value of the p parameter with which the object was constructed.

29.6.8.3.3 Class template geometric_­distribution [rand.dist.bern.geo]

A geometric_­distribution random number distribution produces integer values distributed according to the discrete probability function

template<class IntType = int>
  class geometric_distribution {
  public:
    // types
    using result_type = IntType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit geometric_distribution(double p = 0.5);
    explicit geometric_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    double p() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit geometric_distribution(double p = 0.5);
Requires: .
Effects: Constructs a geometric_­distribution object; p corresponds to the parameter of the distribution.
double p() const;
Returns: The value of the p parameter with which the object was constructed.

29.6.8.3.4 Class template negative_­binomial_­distribution [rand.dist.bern.negbin]

A negative_­binomial_­distribution random number distribution produces random integers distributed according to the discrete probability function

[Note
:
This implies that is undefined when p == 1.
end note
]
template<class IntType = int>
  class negative_binomial_distribution {
  public:
    // types
    using result_type = IntType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit negative_binomial_distribution(IntType k = 1, double p = 0.5);
    explicit negative_binomial_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    IntType k() const;
    double p() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit negative_binomial_distribution(IntType k = 1, double p = 0.5);
Requires: and .
Effects: Constructs a negative_­binomial_­distribution object; k and p correspond to the respective parameters of the distribution.
IntType k() const;
Returns: The value of the k parameter with which the object was constructed.
double p() const;
Returns: The value of the p parameter with which the object was constructed.

29.6.8.4 Poisson distributions [rand.dist.pois]

29.6.8.4.1 Class template poisson_­distribution [rand.dist.pois.poisson]

A poisson_­distribution random number distribution produces integer values distributed according to the discrete probability function

The distribution parameter μ is also known as this distribution's mean.

template<class IntType = int>
  class poisson_distribution
  {
  public:
    // types
    using result_type = IntType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit poisson_distribution(double mean = 1.0);
    explicit poisson_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    double mean() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit poisson_distribution(double mean = 1.0);
Requires: .
Effects: Constructs a poisson_­distribution object; mean corresponds to the parameter of the distribution.
double mean() const;
Returns: The value of the mean parameter with which the object was constructed.

29.6.8.4.2 Class template exponential_­distribution [rand.dist.pois.exp]

An exponential_­distribution random number distribution produces random numbers distributed according to the probability density function

template<class RealType = double>
  class exponential_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit exponential_distribution(RealType lambda = 1.0);
    explicit exponential_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType lambda() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit exponential_distribution(RealType lambda = 1.0);
Requires: .
Effects: Constructs an exponential_­distribution object; lambda corresponds to the parameter of the distribution.
RealType lambda() const;
Returns: The value of the lambda parameter with which the object was constructed.

29.6.8.4.3 Class template gamma_­distribution [rand.dist.pois.gamma]

A gamma_­distribution random number distribution produces random numbers distributed according to the probability density function

template<class RealType = double>
  class gamma_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit gamma_distribution(RealType alpha = 1.0, RealType beta = 1.0);
    explicit gamma_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType alpha() const;
    RealType beta() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit gamma_distribution(RealType alpha = 1.0, RealType beta = 1.0);
Requires: and .
Effects: Constructs a gamma_­distribution object; alpha and beta correspond to the parameters of the distribution.
RealType alpha() const;
Returns: The value of the alpha parameter with which the object was constructed.
RealType beta() const;
Returns: The value of the beta parameter with which the object was constructed.

29.6.8.4.4 Class template weibull_­distribution [rand.dist.pois.weibull]

A weibull_­distribution random number distribution produces random numbers distributed according to the probability density function

template<class RealType = double>
  class weibull_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit weibull_distribution(RealType a = 1.0, RealType b = 1.0);
    explicit weibull_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType a() const;
    RealType b() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit weibull_distribution(RealType a = 1.0, RealType b = 1.0);
Requires: and .
Effects: Constructs a weibull_­distribution object; a and b correspond to the respective parameters of the distribution.
RealType a() const;
Returns: The value of the a parameter with which the object was constructed.
RealType b() const;
Returns: The value of the b parameter with which the object was constructed.

29.6.8.4.5 Class template extreme_­value_­distribution [rand.dist.pois.extreme]

An extreme_­value_­distribution random number distribution produces random numbers x distributed according to the probability density function274

template<class RealType = double>
  class extreme_value_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit extreme_value_distribution(RealType a = 0.0, RealType b = 1.0);
    explicit extreme_value_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType a() const;
    RealType b() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit extreme_value_distribution(RealType a = 0.0, RealType b = 1.0);
Requires: .
Effects: Constructs an extreme_­value_­distribution object; a and b correspond to the respective parameters of the distribution.
RealType a() const;
Returns: The value of the a parameter with which the object was constructed.
RealType b() const;
Returns: The value of the b parameter with which the object was constructed.
The distribution corresponding to this probability density function is also known (with a possible change of variable) as the Gumbel Type I, the log-Weibull, or the Fisher-Tippett Type I distribution.

29.6.8.5 Normal distributions [rand.dist.norm]

29.6.8.5.1 Class template normal_­distribution [rand.dist.norm.normal]

A normal_­distribution random number distribution produces random numbers x distributed according to the probability density function

The distribution parameters μ and σ are also known as this distribution's mean and standard deviation.

template<class RealType = double>
  class normal_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructors and reset functions
    explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0);
    explicit normal_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType mean() const;
    RealType stddev() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0);
Requires: .
Effects: Constructs a normal_­distribution object; mean and stddev correspond to the respective parameters of the distribution.
RealType mean() const;
Returns: The value of the mean parameter with which the object was constructed.
RealType stddev() const;
Returns: The value of the stddev parameter with which the object was constructed.

29.6.8.5.2 Class template lognormal_­distribution [rand.dist.norm.lognormal]

A lognormal_­distribution random number distribution produces random numbers distributed according to the probability density function

template<class RealType = double>
  class lognormal_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit lognormal_distribution(RealType m = 0.0, RealType s = 1.0);
    explicit lognormal_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType m() const;
    RealType s() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit lognormal_distribution(RealType m = 0.0, RealType s = 1.0);
Requires: .
Effects: Constructs a lognormal_­distribution object; m and s correspond to the respective parameters of the distribution.
RealType m() const;
Returns: The value of the m parameter with which the object was constructed.
RealType s() const;
Returns: The value of the s parameter with which the object was constructed.

29.6.8.5.3 Class template chi_­squared_­distribution [rand.dist.norm.chisq]

A chi_­squared_­distribution random number distribution produces random numbers x>0 distributed according to the probability density function

template<class RealType = double>
  class chi_squared_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit chi_squared_distribution(RealType n = 1);
    explicit chi_squared_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType n() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit chi_squared_distribution(RealType n = 1);
Requires: .
Effects: Constructs a chi_­squared_­distribution object; n corresponds to the parameter of the distribution.
RealType n() const;
Returns: The value of the n parameter with which the object was constructed.

29.6.8.5.4 Class template cauchy_­distribution [rand.dist.norm.cauchy]

A cauchy_­distribution random number distribution produces random numbers x distributed according to the probability density function

template<class RealType = double>
  class cauchy_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit cauchy_distribution(RealType a = 0.0, RealType b = 1.0);
    explicit cauchy_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType a() const;
    RealType b() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit cauchy_distribution(RealType a = 0.0, RealType b = 1.0);
Requires: .
Effects: Constructs a cauchy_­distribution object; a and b correspond to the respective parameters of the distribution.
RealType a() const;
Returns: The value of the a parameter with which the object was constructed.
RealType b() const;
Returns: The value of the b parameter with which the object was constructed.

29.6.8.5.5 Class template fisher_­f_­distribution [rand.dist.norm.f]

A fisher_­f_­distribution random number distribution produces random numbers x≥0 distributed according to the probability density function

template<class RealType = double>
  class fisher_f_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit fisher_f_distribution(RealType m = 1, RealType n = 1);
    explicit fisher_f_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType m() const;
    RealType n() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit fisher_f_distribution(RealType m = 1, RealType n = 1);
Requires: and .
Effects: Constructs a fisher_­f_­distribution object; m and n correspond to the respective parameters of the distribution.
RealType m() const;
Returns: The value of the m parameter with which the object was constructed.
RealType n() const;
Returns: The value of the n parameter with which the object was constructed.

29.6.8.5.6 Class template student_­t_­distribution [rand.dist.norm.t]

A student_­t_­distribution random number distribution produces random numbers x distributed according to the probability density function

template<class RealType = double>
  class student_t_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    explicit student_t_distribution(RealType n = 1);
    explicit student_t_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    RealType n() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
explicit student_t_distribution(RealType n = 1);
Requires: .
Effects: Constructs a student_­t_­distribution object; n corresponds to the parameter of the distribution.
RealType n() const;
Returns: The value of the n parameter with which the object was constructed.

29.6.8.6 Sampling distributions [rand.dist.samp]

29.6.8.6.1 Class template discrete_­distribution [rand.dist.samp.discrete]

A discrete_­distribution random number distribution produces random integers i, , distributed according to the discrete probability function

Unless specified otherwise, the distribution parameters are calculated as: , in which the values , commonly known as the weights, shall be non-negative, non-NaN, and non-infinity.
Moreover, the following relation shall hold: .
template<class IntType = int>
  class discrete_distribution {
  public:
    // types
    using result_type = IntType;
    using param_type  = unspecified;

    // constructor and reset functions
    discrete_distribution();
    template<class InputIterator>
      discrete_distribution(InputIterator firstW, InputIterator lastW);
    discrete_distribution(initializer_list<double> wl);
    template<class UnaryOperation>
      discrete_distribution(size_t nw, double xmin, double xmax, UnaryOperation fw);
    explicit discrete_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    vector<double> probabilities() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
discrete_distribution();
Effects: Constructs a discrete_­distribution object with and .
[Note
:
Such an object will always deliver the value 0.
end note
]
template<class InputIterator> discrete_distribution(InputIterator firstW, InputIterator lastW);
Requires: InputIterator shall satisfy the requirements of an input iterator ([input.iterators]).
Moreover, iterator_­traits<InputIterator>​::​value_­type shall denote a type that is convertible to double.
If firstW == lastW, let and .
Otherwise, shall form a sequence w of length .
Effects: Constructs a discrete_­distribution object with probabilities given by the formula above.
discrete_distribution(initializer_list<double> wl);
Effects: Same as discrete_­distribution(wl.begin(), wl.end()).
template<class UnaryOperation> discrete_distribution(size_t nw, double xmin, double xmax, UnaryOperation fw);
Requires: Each instance of type UnaryOperation shall be a function object ([function.objects]) whose return type shall be convertible to double.
Moreover, double shall be convertible to the type of UnaryOperation's sole parameter.
If , let , otherwise let .
The relation shall hold.
Effects: Constructs a discrete_­distribution object with probabilities given by the formula above, using the following values: If , let .
Otherwise, let for .
Complexity: The number of invocations of fw shall not exceed n.
vector<double> probabilities() const;
Returns: A vector<double> whose size member returns n and whose operator[] member returns when invoked with argument k for .

29.6.8.6.2 Class template piecewise_­constant_­distribution [rand.dist.samp.pconst]

A piecewise_­constant_­distribution random number distribution produces random numbers x, , uniformly distributed over each subinterval according to the probability density function

The distribution parameters , also known as this distribution's interval boundaries, shall satisfy the relation for .
Unless specified otherwise, the remaining n distribution parameters are calculated as:

in which the values , commonly known as the weights, shall be non-negative, non-NaN, and non-infinity.

Moreover, the following relation shall hold: .
template<class RealType = double>
  class piecewise_constant_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    piecewise_constant_distribution();
    template<class InputIteratorB, class InputIteratorW>
      piecewise_constant_distribution(InputIteratorB firstB, InputIteratorB lastB,
                                      InputIteratorW firstW);
    template<class UnaryOperation>
      piecewise_constant_distribution(initializer_list<RealType> bl, UnaryOperation fw);
    template<class UnaryOperation>
      piecewise_constant_distribution(size_t nw, RealType xmin, RealType xmax,
                                      UnaryOperation fw);
    explicit piecewise_constant_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    vector<result_type> intervals() const;
    vector<result_type> densities() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
piecewise_constant_distribution();
Effects: Constructs a piecewise_­constant_­distribution object with , , , and .
template<class InputIteratorB, class InputIteratorW> piecewise_constant_distribution(InputIteratorB firstB, InputIteratorB lastB, InputIteratorW firstW);
Requires: InputIteratorB and InputIteratorW shall each satisfy the requirements of an input iterator (Table 90) type.
Moreover, iterator_­traits<InputIteratorB>​::​value_­type and iterator_­traits<InputIteratorW>​::​value_­type shall each denote a type that is convertible to double.
If firstB == lastB or ++firstB == lastB, let , , , and .
Otherwise, shall form a sequence b of length , the length of the sequence w starting from firstW shall be at least n, and any for shall be ignored by the distribution.
Effects: Constructs a piecewise_­constant_­distribution object with parameters as specified above.
template<class UnaryOperation> piecewise_constant_distribution(initializer_list<RealType> bl, UnaryOperation fw);
Requires: Each instance of type UnaryOperation shall be a function object ([function.objects]) whose return type shall be convertible to double.
Moreover, double shall be convertible to the type of UnaryOperation's sole parameter.
Effects: Constructs a piecewise_­constant_­distribution object with parameters taken or calculated from the following values: If , let , , , and .
Otherwise, let form a sequence , and let for .
Complexity: The number of invocations of fw shall not exceed n.
template<class UnaryOperation> piecewise_constant_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw);
Requires: Each instance of type UnaryOperation shall be a function object ([function.objects]) whose return type shall be convertible to double.
Moreover, double shall be convertible to the type of UnaryOperation's sole parameter.
If , let , otherwise let .
The relation shall hold.
Effects: Constructs a piecewise_­constant_­distribution object with parameters taken or calculated from the following values: Let for , and for .
Complexity: The number of invocations of fw shall not exceed n.
vector<result_type> intervals() const;
Returns: A vector<result_­type> whose size member returns and whose operator[] member returns when invoked with argument k for .
vector<result_type> densities() const;
Returns: A vector<result_­type> whose size member returns n and whose operator[] member returns when invoked with argument k for .

29.6.8.6.3 Class template piecewise_­linear_­distribution [rand.dist.samp.plinear]

A piecewise_­linear_­distribution random number distribution produces random numbers x, , distributed over each subinterval according to the probability density function

The distribution parameters , also known as this distribution's interval boundaries, shall satisfy the relation for .
Unless specified otherwise, the remaining distribution parameters are calculated as , in which the values , commonly known as the weights at boundaries, shall be non-negative, non-NaN, and non-infinity.
Moreover, the following relation shall hold:

template<class RealType = double>
  class piecewise_linear_distribution {
  public:
    // types
    using result_type = RealType;
    using param_type  = unspecified;

    // constructor and reset functions
    piecewise_linear_distribution();
    template<class InputIteratorB, class InputIteratorW>
      piecewise_linear_distribution(InputIteratorB firstB, InputIteratorB lastB,
                                    InputIteratorW firstW);
    template<class UnaryOperation>
      piecewise_linear_distribution(initializer_list<RealType> bl, UnaryOperation fw);
    template<class UnaryOperation>
      piecewise_linear_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw);
    explicit piecewise_linear_distribution(const param_type& parm);
    void reset();

    // generating functions
    template<class URBG>
      result_type operator()(URBG& g);
    template<class URBG>
      result_type operator()(URBG& g, const param_type& parm);

    // property functions
    vector<result_type> intervals() const;
    vector<result_type> densities() const;
    param_type param() const;
    void param(const param_type& parm);
    result_type min() const;
    result_type max() const;
  };
piecewise_linear_distribution();
Effects: Constructs a piecewise_­linear_­distribution object with , , , and .
template<class InputIteratorB, class InputIteratorW> piecewise_linear_distribution(InputIteratorB firstB, InputIteratorB lastB, InputIteratorW firstW);
Requires: InputIteratorB and InputIteratorW shall each satisfy the requirements of an input iterator (Table 90) type.
Moreover, iterator_­traits<InputIteratorB>​::​value_­type and iterator_­traits<InputIteratorW>​::​value_­type shall each denote a type that is convertible to double.
If firstB == lastB or ++firstB == lastB, let , , , and .
Otherwise, shall form a sequence b of length , the length of the sequence w starting from firstW shall be at least , and any for shall be ignored by the distribution.
Effects: Constructs a piecewise_­linear_­distribution object with parameters as specified above.
template<class UnaryOperation> piecewise_linear_distribution(initializer_list<RealType> bl, UnaryOperation fw);
Requires: Each instance of type UnaryOperation shall be a function object ([function.objects]) whose return type shall be convertible to double.
Moreover, double shall be convertible to the type of UnaryOperation's sole parameter.
Effects: Constructs a piecewise_­linear_­distribution object with parameters taken or calculated from the following values: If , let , , , and .
Otherwise, let form a sequence , and let for .
Complexity: The number of invocations of fw shall not exceed .
template<class UnaryOperation> piecewise_linear_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw);
Requires: Each instance of type UnaryOperation shall be a function object ([function.objects]) whose return type shall be convertible to double.
Moreover, double shall be convertible to the type of UnaryOperation's sole parameter.
If , let , otherwise let .
The relation shall hold.
Effects: Constructs a piecewise_­linear_­distribution object with parameters taken or calculated from the following values: Let for , and for .
Complexity: The number of invocations of fw shall not exceed .
vector<result_type> intervals() const;
Returns: A vector<result_­type> whose size member returns and whose operator[] member returns when invoked with argument k for .
vector<result_type> densities() const;
Returns: A vector<result_­type> whose size member returns n and whose operator[] member returns when invoked with argument k for .

29.6.9 Low-quality random number generation [c.math.rand]

[Note
:
The header <cstdlib> ([cstdlib.syn]) declares the functions described in this subclause.
end note
]
int rand(); void srand(unsigned int seed);
Effects: The rand and srand functions have the semantics specified in the C standard library.
Remarks: The implementation may specify that particular library functions may call rand.
It is implementation-defined whether the rand function may introduce data races ([res.on.data.races]).
[Note
:
The other random number generation facilities in this International Standard ([rand]) are often preferable to rand, because rand's underlying algorithm is unspecified.
Use of rand therefore continues to be non-portable, with unpredictable and oft-questionable quality and performance.
end note
]
See also: ISO C 7.
22.
2

29.7 Numeric arrays [numarray]

29.7.1 Header <valarray> synopsis [valarray.syn]

#include <initializer_list>

namespace std {
  template<class T> class valarray;         // An array of type T
  class slice;                              // a BLAS-like slice out of an array
  template<class T> class slice_array;
  class gslice;                             // a generalized slice out of an array
  template<class T> class gslice_array;
  template<class T> class mask_array;       // a masked array
  template<class T> class indirect_array;   // an indirected array

  template<class T> void swap(valarray<T>&, valarray<T>&) noexcept;

  template<class T> valarray<T> operator* (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator* (const valarray<T>&, const T&);
  template<class T> valarray<T> operator* (const T&, const valarray<T>&);

  template<class T> valarray<T> operator/ (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator/ (const valarray<T>&, const T&);
  template<class T> valarray<T> operator/ (const T&, const valarray<T>&);

  template<class T> valarray<T> operator% (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator% (const valarray<T>&, const T&);
  template<class T> valarray<T> operator% (const T&, const valarray<T>&);

  template<class T> valarray<T> operator+ (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator+ (const valarray<T>&, const T&);
  template<class T> valarray<T> operator+ (const T&, const valarray<T>&);

  template<class T> valarray<T> operator- (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator- (const valarray<T>&, const T&);
  template<class T> valarray<T> operator- (const T&, const valarray<T>&);

  template<class T> valarray<T> operator^ (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator^ (const valarray<T>&, const T&);
  template<class T> valarray<T> operator^ (const T&, const valarray<T>&);

  template<class T> valarray<T> operator& (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator& (const valarray<T>&, const T&);
  template<class T> valarray<T> operator& (const T&, const valarray<T>&);

  template<class T> valarray<T> operator| (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator| (const valarray<T>&, const T&);
  template<class T> valarray<T> operator| (const T&, const valarray<T>&);

  template<class T> valarray<T> operator<<(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator<<(const valarray<T>&, const T&);
  template<class T> valarray<T> operator<<(const T&, const valarray<T>&);

  template<class T> valarray<T> operator>>(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator>>(const valarray<T>&, const T&);
  template<class T> valarray<T> operator>>(const T&, const valarray<T>&);

  template<class T> valarray<bool> operator&&(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator&&(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator&&(const T&, const valarray<T>&);

  template<class T> valarray<bool> operator||(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator||(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator||(const T&, const valarray<T>&);

  template<class T>
    valarray<bool> operator==(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator==(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator==(const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator!=(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator!=(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator!=(const T&, const valarray<T>&);

  template<class T>
    valarray<bool> operator< (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator< (const valarray<T>&, const T&);
  template<class T> valarray<bool> operator< (const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator> (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator> (const valarray<T>&, const T&);
  template<class T> valarray<bool> operator> (const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator<=(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator<=(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator<=(const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator>=(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator>=(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator>=(const T&, const valarray<T>&);

  template<class T> valarray<T> abs  (const valarray<T>&);
  template<class T> valarray<T> acos (const valarray<T>&);
  template<class T> valarray<T> asin (const valarray<T>&);
  template<class T> valarray<T> atan (const valarray<T>&);

  template<class T> valarray<T> atan2(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> atan2(const valarray<T>&, const T&);
  template<class T> valarray<T> atan2(const T&, const valarray<T>&);

  template<class T> valarray<T> cos  (const valarray<T>&);
  template<class T> valarray<T> cosh (const valarray<T>&);
  template<class T> valarray<T> exp  (const valarray<T>&);
  template<class T> valarray<T> log  (const valarray<T>&);
  template<class T> valarray<T> log10(const valarray<T>&);

  template<class T> valarray<T> pow(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> pow(const valarray<T>&, const T&);
  template<class T> valarray<T> pow(const T&, const valarray<T>&);

  template<class T> valarray<T> sin  (const valarray<T>&);
  template<class T> valarray<T> sinh (const valarray<T>&);
  template<class T> valarray<T> sqrt (const valarray<T>&);
  template<class T> valarray<T> tan  (const valarray<T>&);
  template<class T> valarray<T> tanh (const valarray<T>&);

  template <class T> unspecified1 begin(valarray<T>& v);
  template <class T> unspecified2 begin(const valarray<T>& v);
  template <class T> unspecified1 end(valarray<T>& v);
  template <class T> unspecified2 end(const valarray<T>& v);
}
The header <valarray> defines five class templates (valarray, slice_­array, gslice_­array, mask_­array, and indirect_­array), two classes (slice and gslice), and a series of related function templates for representing and manipulating arrays of values.
The valarray array classes are defined to be free of certain forms of aliasing, thus allowing operations on these classes to be optimized.
Any function returning a valarray<T> is permitted to return an object of another type, provided all the const member functions of valarray<T> are also applicable to this type.
This return type shall not add more than two levels of template nesting over the most deeply nested argument type.275
Implementations introducing such replacement types shall provide additional functions and operators as follows:
  • for every function taking a const valarray<T>& other than begin and end ([valarray.range]), identical functions taking the replacement types shall be added;
  • for every function taking two const valarray<T>& arguments, identical functions taking every combination of const valarray<T>& and replacement types shall be added.
In particular, an implementation shall allow a valarray<T> to be constructed from such replacement types and shall allow assignments and compound assignments of such types to valarray<T>, slice_­array<T>, gslice_­array<T>, mask_­array<T> and indirect_­array<T> objects.
These library functions are permitted to throw a bad_­alloc ([bad.alloc]) exception if there are not sufficient resources available to carry out the operation.
Note that the exception is not mandated.
Annex [implimits] recommends a minimum number of recursively nested template instantiations.
This requirement thus indirectly suggests a minimum allowable complexity for valarray expressions.

29.7.2 Class template valarray [template.valarray]

29.7.2.1 Class template valarray overview [template.valarray.overview]

namespace std {
  template<class T> class valarray {
  public:
    using value_type = T;

    // [valarray.cons], construct/destroy
    valarray();
    explicit valarray(size_t);
    valarray(const T&, size_t);
    valarray(const T*, size_t);
    valarray(const valarray&);
    valarray(valarray&&) noexcept;
    valarray(const slice_array<T>&);
    valarray(const gslice_array<T>&);
    valarray(const mask_array<T>&);
    valarray(const indirect_array<T>&);
    valarray(initializer_list<T>);
    ~valarray();

    // [valarray.assign], assignment
    valarray& operator=(const valarray&);
    valarray& operator=(valarray&&) noexcept;
    valarray& operator=(initializer_list<T>);
    valarray& operator=(const T&);
    valarray& operator=(const slice_array<T>&);
    valarray& operator=(const gslice_array<T>&);
    valarray& operator=(const mask_array<T>&);
    valarray& operator=(const indirect_array<T>&);

    // [valarray.access], element access
    const T&          operator[](size_t) const;
    T&                operator[](size_t);

    // [valarray.sub], subset operations
    valarray          operator[](slice) const;
    slice_array<T>    operator[](slice);
    valarray          operator[](const gslice&) const;
    gslice_array<T>   operator[](const gslice&);
    valarray          operator[](const valarray<bool>&) const;
    mask_array<T>     operator[](const valarray<bool>&);
    valarray          operator[](const valarray<size_t>&) const;
    indirect_array<T> operator[](const valarray<size_t>&);

    // [valarray.unary], unary operators
    valarray operator+() const;
    valarray operator-() const;
    valarray operator~() const;
    valarray<bool> operator!() const;

    // [valarray.cassign], compound assignment
    valarray& operator*= (const T&);
    valarray& operator/= (const T&);
    valarray& operator%= (const T&);
    valarray& operator+= (const T&);
    valarray& operator-= (const T&);
    valarray& operator^= (const T&);
    valarray& operator&= (const T&);
    valarray& operator|= (const T&);
    valarray& operator<<=(const T&);
    valarray& operator>>=(const T&);

    valarray& operator*= (const valarray&);
    valarray& operator/= (const valarray&);
    valarray& operator%= (const valarray&);
    valarray& operator+= (const valarray&);
    valarray& operator-= (const valarray&);
    valarray& operator^= (const valarray&);
    valarray& operator|= (const valarray&);
    valarray& operator&= (const valarray&);
    valarray& operator<<=(const valarray&);
    valarray& operator>>=(const valarray&);

    // [valarray.members], member functions
    void swap(valarray&) noexcept;

    size_t size() const;

    T sum() const;
    T min() const;
    T max() const;

    valarray shift (int) const;
    valarray cshift(int) const;
    valarray apply(T func(T)) const;
    valarray apply(T func(const T&)) const;
    void resize(size_t sz, T c = T());
  };

  template<class T, size_t cnt> valarray(const T(&)[cnt], size_t) -> valarray<T>;
}
The class template valarray<T> is a one-dimensional smart array, with elements numbered sequentially from zero.
It is a representation of the mathematical concept of an ordered set of values.
For convenience, an object of type valarray<T> is referred to as an “array” throughout the remainder of [numarray].
The illusion of higher dimensionality may be produced by the familiar idiom of computed indices, together with the powerful subsetting capabilities provided by the generalized subscript operators.276
An implementation is permitted to qualify any of the functions declared in <valarray> as inline.
The intent is to specify an array template that has the minimum functionality necessary to address aliasing ambiguities and the proliferation of temporaries.
Thus, the valarray template is neither a matrix class nor a field class.
However, it is a very useful building block for designing such classes.

29.7.2.2 valarray constructors [valarray.cons]

valarray();
Effects: Constructs a valarray that has zero length.277
explicit valarray(size_t n);
Effects: Constructs a valarray that has length n.
Each element of the array is value-initialized ([dcl.init]).
valarray(const T& v, size_t n);
Effects: Constructs a valarray that has length n.
Each element of the array is initialized with v.
valarray(const T* p, size_t n);
Requires: p points to an array ([dcl.array]) of at least n elements.
Effects: Constructs a valarray that has length n.
The values of the elements of the array are initialized with the first n values pointed to by the first argument.278
valarray(const valarray& v);
Effects: Constructs a valarray that has the same length as v.
The elements are initialized with the values of the corresponding elements of v.279
valarray(valarray&& v) noexcept;
Effects: Constructs a valarray that has the same length as v.
The elements are initialized with the values of the corresponding elements of v.
Complexity: Constant.
valarray(initializer_list<T> il);
Effects: Equivalent to valarray(il.begin(), il.size()).
valarray(const slice_array<T>&); valarray(const gslice_array<T>&); valarray(const mask_array<T>&); valarray(const indirect_array<T>&);
These conversion constructors convert one of the four reference templates to a valarray.
~valarray();
Effects: The destructor is applied to every element of *this; an implementation may return all allocated memory.
This default constructor is essential, since arrays of valarray may be useful.
After initialization, the length of an empty array can be increased with the resize member function.
This constructor is the preferred method for converting a C array to a valarray object.
This copy constructor creates a distinct array rather than an alias.
Implementations in which arrays share storage are permitted, but they shall implement a copy-on-reference mechanism to ensure that arrays are conceptually distinct.

29.7.2.3 valarray assignment [valarray.assign]

valarray& operator=(const valarray& v);
Effects: Each element of the *this array is assigned the value of the corresponding element of v.
If the length of v is not equal to the length of *this, resizes *this to make the two arrays the same length, as if by calling resize(v.size()), before performing the assignment.
Postconditions: size() == v.size().
Returns: *this.
valarray& operator=(valarray&& v) noexcept;
Effects: *this obtains the value of v.
The value of v after the assignment is not specified.
Returns: *this.
Complexity: Linear.
valarray& operator=(initializer_list<T> il);
Effects: Equivalent to: return *this = valarray(il);
valarray& operator=(const T& v);
Effects: Assigns v to each element of *this.
Returns: *this.
valarray& operator=(const slice_array<T>&); valarray& operator=(const gslice_array<T>&); valarray& operator=(const mask_array<T>&); valarray& operator=(const indirect_array<T>&);
Requires: The length of the array to which the argument refers equals size().
The value of an element in the left-hand side of a valarray assignment operator does not depend on the value of another element in that left-hand side.
These operators allow the results of a generalized subscripting operation to be assigned directly to a valarray.

29.7.2.4 valarray element access [valarray.access]

const T& operator[](size_t n) const; T& operator[](size_t n);
Requires: n < size().
Returns: A reference to the corresponding element of the array.
[Note
:
The expression (a[i] = q, a[i]) == q evaluates to true for any non-constant valarray<T> a, any T q, and for any size_­t i such that the value of i is less than the length of a.
end note
]
Remarks: The expression &a[i+j] == &a[i] + j evaluates to true for all size_­t i and size_­t j such that i+j < a.size().
The expression &a[i] != &b[j] evaluates to true for any two arrays a and b and for any size_­t i and size_­t j such that i < a.size() and j < b.size().
[Note
:
This property indicates an absence of aliasing and may be used to advantage by optimizing compilers.
Compilers may take advantage of inlining, constant propagation, loop fusion, tracking of pointers obtained from operator new, and other techniques to generate efficient valarrays.
end note
]
The reference returned by the subscript operator for an array shall be valid until the member function resize(size_­t, T) ([valarray.members]) is called for that array or until the lifetime of that array ends, whichever happens first.

29.7.2.5 valarray subset operations [valarray.sub]

The member operator[] is overloaded to provide several ways to select sequences of elements from among those controlled by *this.
Each of these operations returns a subset of the array.
The const-qualified versions return this subset as a new valarray object.
The non-const versions return a class template object which has reference semantics to the original array, working in conjunction with various overloads of operator= and other assigning operators to allow selective replacement (slicing) of the controlled sequence.
In each case the selected element(s) must exist.
valarray operator[](slice slicearr) const;
Returns: A valarray containing those elements of the controlled sequence designated by slicearr.
[Example
:
const valarray<char> v0("abcdefghijklmnop", 16);
// v0[slice(2, 5, 3)] returns valarray<char>("cfilo", 5)
end example
]
slice_array<T> operator[](slice slicearr);
Returns: An object that holds references to elements of the controlled sequence selected by slicearr.
[Example
:
valarray<char> v0("abcdefghijklmnop", 16);
valarray<char> v1("ABCDE", 5);
v0[slice(2, 5, 3)] = v1;
// v0 == valarray<char>("abAdeBghCjkDmnEp", 16);
end example
]
valarray operator[](const gslice& gslicearr) const;
Returns: A valarray containing those elements of the controlled sequence designated by gslicearr.
[Example
:
const valarray<char> v0("abcdefghijklmnop", 16);
const size_t lv[] = { 2, 3 };
const size_t dv[] = { 7, 2 };
const valarray<size_t> len(lv, 2), str(dv, 2);
// v0[gslice(3, len, str)] returns
// valarray<char>("dfhkmo", 6)
end example
]
gslice_array<T> operator[](const gslice& gslicearr);
Returns: An object that holds references to elements of the controlled sequence selected by gslicearr.
[Example
:
valarray<char> v0("abcdefghijklmnop", 16);
valarray<char> v1("ABCDEF", 6);
const size_t lv[] = { 2, 3 };
const size_t dv[] = { 7, 2 };
const valarray<size_t> len(lv, 2), str(dv, 2);
v0[gslice(3, len, str)] = v1;
// v0 == valarray<char>("abcAeBgCijDlEnFp", 16)
end example
]
valarray operator[](const valarray<bool>& boolarr) const;
Returns: A valarray containing those elements of the controlled sequence designated by boolarr.
[Example
:
const valarray<char> v0("abcdefghijklmnop", 16);
const bool vb[] = { false, false, true, true, false, true };
// v0[valarray<bool>(vb, 6)] returns
// valarray<char>("cdf", 3)
end example
]
mask_array<T> operator[](const valarray<bool>& boolarr);
Returns: An object that holds references to elements of the controlled sequence selected by boolarr.
[Example
:
valarray<char> v0("abcdefghijklmnop", 16);
valarray<char> v1("ABC", 3);
const bool vb[] = { false, false, true, true, false, true };
v0[valarray<bool>(vb, 6)] = v1;
// v0 == valarray<char>("abABeCghijklmnop", 16)
end example
]
valarray operator[](const valarray<size_t>& indarr) const;
Returns: A valarray containing those elements of the controlled sequence designated by indarr.
[Example
:
const valarray<char> v0("abcdefghijklmnop", 16);
const size_t vi[] = { 7, 5, 2, 3, 8 };
// v0[valarray<size_­t>(vi, 5)] returns
// valarray<char>("hfcdi", 5)
end example
]
indirect_array<T> operator[](const valarray<size_t>& indarr);
Returns: An object that holds references to elements of the controlled sequence selected by indarr.
[Example
:
valarray<char> v0("abcdefghijklmnop", 16);
valarray<char> v1("ABCDE", 5);
const size_t vi[] = { 7, 5, 2, 3, 8 };
v0[valarray<size_t>(vi, 5)] = v1;
// v0 == valarray<char>("abCDeBgAEjklmnop", 16)
end example
]

29.7.2.6 valarray unary operators [valarray.unary]

valarray operator+() const; valarray operator-() const; valarray operator~() const; valarray<bool> operator!() const;
Requires: Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type T (bool for operator!) or which may be unambiguously implicitly converted to type T (bool for operator!).
Returns: A valarray whose length is size().
Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding element of the array.

29.7.2.7 valarray compound assignment [valarray.cassign]

valarray& operator*= (const valarray& v); valarray& operator/= (const valarray& v); valarray& operator%= (const valarray& v); valarray& operator+= (const valarray& v); valarray& operator-= (const valarray& v); valarray& operator^= (const valarray& v); valarray& operator&= (const valarray& v); valarray& operator|= (const valarray& v); valarray& operator<<=(const valarray& v); valarray& operator>>=(const valarray& v);
Requires: size() == v.size().
Each of these operators may only be instantiated for a type T if the indicated operator can be applied to two operands of type T.
The value of an element in the left-hand side of a valarray compound assignment operator does not depend on the value of another element in that left hand side.
Effects: Each of these operators performs the indicated operation on each of the elements of *this and the corresponding element of v.
Returns: *this.
Remarks: The appearance of an array on the left-hand side of a compound assignment does not invalidate references or pointers.
valarray& operator*= (const T& v); valarray& operator/= (const T& v); valarray& operator%= (const T& v); valarray& operator+= (const T& v); valarray& operator-= (const T& v); valarray& operator^= (const T& v); valarray& operator&= (const T& v); valarray& operator|= (const T& v); valarray& operator<<=(const T& v); valarray& operator>>=(const T& v);
Requires: Each of these operators may only be instantiated for a type T if the indicated operator can be applied to two operands of type T.
Effects: Each of these operators applies the indicated operation to each element of *this and v.
Returns: *this
Remarks: The appearance of an array on the left-hand side of a compound assignment does not invalidate references or pointers to the elements of the array.

29.7.2.8 valarray member functions [valarray.members]

void swap(valarray& v) noexcept;
Effects: *this obtains the value of v.
v obtains the value of *this.
Complexity: Constant.
size_t size() const;
Returns: The number of elements in the array.
Complexity: Constant time.
T sum() const;
Requires: size() > 0.
This function may only be instantiated for a type T to which operator+= can be applied.
Returns: The sum of all the elements of the array.
If the array has length 1, returns the value of element 0.
Otherwise, the returned value is calculated by applying operator+= to a copy of an element of the array and all other elements of the array in an unspecified order.
T min() const;
Requires: size() > 0
Returns: The minimum value contained in *this.
For an array of length 1, the value of element 0 is returned.
For all other array lengths, the determination is made using operator<.
T max() const;
Requires: size() > 0.
Returns: The maximum value contained in *this.
For an array of length 1, the value of element 0 is returned.
For all other array lengths, the determination is made using operator<.
valarray shift(int n) const;
Returns: A valarray of length size(), each of whose elements I is (*this)[I + n] if I + n is non-negative and less than size(), otherwise T().
[Note
:
If element zero is taken as the leftmost element, a positive value of n shifts the elements left n places, with zero fill.
end note
]
[Example
:
If the argument has the value -2, the first two elements of the result will be value-initialized ([dcl.init]); the third element of the result will be assigned the value of the first element of the argument; etc.
end example
]
valarray cshift(int n) const;
Returns: A valarray of length size() that is a circular shift of *this.
If element zero is taken as the leftmost element, a non-negative value of n shifts the elements circularly left n places and a negative value of n shifts the elements circularly right places.
valarray apply(T func(T)) const; valarray apply(T func(const T&)) const;
Returns: A valarray whose length is size().
Each element of the returned array is assigned the value returned by applying the argument function to the corresponding element of *this.
void resize(size_t sz, T c = T());
Effects: Changes the length of the *this array to sz and then assigns to each element the value of the second argument.
Resizing invalidates all pointers and references to elements in the array.

29.7.3 valarray non-member operations [valarray.nonmembers]

29.7.3.1 valarray binary operators [valarray.binary]

template<class T> valarray<T> operator* (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator/ (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator% (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator+ (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator- (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator^ (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator& (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator| (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator<< (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> operator>> (const valarray<T>&, const valarray<T>&);
Requires: Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type T or which can be unambiguously implicitly converted to type T.
The argument arrays have the same length.
Returns: A valarray whose length is equal to the lengths of the argument arrays.
Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding elements of the argument arrays.
template<class T> valarray<T> operator* (const valarray<T>&, const T&); template<class T> valarray<T> operator* (const T&, const valarray<T>&); template<class T> valarray<T> operator/ (const valarray<T>&, const T&); template<class T> valarray<T> operator/ (const T&, const valarray<T>&); template<class T> valarray<T> operator% (const valarray<T>&, const T&); template<class T> valarray<T> operator% (const T&, const valarray<T>&); template<class T> valarray<T> operator+ (const valarray<T>&, const T&); template<class T> valarray<T> operator+ (const T&, const valarray<T>&); template<class T> valarray<T> operator- (const valarray<T>&, const T&); template<class T> valarray<T> operator- (const T&, const valarray<T>&); template<class T> valarray<T> operator^ (const valarray<T>&, const T&); template<class T> valarray<T> operator^ (const T&, const valarray<T>&); template<class T> valarray<T> operator& (const valarray<T>&, const T&); template<class T> valarray<T> operator& (const T&, const valarray<T>&); template<class T> valarray<T> operator| (const valarray<T>&, const T&); template<class T> valarray<T> operator| (const T&, const valarray<T>&); template<class T> valarray<T> operator<<(const valarray<T>&, const T&); template<class T> valarray<T> operator<<(const T&, const valarray<T>&); template<class T> valarray<T> operator>>(const valarray<T>&, const T&); template<class T> valarray<T> operator>>(const T&, const valarray<T>&);
Requires: Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type T or which can be unambiguously implicitly converted to type T.
Returns: A valarray whose length is equal to the length of the array argument.
Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding element of the array argument and the non-array argument.

29.7.3.2 valarray logical operators [valarray.comparison]

template<class T> valarray<bool> operator== (const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator!= (const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator< (const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator> (const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator<= (const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator>= (const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator&& (const valarray<T>&, const valarray<T>&); template<class T> valarray<bool> operator|| (const valarray<T>&, const valarray<T>&);
Requires: Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type bool or which can be unambiguously implicitly converted to type bool.
The two array arguments have the same length.
Returns: A valarray<bool> whose length is equal to the length of the array arguments.
Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding elements of the argument arrays.
template<class T> valarray<bool> operator==(const valarray<T>&, const T&); template<class T> valarray<bool> operator==(const T&, const valarray<T>&); template<class T> valarray<bool> operator!=(const valarray<T>&, const T&); template<class T> valarray<bool> operator!=(const T&, const valarray<T>&); template<class T> valarray<bool> operator< (const valarray<T>&, const T&); template<class T> valarray<bool> operator< (const T&, const valarray<T>&); template<class T> valarray<bool> operator> (const valarray<T>&, const T&); template<class T> valarray<bool> operator> (const T&, const valarray<T>&); template<class T> valarray<bool> operator<=(const valarray<T>&, const T&); template<class T> valarray<bool> operator<=(const T&, const valarray<T>&); template<class T> valarray<bool> operator>=(const valarray<T>&, const T&); template<class T> valarray<bool> operator>=(const T&, const valarray<T>&); template<class T> valarray<bool> operator&&(const valarray<T>&, const T&); template<class T> valarray<bool> operator&&(const T&, const valarray<T>&); template<class T> valarray<bool> operator||(const valarray<T>&, const T&); template<class T> valarray<bool> operator||(const T&, const valarray<T>&);
Requires: Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type bool or which can be unambiguously implicitly converted to type bool.
Returns: A valarray<bool> whose length is equal to the length of the array argument.
Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding element of the array and the non-array argument.

29.7.3.3 valarray transcendentals [valarray.transcend]

template<class T> valarray<T> abs (const valarray<T>&); template<class T> valarray<T> acos (const valarray<T>&); template<class T> valarray<T> asin (const valarray<T>&); template<class T> valarray<T> atan (const valarray<T>&); template<class T> valarray<T> atan2 (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> atan2(const valarray<T>&, const T&); template<class T> valarray<T> atan2(const T&, const valarray<T>&); template<class T> valarray<T> cos (const valarray<T>&); template<class T> valarray<T> cosh (const valarray<T>&); template<class T> valarray<T> exp (const valarray<T>&); template<class T> valarray<T> log (const valarray<T>&); template<class T> valarray<T> log10(const valarray<T>&); template<class T> valarray<T> pow (const valarray<T>&, const valarray<T>&); template<class T> valarray<T> pow (const valarray<T>&, const T&); template<class T> valarray<T> pow (const T&, const valarray<T>&); template<class T> valarray<T> sin (const valarray<T>&); template<class T> valarray<T> sinh (const valarray<T>&); template<class T> valarray<T> sqrt (const valarray<T>&); template<class T> valarray<T> tan (const valarray<T>&); template<class T> valarray<T> tanh (const valarray<T>&);
Requires: Each of these functions may only be instantiated for a type T to which a unique function with the indicated name can be applied (unqualified).
This function shall return a value which is of type T or which can be unambiguously implicitly converted to type T.

29.7.3.4 valarray specialized algorithms [valarray.special]

template <class T> void swap(valarray<T>& x, valarray<T>& y) noexcept;
Effects: Equivalent to x.swap(y).

29.7.4 Class slice [class.slice]

29.7.4.1 Class slice overview [class.slice.overview]

namespace std {
  class slice {
  public:
    slice();
    slice(size_t, size_t, size_t);

    size_t start() const;
    size_t size() const;
    size_t stride() const;
  };
}
The slice class represents a BLAS-like slice from an array.
Such a slice is specified by a starting index, a length, and a stride.280
BLAS stands for Basic Linear Algebra Subprograms. C++ programs may instantiate this class.
See, for example, Dongarra, Du Croz, Duff, and Hammerling: A set of Level 3 Basic Linear Algebra Subprograms; Technical Report MCS-P1-0888, Argonne National Laboratory (USA), Mathematics and Computer Science Division, August, 1988.

29.7.4.2 slice constructors [cons.slice]

slice(); slice(size_t start, size_t length, size_t stride); slice(const slice&);
The default constructor is equivalent to slice(0, 0, 0).
A default constructor is provided only to permit the declaration of arrays of slices.
The constructor with arguments for a slice takes a start, length, and stride parameter.
[Example
:
slice(3, 8, 2) constructs a slice which selects elements 3, 5, 7, .
17 from an array.
end example
]

29.7.4.3 slice access functions [slice.access]

size_t start() const; size_t size() const; size_t stride() const;
Returns: The start, length, or stride specified by a slice object.
Complexity: Constant time.

29.7.5 Class template slice_­array [template.slice.array]

29.7.5.1 Class template slice_­array overview [template.slice.array.overview]

namespace std {
  template <class T> class slice_array {
  public:
    using value_type = T;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;

    slice_array(const slice_array&);
    ~slice_array();
    const slice_array& operator=(const slice_array&) const;
    void operator=(const T&) const;

    slice_array() = delete;       // as implied by declaring copy constructor above
  };
}
The slice_­array template is a helper template used by the slice subscript operator
slice_array<T> valarray<T>::operator[](slice);
It has reference semantics to a subset of an array specified by a slice object.
[Example
:
The expression a[slice(1, 5, 3)] = b; has the effect of assigning the elements of b to a slice of the elements in a.
For the slice shown, the elements selected from a are 1, 4, .
, 13.
end example
]

29.7.5.2 slice_­array assignment [slice.arr.assign]

void operator=(const valarray<T>&) const; const slice_array& operator=(const slice_array&) const;
These assignment operators have reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which the slice_­array object refers.

29.7.5.3 slice_­array compound assignment [slice.arr.comp.assign]

void operator*= (const valarray<T>&) const; void operator/= (const valarray<T>&) const; void operator%= (const valarray<T>&) const; void operator+= (const valarray<T>&) const; void operator-= (const valarray<T>&) const; void operator^= (const valarray<T>&) const; void operator&= (const valarray<T>&) const; void operator|= (const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const;
These compound assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the slice_­array object refers.

29.7.5.4 slice_­array fill function [slice.arr.fill]

void operator=(const T&) const;
This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the slice_­array object refers.

29.7.6 The gslice class [class.gslice]

29.7.6.1 The gslice class overview [class.gslice.overview]

namespace std {
  class gslice {
  public:
    gslice();
    gslice(size_t s, const valarray<size_t>& l, const valarray<size_t>& d);

    size_t           start() const;
    valarray<size_t> size() const;
    valarray<size_t> stride() const;
  };
}
This class represents a generalized slice out of an array.
A gslice is defined by a starting offset (s), a set of lengths (), and a set of strides ().
The number of lengths shall equal the number of strides.
A gslice represents a mapping from a set of indices (), equal in number to the number of strides, to a single index k.
It is useful for building multidimensional array classes using the valarray template, which is one-dimensional.
The set of one-dimensional index values specified by a gslice are

where the multidimensional indices range in value from 0 to .

[Example
:
The gslice specification
start  = 3
length = {2, 4, 3}
stride = {19, 4, 1}
yields the sequence of one-dimensional indices

which are ordered as shown in the following table:

	
		,    
		,    
		,    
		,    
		,    
		,    
		, 
		, 
		, 
		, 
		, 
		, 
		, 
		, 
		      
		
That is, the highest-ordered index turns fastest.
end example
]
It is possible to have degenerate generalized slices in which an address is repeated.
[Example
:
If the stride parameters in the previous example are changed to {1, 1, 1}, the first few elements of the resulting sequence of indices will be
	,  
	,  
	,  
	,  
	,  
	,  
	
end example
]
If a degenerate slice is used as the argument to the non-const version of operator[](const gslice&), the behavior is undefined.

29.7.6.2 gslice constructors [gslice.cons]

gslice(); gslice(size_t start, const valarray<size_t>& lengths, const valarray<size_t>& strides); gslice(const gslice&);
The default constructor is equivalent to gslice(0, valarray<size_­t>(), valarray<size_­t>()).
The constructor with arguments builds a gslice based on a specification of start, lengths, and strides, as explained in the previous section.

29.7.6.3 gslice access functions [gslice.access]

size_t start() const; valarray<size_t> size() const; valarray<size_t> stride() const;
Returns: The representation of the start, lengths, or strides specified for the gslice.
Complexity: start() is constant time.
size() and stride() are linear in the number of strides.

29.7.7 Class template gslice_­array [template.gslice.array]

29.7.7.1 Class template gslice_­array overview [template.gslice.array.overview]

namespace std {
  template <class T> class gslice_array {
  public:
    using value_type = T;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;

    gslice_array(const gslice_array&);
    ~gslice_array();
    const gslice_array& operator=(const gslice_array&) const;
    void operator=(const T&) const;

    gslice_array() = delete;      // as implied by declaring copy constructor above
  };
}
This template is a helper template used by the slice subscript operator
gslice_array<T> valarray<T>::operator[](const gslice&);
It has reference semantics to a subset of an array specified by a gslice object.
Thus, the expression a[gslice(1, length, stride)] = b has the effect of assigning the elements of b to a generalized slice of the elements in a.

29.7.7.2 gslice_­array assignment [gslice.array.assign]

void operator=(const valarray<T>&) const; const gslice_array& operator=(const gslice_array&) const;
These assignment operators have reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which the gslice_­array refers.

29.7.7.3 gslice_­array compound assignment [gslice.array.comp.assign]

void operator*= (const valarray<T>&) const; void operator/= (const valarray<T>&) const; void operator%= (const valarray<T>&) const; void operator+= (const valarray<T>&) const; void operator-= (const valarray<T>&) const; void operator^= (const valarray<T>&) const; void operator&= (const valarray<T>&) const; void operator|= (const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const;
These compound assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the gslice_­array object refers.

29.7.7.4 gslice_­array fill function [gslice.array.fill]

void operator=(const T&) const;
This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the gslice_­array object refers.

29.7.8 Class template mask_­array [template.mask.array]

29.7.8.1 Class template mask_­array overview [template.mask.array.overview]

namespace std {
  template <class T> class mask_array {
  public:
    using value_type = T;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;

    mask_array(const mask_array&);
    ~mask_array();
    const mask_array& operator=(const mask_array&) const;
    void operator=(const T&) const;

    mask_array() = delete;        // as implied by declaring copy constructor above
  };
}
This template is a helper template used by the mask subscript operator:
mask_array<T> valarray<T>::operator[](const valarray<bool>&).
It has reference semantics to a subset of an array specified by a boolean mask.
Thus, the expression a[mask] = b; has the effect of assigning the elements of b to the masked elements in a (those for which the corresponding element in mask is true.)

29.7.8.2 mask_­array assignment [mask.array.assign]

void operator=(const valarray<T>&) const; const mask_array& operator=(const mask_array&) const;
These assignment operators have reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which it refers.

29.7.8.3 mask_­array compound assignment [mask.array.comp.assign]

void operator*= (const valarray<T>&) const; void operator/= (const valarray<T>&) const; void operator%= (const valarray<T>&) const; void operator+= (const valarray<T>&) const; void operator-= (const valarray<T>&) const; void operator^= (const valarray<T>&) const; void operator&= (const valarray<T>&) const; void operator|= (const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const;
These compound assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the mask object refers.

29.7.8.4 mask_­array fill function [mask.array.fill]

void operator=(const T&) const;
This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the mask_­array object refers.

29.7.9 Class template indirect_­array [template.indirect.array]

29.7.9.1 Class template indirect_­array overview [template.indirect.array.overview]

namespace std {
  template <class T> class indirect_array {
  public:
    using value_type = T;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;

    indirect_array(const indirect_array&);
    ~indirect_array();
    const indirect_array& operator=(const indirect_array&) const;
    void operator=(const T&) const;

    indirect_array() = delete;        // as implied by declaring copy constructor above
  };
}
This template is a helper template used by the indirect subscript operator
indirect_array<T> valarray<T>::operator[](const valarray<size_t>&).
It has reference semantics to a subset of an array specified by an indirect_­array.
Thus the expression a[​indirect] = b; has the effect of assigning the elements of b to the elements in a whose indices appear in indirect.

29.7.9.2 indirect_­array assignment [indirect.array.assign]

void operator=(const valarray<T>&) const; const indirect_array& operator=(const indirect_array&) const;
These assignment operators have reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which it refers.
If the indirect_­array specifies an element in the valarray<T> object to which it refers more than once, the behavior is undefined.
[Example
:
int addr[] = {2, 3, 1, 4, 4};
valarray<size_t> indirect(addr, 5);
valarray<double> a(0., 10), b(1., 5);
a[indirect] = b;
results in undefined behavior since element 4 is specified twice in the indirection.
end example
]

29.7.9.3 indirect_­array compound assignment [indirect.array.comp.assign]

void operator*= (const valarray<T>&) const; void operator/= (const valarray<T>&) const; void operator%= (const valarray<T>&) const; void operator+= (const valarray<T>&) const; void operator-= (const valarray<T>&) const; void operator^= (const valarray<T>&) const; void operator&= (const valarray<T>&) const; void operator|= (const valarray<T>&) const; void operator<<=(const valarray<T>&) const; void operator>>=(const valarray<T>&) const;
These compound assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the indirect_­array object refers.
If the indirect_­array specifies an element in the valarray<T> object to which it refers more than once, the behavior is undefined.

29.7.9.4 indirect_­array fill function [indirect.array.fill]

void operator=(const T&) const;
This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the indirect_­array object refers.

29.7.10 valarray range access [valarray.range]

In the begin and end function templates that follow, unspecified1 is a type that meets the requirements of a mutable random access iterator ([random.access.iterators]) and of a contiguous iterator ([iterator.requirements.general]) whose value_­type is the template parameter T and whose reference type is T&.
unspecified2 is a type that meets the requirements of a constant random access iterator ([random.access.iterators]) and of a contiguous iterator ([iterator.requirements.general]) whose value_­type is the template parameter T and whose reference type is const T&.
The iterators returned by begin and end for an array are guaranteed to be valid until the member function resize(size_­t, T) ([valarray.members]) is called for that array or until the lifetime of that array ends, whichever happens first.
template <class T> unspecified1 begin(valarray<T>& v); template <class T> unspecified2 begin(const valarray<T>& v);
Returns: An iterator referencing the first value in the array.
template <class T> unspecified1 end(valarray<T>& v); template <class T> unspecified2 end(const valarray<T>& v);
Returns: An iterator referencing one past the last value in the array.

29.8 Generalized numeric operations [numeric.ops]

29.8.1 Header <numeric> synopsis [numeric.ops.overview]

namespace std {
  // [accumulate], accumulate
  template <class InputIterator, class T>
    T accumulate(InputIterator first, InputIterator last, T init);
  template <class InputIterator, class T, class BinaryOperation>
    T accumulate(InputIterator first, InputIterator last, T init,
                 BinaryOperation binary_op);

  // [reduce], reduce
  template<class InputIterator>
    typename iterator_traits<InputIterator>::value_type
      reduce(InputIterator first, InputIterator last);
  template<class InputIterator, class T>
    T reduce(InputIterator first, InputIterator last, T init);
  template<class InputIterator, class T, class BinaryOperation>
    T reduce(InputIterator first, InputIterator last, T init,
             BinaryOperation binary_op);
  template<class ExecutionPolicy, class ForwardIterator>
    typename iterator_traits<ForwardIterator>::value_type
      reduce(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
             ForwardIterator first, ForwardIterator last);
  template<class ExecutionPolicy, class ForwardIterator, class T>
    T reduce(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
             ForwardIterator first, ForwardIterator last, T init);
  template<class ExecutionPolicy, class ForwardIterator, class T, class BinaryOperation>
    T reduce(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
             ForwardIterator first, ForwardIterator last, T init,
             BinaryOperation binary_op);

  // [inner.product], inner product
  template <class InputIterator1, class InputIterator2, class T>
    T inner_product(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, T init);
  template <class InputIterator1, class InputIterator2, class T,
            class BinaryOperation1, class BinaryOperation2>
    T inner_product(InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, T init,
                    BinaryOperation1 binary_op1,
                    BinaryOperation2 binary_op2);

  // [transform.reduce], transform reduce
  template<class InputIterator1, class InputIterator2, class T>
    T transform_reduce(InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2,
                       T init);
  template<class InputIterator1, class InputIterator2, class T,
           class BinaryOperation1, class BinaryOperation2>
    T transform_reduce(InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2,
                       T init,
                       BinaryOperation1 binary_op1,
                       BinaryOperation2 binary_op2);
  template<class InputIterator, class T,
           class BinaryOperation, class UnaryOperation>
    T transform_reduce(InputIterator first, InputIterator last,
                       T init,
                       BinaryOperation binary_op, UnaryOperation unary_op);
  template<class ExecutionPolicy,
           class ForwardIterator1, class ForwardIterator2, class T>
    T transform_reduce(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                       ForwardIterator1 first1, ForwardIterator1 last1,
                       ForwardIterator2 first2,
                       T init);
  template<class ExecutionPolicy,
           class ForwardIterator1, class ForwardIterator2, class T,
           class BinaryOperation1, class BinaryOperation2>
    T transform_reduce(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                       ForwardIterator1 first1, ForwardIterator1 last1,
                       ForwardIterator2 first2,
                       T init,
                       BinaryOperation1 binary_op1,
                       BinaryOperation2 binary_op2);
  template<class ExecutionPolicy,
           class ForwardIterator, class T,
           class BinaryOperation, class UnaryOperation>
    T transform_reduce(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                       ForwardIterator first, ForwardIterator last,
                       T init,
                       BinaryOperation binary_op, UnaryOperation unary_op);

  // [partial.sum], partial sum
  template <class InputIterator, class OutputIterator>
    OutputIterator partial_sum(InputIterator first,
                               InputIterator last,
                               OutputIterator result);
  template <class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator partial_sum(InputIterator first,
                               InputIterator last,
                               OutputIterator result,
                               BinaryOperation binary_op);

  // [exclusive.scan], exclusive scan
  template<class InputIterator, class OutputIterator, class T>
    OutputIterator exclusive_scan(InputIterator first, InputIterator last,
                                  OutputIterator result,
                                  T init);
  template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
    OutputIterator exclusive_scan(InputIterator first, InputIterator last,
                                  OutputIterator result,
                                  T init, BinaryOperation binary_op);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T>
    ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator1 first, ForwardIterator1 last,
                                    ForwardIterator2 result,
                                    T init);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T,
           class BinaryOperation>
    ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator1 first, ForwardIterator1 last,
                                    ForwardIterator2 result,
                                    T init, BinaryOperation binary_op);

  // [inclusive.scan], inclusive scan
  template<class InputIterator, class OutputIterator>
    OutputIterator inclusive_scan(InputIterator first, InputIterator last,
                                  OutputIterator result);
  template<class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator inclusive_scan(InputIterator first, InputIterator last,
                                  OutputIterator result,
                                  BinaryOperation binary_op);
  template<class InputIterator, class OutputIterator, class BinaryOperation, class T>
    OutputIterator inclusive_scan(InputIterator first, InputIterator last,
                                  OutputIterator result,
                                  BinaryOperation binary_op, T init);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator1 first, ForwardIterator1 last,
                                    ForwardIterator2 result);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryOperation>
    ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator1 first, ForwardIterator1 last,
                                    ForwardIterator2 result,
                                    BinaryOperation binary_op);
  template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
           class BinaryOperation, class T>
    ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                    ForwardIterator1 first, ForwardIterator1 last,
                                    ForwardIterator2 result,
                                    BinaryOperation binary_op, T init);

  // [transform.exclusive.scan], transform exclusive scan
  template<class InputIterator, class OutputIterator, class T,
           class BinaryOperation, class UnaryOperation>
    OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last,
                                            OutputIterator result,
                                            T init,
                                            BinaryOperation binary_op,
                                            UnaryOperation unary_op);
  template<class ExecutionPolicy,
           class ForwardIterator1, class ForwardIterator2, class T,
           class BinaryOperation, class UnaryOperation>
    ForwardIterator2 transform_exclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                              ForwardIterator1 first, ForwardIterator1 last,
                                              ForwardIterator2 result,
                                              T init,
                                              BinaryOperation binary_op,
                                              UnaryOperation unary_op);

  // [transform.inclusive.scan], transform inclusive scan
  template<class InputIterator, class OutputIterator,
           class BinaryOperation, class UnaryOperation>
    OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last,
                                            OutputIterator result,
                                            BinaryOperation binary_op,
                                            UnaryOperation unary_op);
  template<class InputIterator, class OutputIterator,
           class BinaryOperation, class UnaryOperation, class T>
    OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last,
                                            OutputIterator result,
                                            BinaryOperation binary_op,
                                            UnaryOperation unary_op,
                                            T init);
  template<class ExecutionPolicy,
           class ForwardIterator1, class ForwardIterator2,
           class BinaryOperation, class UnaryOperation>
    ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                              ForwardIterator1 first, ForwardIterator1 last,
                                              ForwardIterator2 result,
                                              BinaryOperation binary_op,
                                              UnaryOperation unary_op);
  template<class ExecutionPolicy,
           class ForwardIterator1, class ForwardIterator2,
           class BinaryOperation, class UnaryOperation, class T>
    ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                              ForwardIterator1 first, ForwardIterator1 last,
                                              ForwardIterator2 result,
                                              BinaryOperation binary_op,
                                              UnaryOperation unary_op,
                                              T init);

  // [adjacent.difference], adjacent difference
  template <class InputIterator, class OutputIterator>
    OutputIterator adjacent_difference(InputIterator first,
                                       InputIterator last,
                                       OutputIterator result);
  template <class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator adjacent_difference(InputIterator first,
                                       InputIterator last,
                                       OutputIterator result,
                                       BinaryOperation binary_op);
  template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
    ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         ForwardIterator1 first,
                                         ForwardIterator1 last,
                                         ForwardIterator2 result);
  template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
            class BinaryOperation>
    ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see [algorithms.parallel.overloads]
                                         ForwardIterator1 first,
                                         ForwardIterator1 last,
                                         ForwardIterator2 result,
                                         BinaryOperation binary_op);

  // [numeric.iota], iota
  template <class ForwardIterator, class T>
    void iota(ForwardIterator first, ForwardIterator last, T value);

  // [numeric.ops.gcd], greatest common divisor
  template <class M, class N>
    constexpr common_type_t<M,N> gcd(M m, N n);

  // [numeric.ops.lcm], least common multiple
  template <class M, class N>
    constexpr common_type_t<M,N> lcm(M m, N n);
}
The requirements on the types of algorithms' arguments that are described in the introduction to Clause [algorithms] also apply to the following algorithms.
Throughout this subclause, the parameters UnaryOperation, BinaryOperation, BinaryOperation1, and BinaryOperation2 are used whenever an algorithm expects a function object ([function.objects]).
[Note
:
The use of closed ranges as well as semi-open ranges to specify requirements throughout this subclause is intentional.
end note
]

29.8.2 Accumulate [accumulate]

template <class InputIterator, class T> T accumulate(InputIterator first, InputIterator last, T init); template <class InputIterator, class T, class BinaryOperation> T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
Requires: T shall meet the requirements of CopyConstructible (Table 24) and CopyAssignable (Table 26) types.
In the range [first, last], binary_­op shall neither modify elements nor invalidate iterators or subranges.281
Effects: Computes its result by initializing the accumulator acc with the initial value init and then modifies it with acc = acc + *i or acc = binary_­op(acc, *i) for every iterator i in the range [first, last) in order.282
The use of fully closed ranges is intentional.
accumulate is similar to the APL reduction operator and Common Lisp reduce function, but it avoids the difficulty of defining the result of reduction on an empty sequence by always requiring an initial value.

29.8.3 Reduce [reduce]

template<class InputIterator> typename iterator_traits<InputIterator>::value_type reduce(InputIterator first, InputIterator last);
Effects: Equivalent to:
return reduce(first, last,
              typename iterator_traits<InputIterator>::value_type{});
template<class ExecutionPolicy, class ForwardIterator> typename iterator_traits<ForwardIterator>::value_type reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last);
Effects: Equivalent to:
return reduce(std::forward<ExecutionPolicy>(exec), first, last,
              typename iterator_traits<ForwardIterator>::value_type{});
template<class InputIterator, class T> T reduce(InputIterator first, InputIterator last, T init);
Effects: Equivalent to:
return reduce(first, last, init, plus<>());
template<class ExecutionPolicy, class ForwardIterator, class T> T reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init);
Effects: Equivalent to:
return reduce(std::forward<ExecutionPolicy>(exec), first, last, init, plus<>());
template<class InputIterator, class T, class BinaryOperation> T reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); template<class ExecutionPolicy, class ForwardIterator, class T, class BinaryOperation> T reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op);
Requires:
  • T shall be MoveConstructible (Table 23).
  • All of binary_­op(init, *first), binary_­op(*first, init), binary_­op(init, init), and binary_­op(*first, *first) shall be convertible to T.
  • binary_­op shall neither invalidate iterators or subranges, nor modify elements in the range [first, last].
Returns: GENERALIZED_­SUM(binary_­op, init, *i, ...) for every i in [first, last).
Complexity: applications of binary_­op.
[Note
:
The difference between reduce and accumulate is that reduce applies binary_­op in an unspecified order, which yields a nondeterministic result for non-associative or non-commutative binary_­op such as floating-point addition.
end note
]

29.8.4 Inner product [inner.product]

template <class InputIterator1, class InputIterator2, class T> T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
Requires: T shall meet the requirements of CopyConstructible (Table 24) and CopyAssignable (Table 26) types.
In the ranges [first1, last1] and [first2, first2 + (last1 - first1)] binary_­op1 and binary_­op2 shall neither modify elements nor invalidate iterators or subranges.283
Effects: Computes its result by initializing the accumulator acc with the initial value init and then modifying it with acc = acc + (*i1) * (*i2) or acc = binary_­op1(acc, binary_­op2(*i1, *i2)) for every iterator i1 in the range [first1, last1) and iterator i2 in the range [first2, first2 + (last1 - first1)) in order.
The use of fully closed ranges is intentional.

29.8.5 Transform reduce [transform.reduce]

template <class InputIterator1, class InputIterator2, class T> T transform_reduce(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T> T transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init);
Effects: Equivalent to:
return transform_reduce(first1, last1, first2, init, plus<>(), multiplies<>());
template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> T transform_reduce(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T, class BinaryOperation1, class BinaryOperation2> T transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
Requires:
  • T shall be MoveConstructible (Table 23).
  • All of
    • binary_­op1(init, init),
    • binary_­op1(init, binary_­op2(*first1, *first2)),
    • binary_­op1(binary_­op2(*first1, *first2), init), and
    • binary_­op1(binary_­op2(*first1, *first2), binary_­op2(*first1, *first2))
    shall be convertible to T.
  • Neither binary_­op1 nor binary_­op2 shall invalidate subranges, or modify elements in the ranges [first1, last1] and [first2, first2 + (last1 - first1)].
Returns:
GENERALIZED_SUM(binary_op1, init, binary_op2(*i, *(first2 + (i - first1))), ...)
for every iterator i in [first1, last1).
Complexity: applications each of binary_­op1 and binary_­op2.
template<class InputIterator, class T, class BinaryOperation, class UnaryOperation> T transform_reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op, UnaryOperation unary_op); template<class ExecutionPolicy, class ForwardIterator, class T, class BinaryOperation, class UnaryOperation> T transform_reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op, UnaryOperation unary_op);
Requires:
  • T shall be MoveConstructible (Table 23).
  • All of
    • binary_­op(init, init),
    • binary_­op(init, unary_­op(*first)),
    • binary_­op(unary_­op(*first), init), and
    • binary_­op(unary_­op(*first), unary_­op(*first))
    shall be convertible to T.
  • Neither unary_­op nor binary_­op shall invalidate subranges, or modify elements in the range [first, last].
Returns:
GENERALIZED_SUM(binary_op, init, unary_op(*i), ...)
for every iterator i in [first, last).
Complexity: applications each of unary_­op and binary_­op.
[Note
:
transform_­reduce does not apply unary_­op to init.
end note
]

29.8.6 Partial sum [partial.sum]

template <class InputIterator, class OutputIterator> OutputIterator partial_sum( InputIterator first, InputIterator last, OutputIterator result); template <class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator partial_sum( InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
Requires: InputIterator's value type shall be constructible from the type of *first.
The result of the expression acc + *i or binary_­op(acc, *i) shall be implicitly convertible to InputIterator's value type.
acc shall be writable ([iterator.requirements.general]) to the result output iterator.
In the ranges [first, last] and [result, result + (last - first)] binary_­op shall neither modify elements nor invalidate iterators or subranges.284
Effects: For a non-empty range, the function creates an accumulator acc whose type is InputIterator's value type, initializes it with *first, and assigns the result to *result.
For every iterator i in [first + 1, last) in order, acc is then modified by acc = acc + *i or acc = binary_­op(acc, *i) and the result is assigned to *(result + (i - first)).
Returns: result + (last - first).
Complexity: Exactly (last - first) - 1 applications of the binary operation.
Remarks: result may be equal to first.
The use of fully closed ranges is intentional.

29.8.7 Exclusive scan [exclusive.scan]

template<class InputIterator, class OutputIterator, class T> OutputIterator exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, T init);
Effects: Equivalent to:
return exclusive_scan(first, last, result, init, plus<>());
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T> ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init);
Effects: Equivalent to:
return exclusive_scan(std::forward<ExecutionPolicy>(exec),
                      first, last, result, init, plus<>());
template<class InputIterator, class OutputIterator, class T, class BinaryOperation> OutputIterator exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, T init, BinaryOperation binary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T, class BinaryOperation> ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op);
Requires:
  • T shall be MoveConstructible (Table 23).
  • All of binary_­op(init, init), binary_­op(init, *first), and binary_­op(*first, *first) shall be convertible to T.
  • binary_­op shall neither invalidate iterators or subranges, nor modify elements in the ranges [first, last] or [result, result + (last - first)].
Effects: For each integer K in [0, last - first) assigns through result + K the value of:
GENERALIZED_NONCOMMUTATIVE_SUM(
    binary_op, init, *(first + 0), *(first + 1), ..., *(first + K - 1))
Returns: The end of the resulting range beginning at result.
Complexity: applications of binary_­op.
Remarks: result may be equal to first.
[Note
:
The difference between exclusive_­scan and inclusive_­scan is that exclusive_­scan excludes the ith input element from the ith sum.
If binary_­op is not mathematically associative, the behavior of exclusive_­scan may be nondeterministic.
end note
]

29.8.8 Inclusive scan [inclusive.scan]

template<class InputIterator, class OutputIterator> OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result);
Effects: Equivalent to:
return inclusive_scan(first, last, result, plus<>());
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result);
Effects: Equivalent to:
return inclusive_scan(std::forward<ExecutionPolicy>(exec), first, last, result, plus<>());
template<class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation> ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op); template<class InputIterator, class OutputIterator, class BinaryOperation, class T> OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, T init); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class T> ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, T init);
Requires:
  • If init is provided, T shall be MoveConstructible (Table 23); otherwise, ForwardIterator1's value type shall be MoveConstructible.
  • If init is provided, all of binary_­op(init, init), binary_­op(init, *first), and binary_­op(*first, *first) shall be convertible to T; otherwise, binary_­op(*first, *first) shall be convertible to ForwardIterator1's value type.
  • binary_­op shall neither invalidate iterators or subranges, nor modify elements in the ranges [first, last] or [result, result + (last - first)].
Effects: For each integer K in [0, last - first) assigns through result + K the value of
  • GENERALIZED_­NONCOMMUTATIVE_­SUM(
        binary_­op, init, *(first + 0), *(first + 1), ..., *(first + K))

    if init is provided, or
  • GENERALIZED_­NONCOMMUTATIVE_­SUM(
        binary_­op, *(first + 0), *(first + 1), ..., *(first + K))

    otherwise.
Returns: The end of the resulting range beginning at result.
Complexity: applications of binary_­op.
Remarks: result may be equal to first.
[Note
:
The difference between exclusive_­scan and inclusive_­scan is that inclusive_­scan includes the ith input element in the ith sum.
If binary_­op is not mathematically associative, the behavior of inclusive_­scan may be nondeterministic.
end note
]

29.8.9 Transform exclusive scan [transform.exclusive.scan]

template<class InputIterator, class OutputIterator, class T, class BinaryOperation, class UnaryOperation> OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last, OutputIterator result, T init, BinaryOperation binary_op, UnaryOperation unary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class T, class BinaryOperation, class UnaryOperation> ForwardIterator2 transform_exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op, UnaryOperation unary_op);
Requires:
  • T shall be MoveConstructible (Table 23).
  • All of
    • binary_­op(init, init),
    • binary_­op(init, unary_­op(*first)), and
    • binary_­op(unary_­op(*first), unary_­op(*first))
    shall be convertible to T.
  • Neither unary_­op nor binary_­op shall invalidate iterators or subranges, or modify elements in the ranges [first, last] or [result, result + (last - first)].
Effects: For each integer K in [0, last - first) assigns through result + K the value of:
GENERALIZED_NONCOMMUTATIVE_SUM(
    binary_op, init,
    unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K - 1)))
Returns: The end of the resulting range beginning at result.
Complexity: applications each of unary_­op and binary_­op.
Remarks: result may be equal to first.
[Note
:
The difference between transform_­exclusive_­scan and transform_­inclusive_­scan is that transform_­exclusive_­scan excludes the input element from the sum.
If binary_­op is not mathematically associative, the behavior of transform_­exclusive_­scan may be nondeterministic.
transform_­exclusive_­scan does not apply unary_­op to init.
end note
]

29.8.10 Transform inclusive scan [transform.inclusive.scan]

template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class UnaryOperation> ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op); template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation, class T> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op, T init); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class UnaryOperation, class T> ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op, T init);
Requires:
  • If init is provided, T shall be MoveConstructible (Table 23); otherwise, ForwardIterator1's value type shall be MoveConstructible.
  • If init is provided, all of
    • binary_­op(init, init),
    • binary_­op(init, unary_­op(*first)), and
    • binary_­op(unary_­op(*first), unary_­op(*first))
    shall be convertible to T; otherwise, binary_­op(unary_­op(*first), unary_­op(*first)) shall be convertible to ForwardIterator1's value type.
  • Neither unary_­op nor binary_­op shall invalidate iterators or subranges, nor modify elements in the ranges [first, last] or [result, result + (last - first)].
Effects: For each integer K in [0, last - first) assigns through result + K the value of
  • GENERALIZED_­NONCOMMUTATIVE_­SUM(
        binary_­op, init,
        unary_­op(*(first + 0)), unary_­op(*(first + 1)), ..., unary_­op(*(first + K)))

    if init is provided, or
  • GENERALIZED_­NONCOMMUTATIVE_­SUM(
        binary_­op,
        unary_­op(*(first + 0)), unary_­op(*(first + 1)), ..., unary_­op(*(first + K)))

    otherwise.
Returns: The end of the resulting range beginning at result.
Complexity: applications each of unary_­op and binary_­op.
Remarks: result may be equal to first.
[Note
:
The difference between transform_­exclusive_­scan and transform_­inclusive_­scan is that transform_­inclusive_­scan includes the input element in the sum.
If binary_­op is not mathematically associative, the behavior of transform_­inclusive_­scan may be nondeterministic.
transform_­inclusive_­scan does not apply unary_­op to init.
end note
]

29.8.11 Adjacent difference [adjacent.difference]

template <class InputIterator, class OutputIterator> OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template <class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); template <class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation> ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op);
Requires:
  • For the overloads with no ExecutionPolicy, InputIterator's value type shall be MoveAssignable (Table 25) and shall be constructible from the type of *first.
    acc (defined below) shall be writable ([iterator.requirements.general]) to the result output iterator.
    The result of the expression val - acc or binary_­op(val, acc) shall be writable to the result output iterator.
  • For the overloads with an ExecutionPolicy, the value type of ForwardIterator1 shall be CopyConstructible (Table 24), constructible from the expression *first - *first or binary_­op(*first, *first), and assignable to the value type of ForwardIterator2.
  • For all overloads, in the ranges [first, last] and [result, result + (last - first)], binary_­op shall neither modify elements nor invalidate iterators or subranges.285
Effects: For the overloads with no ExecutionPolicy and a non-empty range, the function creates an accumulator acc whose type is InputIterator's value type, initializes it with *first, and assigns the result to *result.
For every iterator i in [first + 1, last) in order, creates an object val whose type is InputIterator's value type, initializes it with *i, computes val - acc or binary_­op(val, acc), assigns the result to *(result + (i - first)), and move assigns from val to acc.
For the overloads with an ExecutionPolicy and a non-empty range, first the function creates an object whose type is ForwardIterator1's value type, initializes it with *first, and assigns the result to *result.
Then for every d in [1, last - first - 1], creates an object val whose type is ForwardIterator1's value type, initializes it with *(first + d) - *(first + d - 1) or binary_­op(*(first + d), *(first + d - 1)), and assigns the result to *(result + d).
Returns: result + (last - first).
Complexity: Exactly (last - first) - 1 applications of the binary operation.
Remarks: For the overloads with no ExecutionPolicy, result may be equal to first.
For the overloads with an ExecutionPolicy, the ranges [first, last) and [result, result + (last - first)) shall not overlap.
The use of fully closed ranges is intentional.

29.8.12 Iota [numeric.iota]

template <class ForwardIterator, class T> void iota(ForwardIterator first, ForwardIterator last, T value);
Requires: T shall be convertible to ForwardIterator's value type.
The expression ++val, where val has type T, shall be well formed.
Effects: For each element referred to by the iterator i in the range [first, last), assigns *i = value and increments value as if by ++value.
Complexity: Exactly last - first increments and assignments.

29.8.13 Greatest common divisor [numeric.ops.gcd]

template <class M, class N> constexpr common_type_t<M,N> gcd(M m, N n);
Requires: |m| and |n| shall be representable as a value of common_­type_­t<M, N>.
[Note
:
These requirements ensure, for example, that gcd(m, m) = |m| is representable as a value of type M.
end note
]
Remarks: If either M or N is not an integer type, or if either is cv bool, the program is ill-formed.
Returns: Zero when m and n are both zero.
Otherwise, returns the greatest common divisor of |m| and |n|.
Throws: Nothing.

29.8.14 Least common multiple [numeric.ops.lcm]

template <class M, class N> constexpr common_type_t<M,N> lcm(M m, N n);
Requires: |m| and |n| shall be representable as a value of common_­type_­t<M, N>.
The least common multiple of |m| and |n| shall be representable as a value of type common_­type_­t<M,N>.
Remarks: If either M or N is not an integer type, or if either is cv bool the program is ill-formed.
Returns: Zero when either m or n is zero.
Otherwise, returns the least common multiple of |m| and |n|.
Throws: Nothing.

29.9 Mathematical functions for floating-point types [c.math]

29.9.1 Header <cmath> synopsis [cmath.syn]

namespace std {
  using float_t = see below;
  using double_t = see below;
}

#define HUGE_VAL see below
#define HUGE_VALF see below
#define HUGE_VALL see below
#define INFINITY see below
#define NAN see below
#define FP_INFINITE see below
#define FP_NAN see below
#define FP_NORMAL see below
#define FP_SUBNORMAL see below
#define FP_ZERO see below
#define FP_FAST_FMA see below
#define FP_FAST_FMAF see below
#define FP_FAST_FMAL see below
#define FP_ILOGB0 see below
#define FP_ILOGBNAN see below
#define MATH_ERRNO see below
#define MATH_ERREXCEPT see below

#define math_errhandling see below

namespace std {
  float acos(float x);  // see [library.c]
  double acos(double x);
  long double acos(long double x);  // see [library.c]
  float acosf(float x);
  long double acosl(long double x);

  float asin(float x);  // see [library.c]
  double asin(double x);
  long double asin(long double x);  // see [library.c]
  float asinf(float x);
  long double asinl(long double x);

  float atan(float x);  // see [library.c]
  double atan(double x);
  long double atan(long double x);  // see [library.c]
  float atanf(float x);
  long double atanl(long double x);

  float atan2(float y, float x);  // see [library.c]
  double atan2(double y, double x);
  long double atan2(long double y, long double x);  // see [library.c]
  float atan2f(float y, float x);
  long double atan2l(long double y, long double x);

  float cos(float x);  // see [library.c]
  double cos(double x);
  long double cos(long double x);  // see [library.c]
  float cosf(float x);
  long double cosl(long double x);

  float sin(float x);  // see [library.c]
  double sin(double x);
  long double sin(long double x);  // see [library.c]
  float sinf(float x);
  long double sinl(long double x);

  float tan(float x);  // see [library.c]
  double tan(double x);
  long double tan(long double x);  // see [library.c]
  float tanf(float x);
  long double tanl(long double x);

  float acosh(float x);  // see [library.c]
  double acosh(double x);
  long double acosh(long double x);  // see [library.c]
  float acoshf(float x);
  long double acoshl(long double x);

  float asinh(float x);  // see [library.c]
  double asinh(double x);
  long double asinh(long double x);  // see [library.c]
  float asinhf(float x);
  long double asinhl(long double x);

  float atanh(float x);  // see [library.c]
  double atanh(double x);
  long double atanh(long double x);  // see [library.c]
  float atanhf(float x);
  long double atanhl(long double x);

  float cosh(float x);  // see [library.c]
  double cosh(double x);
  long double cosh(long double x);  // see [library.c]
  float coshf(float x);
  long double coshl(long double x);

  float sinh(float x);  // see [library.c]
  double sinh(double x);
  long double sinh(long double x);  // see [library.c]
  float sinhf(float x);
  long double sinhl(long double x);

  float tanh(float x);  // see [library.c]
  double tanh(double x);
  long double tanh(long double x);  // see [library.c]
  float tanhf(float x);
  long double tanhl(long double x);

  float exp(float x);  // see [library.c]
  double exp(double x);
  long double exp(long double x);  // see [library.c]
  float expf(float x);
  long double expl(long double x);

  float exp2(float x);  // see [library.c]
  double exp2(double x);
  long double exp2(long double x);  // see [library.c]
  float exp2f(float x);
  long double exp2l(long double x);

  float expm1(float x);  // see [library.c]
  double expm1(double x);
  long double expm1(long double x);  // see [library.c]
  float expm1f(float x);
  long double expm1l(long double x);

  float frexp(float value, int* exp);  // see [library.c]
  double frexp(double value, int* exp);
  long double frexp(long double value, int* exp);  // see [library.c]
  float frexpf(float value, int* exp);
  long double frexpl(long double value, int* exp);

  int ilogb(float x);  // see [library.c]
  int ilogb(double x);
  int ilogb(long double x);  // see [library.c]
  int ilogbf(float x);
  int ilogbl(long double x);

  float ldexp(float x, int exp);  // see [library.c]
  double ldexp(double x, int exp);
  long double ldexp(long double x, int exp);  // see [library.c]
  float ldexpf(float x, int exp);
  long double ldexpl(long double x, int exp);

  float log(float x);  // see [library.c]
  double log(double x);
  long double log(long double x);  // see [library.c]
  float logf(float x);
  long double logl(long double x);

  float log10(float x);  // see [library.c]
  double log10(double x);
  long double log10(long double x);  // see [library.c]
  float log10f(float x);
  long double log10l(long double x);

  float log1p(float x);  // see [library.c]
  double log1p(double x);
  long double log1p(long double x);  // see [library.c]
  float log1pf(float x);
  long double log1pl(long double x);

  float log2(float x);  // see [library.c]
  double log2(double x);
  long double log2(long double x);  // see [library.c]
  float log2f(float x);
  long double log2l(long double x);

  float logb(float x);  // see [library.c]
  double logb(double x);
  long double logb(long double x);  // see [library.c]
  float logbf(float x);
  long double logbl(long double x);

  float modf(float value, float* iptr);  // see [library.c]
  double modf(double value, double* iptr);
  long double modf(long double value, long double* iptr);  // see [library.c]
  float modff(float value, float* iptr);
  long double modfl(long double value, long double* iptr);

  float scalbn(float x, int n);  // see [library.c]
  double scalbn(double x, int n);
  long double scalbn(long double x, int n);  // see [library.c]
  float scalbnf(float x, int n);
  long double scalbnl(long double x, int n);

  float scalbln(float x, long int n);  // see [library.c]
  double scalbln(double x, long int n);
  long double scalbln(long double x, long int n);  // see [library.c]
  float scalblnf(float x, long int n);
  long double scalblnl(long double x, long int n);

  float cbrt(float x);  // see [library.c]
  double cbrt(double x);
  long double cbrt(long double x);  // see [library.c]
  float cbrtf(float x);
  long double cbrtl(long double x);

  // [c.math.abs], absolute values
  int abs(int j);
  long int abs(long int j);
  long long int abs(long long int j);
  float abs(float j);
  double abs(double j);
  long double abs(long double j);

  float fabs(float x);  // see [library.c]
  double fabs(double x);
  long double fabs(long double x);  // see [library.c]
  float fabsf(float x);
  long double fabsl(long double x);

  float hypot(float x, float y);  // see [library.c]
  double hypot(double x, double y);
  long double hypot(double x, double y);  // see [library.c]
  float hypotf(float x, float y);
  long double hypotl(long double x, long double y);

  // [c.math.hypot3], three-dimensional hypotenuse
  float hypot(float x, float y, float z);
  double hypot(double x, double y, double z);
  long double hypot(long double x, long double y, long double z);

  float pow(float x, float y);  // see [library.c]
  double pow(double x, double y);
  long double pow(long double x, long double y);  // see [library.c]
  float powf(float x, float y);
  long double powl(long double x, long double y);

  float sqrt(float x);  // see [library.c]
  double sqrt(double x);
  long double sqrt(long double x);  // see [library.c]
  float sqrtf(float x);
  long double sqrtl(long double x);

  float erf(float x);  // see [library.c]
  double erf(double x);
  long double erf(long double x);  // see [library.c]
  float erff(float x);
  long double erfl(long double x);

  float erfc(float x);  // see [library.c]
  double erfc(double x);
  long double erfc(long double x);  // see [library.c]
  float erfcf(float x);
  long double erfcl(long double x);

  float lgamma(float x);  // see [library.c]
  double lgamma(double x);
  long double lgamma(long double x);  // see [library.c]
  float lgammaf(float x);
  long double lgammal(long double x);

  float tgamma(float x);  // see [library.c]
  double tgamma(double x);
  long double tgamma(long double x);  // see [library.c]
  float tgammaf(float x);
  long double tgammal(long double x);

  float ceil(float x);  // see [library.c]
  double ceil(double x);
  long double ceil(long double x);  // see [library.c]
  float ceilf(float x);
  long double ceill(long double x);

  float floor(float x);  // see [library.c]
  double floor(double x);
  long double floor(long double x);  // see [library.c]
  float floorf(float x);
  long double floorl(long double x);

  float nearbyint(float x);  // see [library.c]
  double nearbyint(double x);
  long double nearbyint(long double x);  // see [library.c]
  float nearbyintf(float x);
  long double nearbyintl(long double x);

  float rint(float x);  // see [library.c]
  double rint(double x);
  long double rint(long double x);  // see [library.c]
  float rintf(float x);
  long double rintl(long double x);

  long int lrint(float x);  // see [library.c]
  long int lrint(double x);
  long int lrint(long double x);  // see [library.c]
  long int lrintf(float x);
  long int lrintl(long double x);

  long long int llrint(float x);  // see [library.c]
  long long int llrint(double x);
  long long int llrint(long double x);  // see [library.c]
  long long int llrintf(float x);
  long long int llrintl(long double x);

  float round(float x);  // see [library.c]
  double round(double x);
  long double round(long double x);  // see [library.c]
  float roundf(float x);
  long double roundl(long double x);

  long int lround(float x);  // see [library.c]
  long int lround(double x);
  long int lround(long double x);  // see [library.c]
  long int lroundf(float x);
  long int lroundl(long double x);

  long long int llround(float x);  // see [library.c]
  long long int llround(double x);
  long long int llround(long double x);  // see [library.c]
  long long int llroundf(float x);
  long long int llroundl(long double x);

  float trunc(float x);  // see [library.c]
  double trunc(double x);
  long double trunc(long double x);  // see [library.c]
  float truncf(float x);
  long double truncl(long double x);

  float fmod(float x, float y);  // see [library.c]
  double fmod(double x, double y);
  long double fmod(long double x, long double y);  // see [library.c]
  float fmodf(float x, float y);
  long double fmodl(long double x, long double y);

  float remainder(float x, float y);  // see [library.c]
  double remainder(double x, double y);
  long double remainder(long double x, long double y);  // see [library.c]
  float remainderf(float x, float y);
  long double remainderl(long double x, long double y);

  float remquo(float x, float y, int* quo);  // see [library.c]
  double remquo(double x, double y, int* quo);
  long double remquo(long double x, long double y, int* quo);  // see [library.c]
  float remquof(float x, float y, int* quo);
  long double remquol(long double x, long double y, int* quo);

  float copysign(float x, float y);  // see [library.c]
  double copysign(double x, double y);
  long double copysign(long double x, long double y);  // see [library.c]
  float copysignf(float x, float y);
  long double copysignl(long double x, long double y);

  double nan(const char* tagp);
  float nanf(const char* tagp);
  long double nanl(const char* tagp);

  float nextafter(float x, float y);  // see [library.c]
  double nextafter(double x, double y);
  long double nextafter(long double x, long double y);  // see [library.c]
  float nextafterf(float x, float y);
  long double nextafterl(long double x, long double y);

  float nexttoward(float x, long double y);  // see [library.c]
  double nexttoward(double x, long double y);
  long double nexttoward(long double x, long double y);  // see [library.c]
  float nexttowardf(float x, long double y);
  long double nexttowardl(long double x, long double y);

  float fdim(float x, float y);  // see [library.c]
  double fdim(double x, double y);
  long double fdim(long double x, long double y);  // see [library.c]
  float fdimf(float x, float y);
  long double fdiml(long double x, long double y);

  float fmax(float x, float y);  // see [library.c]
  double fmax(double x, double y);
  long double fmax(long double x, long double y);  // see [library.c]
  float fmaxf(float x, float y);
  long double fmaxl(long double x, long double y);

  float fmin(float x, float y);  // see [library.c]
  double fmin(double x, double y);
  long double fmin(long double x, long double y);  // see [library.c]
  float fminf(float x, float y);
  long double fminl(long double x, long double y);

  float fma(float x, float y, float z);  // see [library.c]
  double fma(double x, double y, double z);
  long double fma(long double x, long double y, long double z);  // see [library.c]
  float fmaf(float x, float y, float z);
  long double fmal(long double x, long double y, long double z);

  // [c.math.fpclass], classification / comparison functions
  int fpclassify(float x);
  int fpclassify(double x);
  int fpclassify(long double x);

  int isfinite(float x);
  int isfinite(double x);
  int isfinite(long double x);

  int isinf(float x);
  int isinf(double x);
  int isinf(long double x);

  int isnan(float x);
  int isnan(double x);
  int isnan(long double x);

  int isnormal(float x);
  int isnormal(double x);
  int isnormal(long double x);

  int signbit(float x);
  int signbit(double x);
  int signbit(long double x);

  int isgreater(float x, float y);
  int isgreater(double x, double y);
  int isgreater(long double x, long double y);

  int isgreaterequal(float x, float y);
  int isgreaterequal(double x, double y);
  int isgreaterequal(long double x, long double y);

  int isless(float x, float y);
  int isless(double x, double y);
  int isless(long double x, long double y);

  int islessequal(float x, float y);
  int islessequal(double x, double y);
  int islessequal(long double x, long double y);

  int islessgreater(float x, float y);
  int islessgreater(double x, double y);
  int islessgreater(long double x, long double y);

  int isunordered(float x, float y);
  int isunordered(double x, double y);
  int isunordered(long double x, long double y);

  // [sf.cmath], mathematical special functions

  // [sf.cmath.assoc_laguerre], associated Laguerre polynomials
  double       assoc_laguerre(unsigned n, unsigned m, double x);
  float        assoc_laguerref(unsigned n, unsigned m, float x);
  long double  assoc_laguerrel(unsigned n, unsigned m, long double x);

  // [sf.cmath.assoc_legendre], associated Legendre functions
  double       assoc_legendre(unsigned l, unsigned m, double x);
  float        assoc_legendref(unsigned l, unsigned m, float x);
  long double  assoc_legendrel(unsigned l, unsigned m, long double x);

  // [sf.cmath.beta], beta function
  double       beta(double x, double y);
  float        betaf(float x, float y);
  long double  betal(long double x, long double y);

  // [sf.cmath.comp_ellint_1], complete elliptic integral of the first kind
  double       comp_ellint_1(double k);
  float        comp_ellint_1f(float k);
  long double  comp_ellint_1l(long double k);

  // [sf.cmath.comp_ellint_2], complete elliptic integral of the second kind
  double       comp_ellint_2(double k);
  float        comp_ellint_2f(float k);
  long double  comp_ellint_2l(long double k);

  // [sf.cmath.comp_ellint_3], complete elliptic integral of the third kind
  double       comp_ellint_3(double k, double nu);
  float        comp_ellint_3f(float k, float nu);
  long double  comp_ellint_3l(long double k, long double nu);

  // [sf.cmath.cyl_bessel_i], regular modified cylindrical Bessel functions
  double       cyl_bessel_i(double nu, double x);
  float        cyl_bessel_if(float nu, float x);
  long double  cyl_bessel_il(long double nu, long double x);

  // [sf.cmath.cyl_bessel_j], cylindrical Bessel functions of the first kind
  double       cyl_bessel_j(double nu, double x);
  float        cyl_bessel_jf(float nu, float x);
  long double  cyl_bessel_jl(long double nu, long double x);

  // [sf.cmath.cyl_bessel_k], irregular modified cylindrical Bessel functions
  double       cyl_bessel_k(double nu, double x);
  float        cyl_bessel_kf(float nu, float x);
  long double  cyl_bessel_kl(long double nu, long double x);

  // [sf.cmath.cyl_neumann], cylindrical Neumann functions;
  // cylindrical Bessel functions of the second kind
  double       cyl_neumann(double nu, double x);
  float        cyl_neumannf(float nu, float x);
  long double  cyl_neumannl(long double nu, long double x);

  // [sf.cmath.ellint_1], incomplete elliptic integral of the first kind
  double       ellint_1(double k, double phi);
  float        ellint_1f(float k, float phi);
  long double  ellint_1l(long double k, long double phi);

  // [sf.cmath.ellint_2], incomplete elliptic integral of the second kind
  double       ellint_2(double k, double phi);
  float        ellint_2f(float k, float phi);
  long double  ellint_2l(long double k, long double phi);

  // [sf.cmath.ellint_3], incomplete elliptic integral of the third kind
  double       ellint_3(double k, double nu, double phi);
  float        ellint_3f(float k, float nu, float phi);
  long double  ellint_3l(long double k, long double nu, long double phi);

  // [sf.cmath.expint], exponential integral
  double       expint(double x);
  float        expintf(float x);
  long double  expintl(long double x);

  // [sf.cmath.hermite], Hermite polynomials
  double       hermite(unsigned n, double x);
  float        hermitef(unsigned n, float x);
  long double  hermitel(unsigned n, long double x);

  // [sf.cmath.laguerre], Laguerre polynomials
  double       laguerre(unsigned n, double x);
  float        laguerref(unsigned n, float x);
  long double  laguerrel(unsigned n, long double x);

  // [sf.cmath.legendre], Legendre polynomials
  double       legendre(unsigned l, double x);
  float        legendref(unsigned l, float x);
  long double  legendrel(unsigned l, long double x);

  // [sf.cmath.riemann_zeta], Riemann zeta function
  double       riemann_zeta(double x);
  float        riemann_zetaf(float x);
  long double  riemann_zetal(long double x);

  // [sf.cmath.sph_bessel], spherical Bessel functions of the first kind
  double       sph_bessel(unsigned n, double x);
  float        sph_besself(unsigned n, float x);
  long double  sph_bessell(unsigned n, long double x);

  // [sf.cmath.sph_legendre], spherical associated Legendre functions
  double       sph_legendre(unsigned l, unsigned m, double theta);
  float        sph_legendref(unsigned l, unsigned m, float theta);
  long double  sph_legendrel(unsigned l, unsigned m, long double theta);

  // [sf.cmath.sph_neumann], spherical Neumann functions;
  // spherical Bessel functions of the second kind:
  double       sph_neumann(unsigned n, double x);
  float        sph_neumannf(unsigned n, float x);
  long double  sph_neumannl(unsigned n, long double x);
}
The contents and meaning of the header <cmath> are the same as the C standard library header <math.h>, with the addition of a three-dimensional hypotenuse function ([c.math.hypot3]) and the mathematical special functions described in [sf.cmath].
[Note
:
Several functions have additional overloads in this International Standard, but they have the same behavior as in the C standard library ([library.c]).
end note
]
For each set of overloaded functions within <cmath>, with the exception of abs, there shall be additional overloads sufficient to ensure:
  1. 1.
    If any argument of arithmetic type corresponding to a double parameter has type long double, then all arguments of arithmetic type ([basic.fundamental]) corresponding to double parameters are effectively cast to long double.
  2. 2.
    Otherwise, if any argument of arithmetic type corresponding to a double parameter has type double or an integer type, then all arguments of arithmetic type corresponding to double parameters are effectively cast to double.
  3. 3.
    Otherwise, all arguments of arithmetic type corresponding to double parameters have type float.
[Note
:
abs is exempted from these rules in order to stay compatible with C.
end note
]
See also: ISO C 7.
12

29.9.2 Absolute values [c.math.abs]

[Note
:
The headers <cstdlib> ([cstdlib.syn]) and <cmath> ([cmath.syn]) declare the functions described in this subclause.
end note
]
int abs(int j); long int abs(long int j); long long int abs(long long int j); float abs(float j); double abs(double j); long double abs(long double j);
Effects: The abs functions have the semantics specified in the C standard library for the functions abs, labs, llabs, fabsf, fabs, and fabsl.
Remarks: If abs() is called with an argument of type X for which is_­unsigned_­v<X> is true and if X cannot be converted to int by integral promotion ([conv.prom]), the program is ill-formed.
[Note
:
Arguments that can be promoted to int are permitted for compatibility with C.
end note
]
See also: ISO C 7.
12.
7.
2, 7.
22.
6.
1

29.9.3 Three-dimensional hypotenuse [c.math.hypot3]

float hypot(float x, float y, float z); double hypot(double x, double y, double z); long double hypot(long double x, long double y, long double z);
Returns: .

29.9.4 Classification / comparison functions [c.math.fpclass]

The classification / comparison functions behave the same as the C macros with the corresponding names defined in the C standard library.
Each function is overloaded for the three floating-point types.
See also: ISO C 7.
12.
3, 7.
12.
4

29.9.5 Mathematical special functions [sf.cmath]

If any argument value to any of the functions specified in this subclause is a NaN (Not a Number), the function shall return a NaN but it shall not report a domain error.
Otherwise, the function shall report a domain error for just those argument values for which:
  • the function description's Returns: clause explicitly specifies a domain and those argument values fall outside the specified domain, or
  • the corresponding mathematical function value has a nonzero imaginary component, or
  • the corresponding mathematical function is not mathematically defined.286
Unless otherwise specified, each function is defined for all finite values, for negative infinity, and for positive infinity.
A mathematical function is mathematically defined for a given set of argument values (a) if it is explicitly defined for that set of argument values, or (b) if its limiting value exists and does not depend on the direction of approach.

29.9.5.1 Associated Laguerre polynomials [sf.cmath.assoc_laguerre]

double assoc_laguerre(unsigned n, unsigned m, double x); float assoc_laguerref(unsigned n, unsigned m, float x); long double assoc_laguerrel(unsigned n, unsigned m, long double x);
Effects: These functions compute the associated Laguerre polynomials of their respective arguments n, m, and x.
Returns:

where n is n, m is m, and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if n >= 128 or if m >= 128.

29.9.5.2 Associated Legendre functions [sf.cmath.assoc_legendre]

double assoc_legendre(unsigned l, unsigned m, double x); float assoc_legendref(unsigned l, unsigned m, float x); long double assoc_legendrel(unsigned l, unsigned m, long double x);
Effects: These functions compute the associated Legendre functions of their respective arguments l, m, and x.
Returns:

where l is l, m is m, and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if l >= 128.

29.9.5.3 Beta function [sf.cmath.beta]

double beta(double x, double y); float betaf(float x, float y); long double betal(long double x, long double y);
Effects: These functions compute the beta function of their respective arguments x and y.
Returns:

where x is x and y is y.

29.9.5.4 Complete elliptic integral of the first kind [sf.cmath.comp_ellint_1]

double comp_ellint_1(double k); float comp_ellint_1f(float k); long double comp_ellint_1l(long double k);
Effects: These functions compute the complete elliptic integral of the first kind of their respective arguments k.
Returns:

where k is k.

29.9.5.5 Complete elliptic integral of the second kind [sf.cmath.comp_ellint_2]

double comp_ellint_2(double k); float comp_ellint_2f(float k); long double comp_ellint_2l(long double k);
Effects: These functions compute the complete elliptic integral of the second kind of their respective arguments k.
Returns:

where k is k.

29.9.5.6 Complete elliptic integral of the third kind [sf.cmath.comp_ellint_3]

double comp_ellint_3(double k, double nu); float comp_ellint_3f(float k, float nu); long double comp_ellint_3l(long double k, long double nu);
Effects: These functions compute the complete elliptic integral of the third kind of their respective arguments k and nu.
Returns:

where k is k and ν is nu.

29.9.5.7 Regular modified cylindrical Bessel functions [sf.cmath.cyl_bessel_i]

double cyl_bessel_i(double nu, double x); float cyl_bessel_if(float nu, float x); long double cyl_bessel_il(long double nu, long double x);
Effects: These functions compute the regular modified cylindrical Bessel functions of their respective arguments nu and x.
Returns:

where ν is nu and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if nu >= 128.

29.9.5.8 Cylindrical Bessel functions of the first kind [sf.cmath.cyl_bessel_j]

double cyl_bessel_j(double nu, double x); float cyl_bessel_jf(float nu, float x); long double cyl_bessel_jl(long double nu, long double x);
Effects: These functions compute the cylindrical Bessel functions of the first kind of their respective arguments nu and x.
Returns:

where ν is nu and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if nu >= 128.

29.9.5.9 Irregular modified cylindrical Bessel functions [sf.cmath.cyl_bessel_k]

double cyl_bessel_k(double nu, double x); float cyl_bessel_kf(float nu, float x); long double cyl_bessel_kl(long double nu, long double x);
Effects: These functions compute the irregular modified cylindrical Bessel functions of their respective arguments nu and x.
Returns:

where ν is nu and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if nu >= 128.

29.9.5.10 Cylindrical Neumann functions [sf.cmath.cyl_neumann]

double cyl_neumann(double nu, double x); float cyl_neumannf(float nu, float x); long double cyl_neumannl(long double nu, long double x);
Effects: These functions compute the cylindrical Neumann functions, also known as the cylindrical Bessel functions of the second kind, of their respective arguments nu and x.
Returns:

where ν is nu and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if nu >= 128.

29.9.5.11 Incomplete elliptic integral of the first kind [sf.cmath.ellint_1]

double ellint_1(double k, double phi); float ellint_1f(float k, float phi); long double ellint_1l(long double k, long double phi);
Effects: These functions compute the incomplete elliptic integral of the first kind of their respective arguments k and phi (phi measured in radians).
Returns:

where k is k and φ is phi.

29.9.5.12 Incomplete elliptic integral of the second kind [sf.cmath.ellint_2]

double ellint_2(double k, double phi); float ellint_2f(float k, float phi); long double ellint_2l(long double k, long double phi);
Effects: These functions compute the incomplete elliptic integral of the second kind of their respective arguments k and phi (phi measured in radians).
Returns:

where k is k and φ is phi.

29.9.5.13 Incomplete elliptic integral of the third kind [sf.cmath.ellint_3]

double ellint_3(double k, double nu, double phi); float ellint_3f(float k, float nu, float phi); long double ellint_3l(long double k, long double nu, long double phi);
Effects: These functions compute the incomplete elliptic integral of the third kind of their respective arguments k, nu, and phi (phi measured in radians).
Returns:

where ν is nu, k is k, and φ is phi.

29.9.5.14 Exponential integral [sf.cmath.expint]

double expint(double x); float expintf(float x); long double expintl(long double x);
Effects: These functions compute the exponential integral of their respective arguments x.
Returns:

where x is x.

29.9.5.15 Hermite polynomials [sf.cmath.hermite]

double hermite(unsigned n, double x); float hermitef(unsigned n, float x); long double hermitel(unsigned n, long double x);
Effects: These functions compute the Hermite polynomials of their respective arguments n and x.
Returns:

where n is n and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if n >= 128.

29.9.5.16 Laguerre polynomials [sf.cmath.laguerre]

double laguerre(unsigned n, double x); float laguerref(unsigned n, float x); long double laguerrel(unsigned n, long double x);
Effects: These functions compute the Laguerre polynomials of their respective arguments n and x.
Returns:

where n is n and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if n >= 128.

29.9.5.17 Legendre polynomials [sf.cmath.legendre]

double legendre(unsigned l, double x); float legendref(unsigned l, float x); long double legendrel(unsigned l, long double x);
Effects: These functions compute the Legendre polynomials of their respective arguments l and x.
Returns:

where l is l and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if l >= 128.

29.9.5.18 Riemann zeta function [sf.cmath.riemann_zeta]

double riemann_zeta(double x); float riemann_zetaf(float x); long double riemann_zetal(long double x);
Effects: These functions compute the Riemann zeta function of their respective arguments x.
Returns:

where x is x.

29.9.5.19 Spherical Bessel functions of the first kind [sf.cmath.sph_bessel]

double sph_bessel(unsigned n, double x); float sph_besself(unsigned n, float x); long double sph_bessell(unsigned n, long double x);
Effects: These functions compute the spherical Bessel functions of the first kind of their respective arguments n and x.
Returns:

where n is n and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if n >= 128.

29.9.5.20 Spherical associated Legendre functions [sf.cmath.sph_legendre]

double sph_legendre(unsigned l, unsigned m, double theta); float sph_legendref(unsigned l, unsigned m, float theta); long double sph_legendrel(unsigned l, unsigned m, long double theta);
Effects: These functions compute the spherical associated Legendre functions of their respective arguments l, m, and theta (theta measured in radians).
Returns:

where

and l is l, m is m, and θ is theta.

Remarks: The effect of calling each of these functions is implementation-defined if l >= 128.

29.9.5.21 Spherical Neumann functions [sf.cmath.sph_neumann]

double sph_neumann(unsigned n, double x); float sph_neumannf(unsigned n, float x); long double sph_neumannl(unsigned n, long double x);
Effects: These functions compute the spherical Neumann functions, also known as the spherical Bessel functions of the second kind, of their respective arguments n and x.
Returns:

where n is n and x is x.

Remarks: The effect of calling each of these functions is implementation-defined if n >= 128.

30 Input/output library [input.output]

30.1 General [input.output.general]

This Clause describes components that C++ programs may use to perform input/output operations.
The following subclauses describe requirements for stream parameters, and components for forward declarations of iostreams, predefined iostreams objects, base iostreams classes, stream buffering, stream formatting and manipulators, string streams, and file streams, as summarized in Table 101.
Table 101 — Input/output library summary
Subclause
Header(s)
Requirements
Forward declarations
<iosfwd>
Standard iostream objects
<iostream>
Iostreams base classes
<ios>
Stream buffers
<streambuf>
Formatting and manipulators
<istream>
<ostream>
<iomanip>
String streams
<sstream>
File streams
<fstream>
File systems
<filesystem>
C library files
<cstdio>
<cinttypes>
Figure [fig:streampos] illustrates relationships among various types described in this clause.
A line from A to B indicates that A is an alias (e.g. a typedef) for B or that A is defined in terms of B.
figstreampos traits_pos_type_char char_traits<char> ::pos_type streampos streampos traits_pos_type_char->streampos iostreams.limits.pos traits_pos_type_wchar_t char_traits<wchar_t> ::pos_type wstreampos wstreampos traits_pos_type_wchar_t->wstreampos iostreams.limits.pos fpos fpos<mbstate_t> streampos->fpos iostream.forward wstreampos->fpos iostream.forward traits_off_type_char char_traits<char> ::off_type streamoff streamoff traits_off_type_char->streamoff iostreams.limits.pos traits_off_type_wchar_t char_traits<wchar_t> ::off_type traits_off_type_wchar_t->streamoff iostreams.limits.pos streamoff_type signed integer type sufficient for O/S maximum file size streamoff->streamoff_type stream.types streamsize streamsize streamsize_type signed integer type represents characters xfered or buffer sizes streamsize->streamsize_type stream.types
Figure 7 — Stream position, offset, and size types [non-normative]

30.2 Iostreams requirements [iostreams.requirements]

30.2.1 Imbue limitations [iostream.limits.imbue]

No function described in Clause [input.output] except for ios_­base​::​imbue and basic_­filebuf​::​pubimbue causes any instance of basic_­ios​::​imbue or basic_­streambuf​::​imbue to be called.
If any user function called from a function declared in Clause [input.output] or as an overriding virtual function of any class declared in Clause [input.output] calls imbue, the behavior is undefined.

30.2.2 Positioning type limitations [iostreams.limits.pos]

The classes of Clause [input.output] with template arguments charT and traits behave as described if traits​::​pos_­type and traits​::​off_­type are streampos and streamoff respectively.
Except as noted explicitly below, their behavior when traits​::​pos_­type and traits​::​off_­type are other types is implementation-defined.
In the classes of Clause [input.output], a template parameter with name charT represents a member of the set of types containing char, wchar_­t, and any other implementation-defined character types that satisfy the requirements for a character on which any of the iostream components can be instantiated.

30.2.3 Thread safety [iostreams.threadsafety]

Concurrent access to a stream object ([string.streams], [file.streams]), stream buffer object ([stream.buffers]), or C Library stream ([c.files]) by multiple threads may result in a data race ([intro.multithread]) unless otherwise specified ([iostream.objects]).
[Note
:
Data races result in undefined behavior ([intro.multithread]).
end note
]
If one thread makes a library call a that writes a value to a stream and, as a result, another thread reads this value from the stream through a library call b such that this does not result in a data race, then a's write synchronizes with b's read.

30.3 Forward declarations [iostream.forward]

30.3.1 Header <iosfwd> synopsis [iosfwd.syn]

namespace std {
  template<class charT> class char_traits;
  template<> class char_traits<char>;
  template<> class char_traits<char16_t>;
  template<> class char_traits<char32_t>;
  template<> class char_traits<wchar_t>;

  template<class T> class allocator;

  template <class charT, class traits = char_traits<charT>>
    class basic_ios;
  template <class charT, class traits = char_traits<charT>>
    class basic_streambuf;
  template <class charT, class traits = char_traits<charT>>
    class basic_istream;
  template <class charT, class traits = char_traits<charT>>
    class basic_ostream;
  template <class charT, class traits = char_traits<charT>>
    class basic_iostream;

  template <class charT, class traits = char_traits<charT>,
      class Allocator = allocator<charT>>
    class basic_stringbuf;
  template <class charT, class traits = char_traits<charT>,
      class Allocator = allocator<charT>>
    class basic_istringstream;
  template <class charT, class traits = char_traits<charT>,
      class Allocator = allocator<charT>>
    class basic_ostringstream;
  template <class charT, class traits = char_traits<charT>,
      class Allocator = allocator<charT>>
    class basic_stringstream;

  template <class charT, class traits = char_traits<charT>>
    class basic_filebuf;
  template <class charT, class traits = char_traits<charT>>
    class basic_ifstream;
  template <class charT, class traits = char_traits<charT>>
    class basic_ofstream;
  template <class charT, class traits = char_traits<charT>>
    class basic_fstream;

  template <class charT, class traits = char_traits<charT>>
    class istreambuf_iterator;
  template <class charT, class traits = char_traits<charT>>
    class ostreambuf_iterator;

  using ios  = basic_ios<char>;
  using wios = basic_ios<wchar_t>;

  using streambuf = basic_streambuf<char>;
  using istream   = basic_istream<char>;
  using ostream   = basic_ostream<char>;
  using iostream  = basic_iostream<char>;

  using stringbuf     = basic_stringbuf<char>;
  using istringstream = basic_istringstream<char>;
  using ostringstream = basic_ostringstream<char>;
  using stringstream  = basic_stringstream<char>;

  using filebuf  = basic_filebuf<char>;
  using ifstream = basic_ifstream<char>;
  using ofstream = basic_ofstream<char>;
  using fstream  = basic_fstream<char>;

  using wstreambuf = basic_streambuf<wchar_t>;
  using wistream   = basic_istream<wchar_t>;
  using wostream   = basic_ostream<wchar_t>;
  using wiostream  = basic_iostream<wchar_t>;

  using wstringbuf     = basic_stringbuf<wchar_t>;
  using wistringstream = basic_istringstream<wchar_t>;
  using wostringstream = basic_ostringstream<wchar_t>;
  using wstringstream  = basic_stringstream<wchar_t>;

  using wfilebuf  = basic_filebuf<wchar_t>;
  using wifstream = basic_ifstream<wchar_t>;
  using wofstream = basic_ofstream<wchar_t>;
  using wfstream  = basic_fstream<wchar_t>;

  template <class state> class fpos;
  using streampos  = fpos<char_traits<char>::state_type>;
  using wstreampos = fpos<char_traits<wchar_t>::state_type>;
}
Default template arguments are described as appearing both in <iosfwd> and in the synopsis of other headers but it is well-formed to include both <iosfwd> and one or more of the other headers.287
It is the implementation's responsibility to implement headers so that including <iosfwd> and other headers does not violate the rules about multiple occurrences of default arguments.

30.3.2 Overview [iostream.forward.overview]

The class template specialization basic_­ios<charT, traits> serves as a virtual base class for the class templates basic_­istream, basic_­ostream, and class templates derived from them.
basic_­iostream is a class template derived from both basic_­istream<charT, traits> and basic_­ostream<charT, traits>.
The class template specialization basic_­streambuf<charT, traits> serves as a base class for class templates basic_­stringbuf and basic_­filebuf.
The class template specialization basic_­istream<charT, traits> serves as a base class for class templates basic_­istringstream and basic_­ifstream.
The class template specialization basic_­ostream<charT, traits> serves as a base class for class templates basic_­ostringstream and basic_­ofstream.
The class template specialization basic_­iostream<charT, traits> serves as a base class for class templates basic_­stringstream and basic_­fstream.
Other typedef-names define instances of class templates specialized for char or wchar_­t types.
Specializations of the class template fpos are used for specifying file position information.
The types streampos and wstreampos are used for positioning streams specialized on char and wchar_­t respectively.
[Note
:
This synopsis suggests a circularity between streampos and char_­traits<char>.
An implementation can avoid this circularity by substituting equivalent types.
One way to do this might be
template<class stateT> class fpos { ... };      // depends on nothing
using _STATE = ... ;             // implementation private declaration of stateT

using streampos = fpos<_STATE>;

template<> struct char_traits<char> {
  using pos_type = streampos;
}
end note
]

30.4 Standard iostream objects [iostream.objects]

30.4.1 Header <iostream> synopsis [iostream.syn]

#include <ios>          // see [ios.syn]
#include <streambuf>    // see [streambuf.syn]
#include <istream>      // see [istream.syn]
#include <ostream>      // see [ostream.syn]

namespace std {
  extern istream cin;
  extern ostream cout;
  extern ostream cerr;
  extern ostream clog;

  extern wistream wcin;
  extern wostream wcout;
  extern wostream wcerr;
  extern wostream wclog;
}

30.4.2 Overview [iostream.objects.overview]

In this Clause, the type name FILE refers to the type FILE declared in <cstdio> ([cstdio.syn]).
The header <iostream> declares objects that associate objects with the standard C streams provided for by the functions declared in <cstdio> ([c.files]), and includes all the headers necessary to use these objects.
The objects are constructed and the associations are established at some time prior to or during the first time an object of class ios_­base​::​Init is constructed, and in any case before the body of main ([basic.start.main]) begins execution.288
The objects are not destroyed during program execution.289
The results of including <iostream> in a translation unit shall be as if <iostream> defined an instance of ios_­base​::​Init with static storage duration.
Mixing operations on corresponding wide- and narrow-character streams follows the same semantics as mixing such operations on FILEs, as specified in the C standard library.
Concurrent access to a synchronized ([ios.members.static]) standard iostream object's formatted and unformatted input ([istream]) and output ([ostream]) functions or a standard C stream by multiple threads shall not result in a data race ([intro.multithread]).
[Note
:
Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters.
end note
]
See also: ISO C 7.
21.
2.
If it is possible for them to do so, implementations are encouraged to initialize the objects earlier than required.
Constructors and destructors for static objects can access these objects to read input from stdin or write output to stdout or stderr.

30.4.3 Narrow stream objects [narrow.stream.objects]

istream cin;
The object cin controls input from a stream buffer associated with the object stdin, declared in <cstdio> ([cstdio.syn]).
After the object cin is initialized, cin.tie() returns &cout.
Its state is otherwise the same as required for basic_­ios<char>​::​init ([basic.ios.cons]).
ostream cout;
The object cout controls output to a stream buffer associated with the object stdout, declared in <cstdio> ([cstdio.syn]).
ostream cerr;
The object cerr controls output to a stream buffer associated with the object stderr, declared in <cstdio> ([cstdio.syn]).
After the object cerr is initialized, cerr.flags() & unitbuf is nonzero and cerr.tie() returns &cout.
Its state is otherwise the same as required for basic_­ios<char>​::​init ([basic.ios.cons]).
ostream clog;
The object clog controls output to a stream buffer associated with the object stderr, declared in <cstdio> ([cstdio.syn]).

30.4.4 Wide stream objects [wide.stream.objects]

wistream wcin;
The object wcin controls input from a stream buffer associated with the object stdin, declared in <cstdio> ([cstdio.syn]).
After the object wcin is initialized, wcin.tie() returns &wcout.
Its state is otherwise the same as required for basic_­ios<wchar_­t>​::​init ([basic.ios.cons]).
wostream wcout;
The object wcout controls output to a stream buffer associated with the object stdout, declared in <cstdio> ([cstdio.syn]).
wostream wcerr;
The object wcerr controls output to a stream buffer associated with the object stderr, declared in <cstdio> ([cstdio.syn]).
After the object wcerr is initialized, wcerr.flags() & unitbuf is nonzero and wcerr.tie() returns &wcout.
Its state is otherwise the same as required for basic_­ios<wchar_­t>​::​init ([basic.ios.cons]).
wostream wclog;
The object wclog controls output to a stream buffer associated with the object stderr, declared in <cstdio> ([cstdio.syn]).

30.5 Iostreams base classes [iostreams.base]

30.5.1 Header <ios> synopsis [ios.syn]

#include <iosfwd>   // see [iosfwd.syn]

namespace std {
  using streamoff  = implementation-defined;
  using streamsize = implementation-defined;
  template <class stateT> class fpos;

  class ios_base;
  template <class charT, class traits = char_traits<charT>>
    class basic_ios;

  // [std.ios.manip], manipulators
  ios_base& boolalpha  (ios_base& str);
  ios_base& noboolalpha(ios_base& str);

  ios_base& showbase   (ios_base& str);
  ios_base& noshowbase (ios_base& str);

  ios_base& showpoint  (ios_base& str);
  ios_base& noshowpoint(ios_base& str);

  ios_base& showpos    (ios_base& str);
  ios_base& noshowpos  (ios_base& str);

  ios_base& skipws     (ios_base& str);
  ios_base& noskipws   (ios_base& str);

  ios_base& uppercase  (ios_base& str);
  ios_base& nouppercase(ios_base& str);

  ios_base& unitbuf    (ios_base& str);
  ios_base& nounitbuf  (ios_base& str);

  // [adjustfield.manip], adjustfield
  ios_base& internal   (ios_base& str);
  ios_base& left       (ios_base& str);
  ios_base& right      (ios_base& str);

  // [basefield.manip], basefield
  ios_base& dec        (ios_base& str);
  ios_base& hex        (ios_base& str);
  ios_base& oct        (ios_base& str);

  // [floatfield.manip], floatfield
  ios_base& fixed      (ios_base& str);
  ios_base& scientific (ios_base& str);
  ios_base& hexfloat   (ios_base& str);
  ios_base& defaultfloat(ios_base& str);

  // [error.reporting], error reporting
  enum class io_errc {
    stream = 1
  };

  template <> struct is_error_code_enum<io_errc> : public true_type { };
  error_code make_error_code(io_errc e) noexcept;
  error_condition make_error_condition(io_errc e) noexcept;
  const error_category& iostream_category() noexcept;
}

30.5.2 Types [stream.types]

using streamoff = implementation-defined;
The type streamoff is a synonym for one of the signed basic integral types of sufficient size to represent the maximum possible file size for the operating system.290
using streamsize = implementation-defined;
The type streamsize is a synonym for one of the signed basic integral types.
It is used to represent the number of characters transferred in an I/O operation, or the size of I/O buffers.291
Typically long long.
streamsize is used in most places where ISO C would use size_­t.
Most of the uses of streamsize could use size_­t, except for the strstreambuf constructors, which require negative values.
It should probably be the signed type corresponding to size_­t (which is what Posix.
2 calls ssize_­t).

30.5.3 Class ios_­base [ios.base]

namespace std {
  class ios_base {
  public:
    class failure; // see below

    // [ios::fmtflags], fmtflags
    using fmtflags = T1;
    static constexpr fmtflags boolalpha = unspecified;
    static constexpr fmtflags dec = unspecified;
    static constexpr fmtflags fixed = unspecified;
    static constexpr fmtflags hex = unspecified;
    static constexpr fmtflags internal = unspecified;
    static constexpr fmtflags left = unspecified;
    static constexpr fmtflags oct = unspecified;
    static constexpr fmtflags right = unspecified;
    static constexpr fmtflags scientific = unspecified;
    static constexpr fmtflags showbase = unspecified;
    static constexpr fmtflags showpoint = unspecified;
    static constexpr fmtflags showpos = unspecified;
    static constexpr fmtflags skipws = unspecified;
    static constexpr fmtflags unitbuf = unspecified;
    static constexpr fmtflags uppercase = unspecified;
    static constexpr fmtflags adjustfield = see below;
    static constexpr fmtflags basefield = see below;
    static constexpr fmtflags floatfield = see below;

    // [ios::iostate], iostate
    using iostate = T2;
    static constexpr iostate badbit = unspecified;
    static constexpr iostate eofbit = unspecified;
    static constexpr iostate failbit = unspecified;
    static constexpr iostate goodbit = see below;

    // [ios::openmode], openmode
    using openmode = T3;
    static constexpr openmode app = unspecified;
    static constexpr openmode ate = unspecified;
    static constexpr openmode binary = unspecified;
    static constexpr openmode in = unspecified;
    static constexpr openmode out = unspecified;
    static constexpr openmode trunc = unspecified;

    // [ios::seekdir], seekdir
    using seekdir = T4;
    static constexpr seekdir beg = unspecified;
    static constexpr seekdir cur = unspecified;
    static constexpr seekdir end = unspecified;

    class Init;

    // [fmtflags.state], fmtflags state
    fmtflags flags() const;
    fmtflags flags(fmtflags fmtfl);
    fmtflags setf(fmtflags fmtfl);
    fmtflags setf(fmtflags fmtfl, fmtflags mask);
    void unsetf(fmtflags mask);

    streamsize precision() const;
    streamsize precision(streamsize prec);
    streamsize width() const;
    streamsize width(streamsize wide);

    // [ios.base.locales], locales
    locale imbue(const locale& loc);
    locale getloc() const;

    // [ios.base.storage], storage
    static int xalloc();
    long&  iword(int index);
    void*& pword(int index);

    // destructor:
    virtual ~ios_base();

    // [ios.base.callback], callbacks;
    enum event { erase_event, imbue_event, copyfmt_event };
    using event_callback = void (*)(event, ios_base&, int index);
    void register_callback(event_callback fn, int index);

    ios_base(const ios_base&) = delete;
    ios_base& operator=(const ios_base&) = delete;

    static bool sync_with_stdio(bool sync = true);

  protected:
    ios_base();

  private:
    static int index;  // exposition only
    long*  iarray;     // exposition only
    void** parray;     // exposition only
  };
}
ios_­base defines several member types:
  • a type failure, defined as either a class derived from system_­error or a synonym for a class derived from system_­error;
  • a class Init;
  • three bitmask types, fmtflags, iostate, and openmode;
  • an enumerated type, seekdir.
It maintains several kinds of data:
  • state information that reflects the integrity of the stream buffer;
  • control information that influences how to interpret (format) input sequences and how to generate (format) output sequences;
  • additional information that is stored by the program for its private use.
[Note
:
For the sake of exposition, the maintained data is presented here as:
  • static int index, specifies the next available unique index for the integer or pointer arrays maintained for the private use of the program, initialized to an unspecified value;
  • long* iarray, points to the first element of an arbitrary-length long array maintained for the private use of the program;
  • void** parray, points to the first element of an arbitrary-length pointer array maintained for the private use of the program.
end note
]

30.5.3.1 Types [ios.types]

30.5.3.1.1 Class ios_­base​::​failure [ios::failure]

namespace std {
  class ios_base::failure : public system_error {
  public:
    explicit failure(const string& msg, const error_code& ec = io_errc::stream);
    explicit failure(const char* msg, const error_code& ec = io_errc::stream);
  };
}
An implementation is permitted to define ios_­base​::​failure as a synonym for a class with equivalent functionality to class ios_­base​::​failure shown in this subclause.
[Note
:
When ios_­base​::​failure is a synonym for another type it shall provide a nested type failure, to emulate the injected class name.
end note
]
The class failure defines the base class for the types of all objects thrown as exceptions, by functions in the iostreams library, to report errors detected during stream buffer operations.
When throwing ios_­base​::​failure exceptions, implementations should provide values of ec that identify the specific reason for the failure.
[Note
:
Errors arising from the operating system would typically be reported as system_­category() errors with an error value of the error number reported by the operating system.
Errors arising from within the stream library would typically be reported as error_­code(io_­errc​::​stream, iostream_­category()).
end note
]
explicit failure(const string& msg, const error_code& ec = io_errc::stream);
Effects: Constructs an object of class failure by constructing the base class with msg and ec.
explicit failure(const char* msg, const error_code& ec = io_errc::stream);
Effects: Constructs an object of class failure by constructing the base class with msg and ec.

30.5.3.1.2 Type ios_­base​::​fmtflags [ios::fmtflags]

using fmtflags = T1;
The type fmtflags is a bitmask type ([bitmask.types]).
Setting its elements has the effects indicated in Table 102.
Table 102fmtflags effects
Element
Effect(s) if set
boolalpha
insert and extract bool type in alphabetic format
dec
converts integer input or generates integer output in decimal base
fixed
generate floating-point output in fixed-point notation
hex
converts integer input or generates integer output in hexadecimal base
internal
adds fill characters at a designated internal point in certain generated output, or identical to right if no such point is designated
left
adds fill characters on the right (final positions) of certain generated output
oct
converts integer input or generates integer output in octal base
right
adds fill characters on the left (initial positions) of certain generated output
scientific
generates floating-point output in scientific notation
showbase
generates a prefix indicating the numeric base of generated integer output
showpoint
generates a decimal-point character unconditionally in generated floating-point output
showpos
generates a + sign in non-negative generated numeric output
skipws
skips leading whitespace before certain input operations
unitbuf
flushes output after each output operation
uppercase
replaces certain lowercase letters with their uppercase equivalents in generated output
Type fmtflags also defines the constants indicated in Table 103.
Table 103fmtflags constants
Constant
Allowable values
adjustfield
left | right | internal
basefield
dec | oct | hex
floatfield
scientific | fixed

30.5.3.1.3 Type ios_­base​::​iostate [ios::iostate]

using iostate = T2;
The type iostate is a bitmask type ([bitmask.types]) that contains the elements indicated in Table 104.
Table 104iostate effects
Element
Effect(s) if set
badbit
indicates a loss of integrity in an input or output sequence (such as an irrecoverable read error from a file);
eofbit
indicates that an input operation reached the end of an input sequence;
failbit
indicates that an input operation failed to read the expected characters, or that an output operation failed to generate the desired characters.
Type iostate also defines the constant:

30.5.3.1.4 Type ios_­base​::​openmode [ios::openmode]

using openmode = T3;
The type openmode is a bitmask type ([bitmask.types]).
It contains the elements indicated in Table 105.
Table 105openmode effects
Element
Effect(s) if set
app
seek to end before each write
ate
open and seek to end immediately after opening
binary
perform input and output in binary mode (as opposed to text mode)
in
open for input
out
open for output
trunc
truncate an existing stream when opening

30.5.3.1.5 Type ios_­base​::​seekdir [ios::seekdir]

using seekdir = T4;
The type seekdir is an enumerated type ([enumerated.types]) that contains the elements indicated in Table 106.
Table 106seekdir effects
Element
Meaning
beg
request a seek (for subsequent input or output) relative to the beginning of the stream
cur
request a seek relative to the current position within the sequence
end
request a seek relative to the current end of the sequence

30.5.3.1.6 Class ios_­base​::​Init [ios::Init]

namespace std {
  class ios_base::Init {
  public:
    Init();
    ~Init();
  private:
    static int init_cnt; // exposition only
  };
}
The class Init describes an object whose construction ensures the construction of the eight objects declared in <iostream> ([iostream.objects]) that associate file stream buffers with the standard C streams provided for by the functions declared in <cstdio> ([cstdio.syn]).
For the sake of exposition, the maintained data is presented here as:
  • static int init_­cnt, counts the number of constructor and destructor calls for class Init, initialized to zero.
Init();
Effects: Constructs an object of class Init.
Constructs and initializes the objects cin, cout, cerr, clog, wcin, wcout, wcerr, and wclog if they have not already been constructed and initialized.
~Init();
Effects: Destroys an object of class Init.
If there are no other instances of the class still in existence, calls cout.flush(), cerr.flush(), clog.flush(), wcout.flush(), wcerr.flush(), wclog.flush().

30.5.3.2 ios_­base state functions [fmtflags.state]

fmtflags flags() const;
Returns: The format control information for both input and output.
fmtflags flags(fmtflags fmtfl);
Postconditions: fmtfl == flags().
Returns: The previous value of flags().
fmtflags setf(fmtflags fmtfl);
Effects: Sets fmtfl in flags().
Returns: The previous value of flags().
fmtflags setf(fmtflags fmtfl, fmtflags mask);
Effects: Clears mask in flags(), sets fmtfl & mask in flags().
Returns: The previous value of flags().
void unsetf(fmtflags mask);
Effects: Clears mask in flags().
streamsize precision() const;
Returns: The precision to generate on certain output conversions.
streamsize precision(streamsize prec);
Postconditions: prec == precision().
Returns: The previous value of precision().
streamsize width() const;
Returns: The minimum field width (number of characters) to generate on certain output conversions.
streamsize width(streamsize wide);
Postconditions: wide == width().
Returns: The previous value of width().

30.5.3.3 ios_­base functions [ios.base.locales]

locale imbue(const locale& loc);
Effects: Calls each registered callback pair (fn, index) ([ios.base.callback]) as (*fn)(imbue_­event, *this, index) at such a time that a call to ios_­base​::​getloc() from within fn returns the new locale value loc.
Returns: The previous value of getloc().
Postconditions: loc == getloc().
locale getloc() const;
Returns: If no locale has been imbued, a copy of the global C++ locale, locale(), in effect at the time of construction.
Otherwise, returns the imbued locale, to be used to perform locale-dependent input and output operations.

30.5.3.4 ios_­base static members [ios.members.static]

bool sync_with_stdio(bool sync = true);
Returns: true if the previous state of the standard iostream objects ([iostream.objects]) was synchronized and otherwise returns false.
The first time it is called, the function returns true.
Effects: If any input or output operation has occurred using the standard streams prior to the call, the effect is implementation-defined.
Otherwise, called with a false argument, it allows the standard streams to operate independently of the standard C streams.
When a standard iostream object str is synchronized with a standard stdio stream f, the effect of inserting a character c by
fputc(f, c);
is the same as the effect of
str.rdbuf()->sputc(c);
for any sequences of characters; the effect of extracting a character c by
c = fgetc(f);
is the same as the effect of
c = str.rdbuf()->sbumpc();
for any sequences of characters; and the effect of pushing back a character c by
ungetc(c, f);
is the same as the effect of
str.rdbuf()->sputbackc(c);
for any sequence of characters.292
This implies that operations on a standard iostream object can be mixed arbitrarily with operations on the corresponding stdio stream.
In practical terms, synchronization usually means that a standard iostream object and a standard stdio object share a buffer.

30.5.3.5 ios_­base storage functions [ios.base.storage]

static int xalloc();
Returns: index ++.
Remarks: Concurrent access to this function by multiple threads shall not result in a data race ([intro.multithread]).
long& iword(int idx);
Effects: If iarray is a null pointer, allocates an array of long of unspecified size and stores a pointer to its first element in iarray.
The function then extends the array pointed at by iarray as necessary to include the element iarray[idx].
Each newly allocated element of the array is initialized to zero.
The reference returned is invalid after any other operations on the object.293
However, the value of the storage referred to is retained, so that until the next call to copyfmt, calling iword with the same index yields another reference to the same value.
If the function fails294 and *this is a base class subobject of a basic_­ios<> object or subobject, the effect is equivalent to calling basic_­ios<>​::​setstate(badbit) on the derived object (which may throw failure).
Returns: On success iarray[idx].
On failure, a valid long& initialized to 0.
void*& pword(int idx);
Effects: If parray is a null pointer, allocates an array of pointers to void of unspecified size and stores a pointer to its first element in parray.
The function then extends the array pointed at by parray as necessary to include the element parray[idx].
Each newly allocated element of the array is initialized to a null pointer.
The reference returned is invalid after any other operations on the object.
However, the value of the storage referred to is retained, so that until the next call to copyfmt, calling pword with the same index yields another reference to the same value.
If the function fails295 and *this is a base class subobject of a basic_­ios<> object or subobject, the effect is equivalent to calling basic_­ios<>​::​setstate(badbit) on the derived object (which may throw failure).
Returns: On success parray[idx].
On failure a valid void*& initialized to 0.
Remarks: After a subsequent call to pword(int) for the same object, the earlier return value may no longer be valid.
An implementation is free to implement both the integer array pointed at by iarray and the pointer array pointed at by parray as sparse data structures, possibly with a one-element cache for each.
for example, because it cannot allocate space.
for example, because it cannot allocate space.

30.5.3.6 ios_­base callbacks [ios.base.callback]

void register_callback(event_callback fn, int index);
Effects: Registers the pair (fn, index) such that during calls to imbue() ([ios.base.locales]), copyfmt(), or ~ios_­base() ([ios.base.cons]), the function fn is called with argument index.
Functions registered are called when an event occurs, in opposite order of registration.
Functions registered while a callback function is active are not called until the next event.
Requires: The function fn shall not throw exceptions.
Remarks: Identical pairs are not merged.
A function registered twice will be called twice.

30.5.3.7 ios_­base constructors/destructor [ios.base.cons]

ios_base();
Effects: Each ios_­base member has an indeterminate value after construction.
The object's members shall be initialized by calling basic_­ios​::​init before the object's first use or before it is destroyed, whichever comes first; otherwise the behavior is undefined.
~ios_base();
Effects: Destroys an object of class ios_­base.
Calls each registered callback pair (fn, index) ([ios.base.callback]) as (*fn)(​erase_­event, *this, index) at such time that any ios_­base member function called from within fn has well defined results.

30.5.4 Class template fpos [fpos]

namespace std {
  template <class stateT> class fpos {
  public:
    // [fpos.members], members
    stateT state() const;
    void state(stateT);
  private;
    stateT st; // exposition only
  };
}

30.5.4.1 fpos members [fpos.members]

void state(stateT s);
Effects: Assigns s to st.
stateT state() const;
Returns: Current value of st.

30.5.4.2 fpos requirements [fpos.operations]

Operations specified in Table 107 are permitted.
In that table,
  • P refers to an instance of fpos,
  • p and q refer to values of type P,
  • O refers to type streamoff,
  • o refers to a value of type streamoff,
  • sz refers to a value of type streamsize and
  • i refers to a value of type int.
Table 107 — Position type requirements
Expression
Return type
Operational
Assertion/note
semantics
pre-/post-condition
P(i)
p == P(i)
note: a destructor is assumed.
P p(i);
P p = i;
Postconditions: p == P(i).
P(o)
fpos
converts from offset
O(p)
streamoff
converts to offset
P(O(p)) == p
p == q
convertible to bool
== is an equivalence relation
p != q
convertible to bool
!(p == q)
q = p + o
p += o
fpos
+ offset
q - o == p
q = p - o
p -= o
fpos
- offset
q + o == p
o = p - q
streamoff
distance
q + o == p
streamsize(o)
O(sz)
streamsize
streamoff
converts
converts
streamsize(O(sz)) == sz
streamsize(O(sz)) == sz
[Note
:
Every implementation is required to supply overloaded operators on fpos objects to satisfy the requirements of [fpos.operations].
It is unspecified whether these operators are members of fpos, global operators, or provided in some other way.
end note
]
Stream operations that return a value of type traits​::​pos_­type return P(O(-1)) as an invalid value to signal an error.
If this value is used as an argument to any istream, ostream, or streambuf member that accepts a value of type traits​::​pos_­type then the behavior of that function is undefined.

30.5.5 Class template basic_­ios [ios]

30.5.5.1 Overview [ios.overview]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_ios : public ios_base {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [iostate.flags], flags functions
    explicit operator bool() const;
    bool operator!() const;
    iostate rdstate() const;
    void clear(iostate state = goodbit);
    void setstate(iostate state);
    bool good() const;
    bool eof()  const;
    bool fail() const;
    bool bad()  const;

    iostate exceptions() const;
    void exceptions(iostate except);

    // [basic.ios.cons], constructor/destructor
    explicit basic_ios(basic_streambuf<charT, traits>* sb);
    virtual ~basic_ios();

    // [basic.ios.members], members
    basic_ostream<charT, traits>* tie() const;
    basic_ostream<charT, traits>* tie(basic_ostream<charT, traits>* tiestr);

    basic_streambuf<charT, traits>* rdbuf() const;
    basic_streambuf<charT, traits>* rdbuf(basic_streambuf<charT, traits>* sb);

    basic_ios& copyfmt(const basic_ios& rhs);

    char_type fill() const;
    char_type fill(char_type ch);

    locale imbue(const locale& loc);

    char      narrow(char_type c, char dfault) const;
    char_type widen(char c) const;

    basic_ios(const basic_ios&) = delete;
    basic_ios& operator=(const basic_ios&) = delete;

  protected:
    basic_ios();
    void init(basic_streambuf<charT, traits>* sb);
    void move(basic_ios& rhs);
    void move(basic_ios&& rhs);
    void swap(basic_ios& rhs) noexcept;
    void set_rdbuf(basic_streambuf<charT, traits>* sb);

  };
}

30.5.5.2 basic_­ios constructors [basic.ios.cons]

explicit basic_ios(basic_streambuf<charT, traits>* sb);
Effects: Constructs an object of class basic_­ios, assigning initial values to its member objects by calling init(sb).
basic_ios();
Effects: Constructs an object of class basic_­ios ([ios.base.cons]) leaving its member objects uninitialized.
The object shall be initialized by calling basic_­ios​::​init before its first use or before it is destroyed, whichever comes first; otherwise the behavior is undefined.
~basic_ios();
Remarks: The destructor does not destroy rdbuf().
void init(basic_streambuf<charT, traits>* sb);
Postconditions: The postconditions of this function are indicated in Table 108.
Table 108basic_­ios​::​init() effects
Element
Value
rdbuf()
sb
tie()
0
rdstate()
goodbit if sb is not a null pointer, otherwise badbit.
exceptions()
goodbit
flags()
skipws | dec
width()
0
precision()
6
fill()
widen(' ')
getloc()
a copy of the value returned by locale()
iarray
a null pointer
parray
a null pointer

30.5.5.3 Member functions [basic.ios.members]

basic_ostream<charT, traits>* tie() const;
Returns: An output sequence that is tied to (synchronized with) the sequence controlled by the stream buffer.
basic_ostream<charT, traits>* tie(basic_ostream<charT, traits>* tiestr);
Requires: If tiestr is not null, tiestr must not be reachable by traversing the linked list of tied stream objects starting from tiestr->tie().
Postconditions: tiestr == tie().
Returns: The previous value of tie().
basic_streambuf<charT, traits>* rdbuf() const;
Returns: A pointer to the streambuf associated with the stream.
basic_streambuf<charT, traits>* rdbuf(basic_streambuf<charT, traits>* sb);
Postconditions: sb == rdbuf().
Effects: Calls clear().
Returns: The previous value of rdbuf().
locale imbue(const locale& loc);
Effects: Calls ios_­base​::​imbue(loc) ([ios.base.locales]) and if rdbuf() != 0 then rdbuf()->pubimbue(loc) ([streambuf.locales]).
Returns: The prior value of ios_­base​::​imbue().
char narrow(char_type c, char dfault) const;
Returns: use_­facet<ctype<char_­type>>(getloc()).narrow(c, dfault)
char_type widen(char c) const;
Returns: use_­facet<ctype<char_­type>>(getloc()).widen(c)
char_type fill() const;
Returns: The character used to pad (fill) an output conversion to the specified field width.
char_type fill(char_type fillch);
Postconditions: traits​::​eq(fillch, fill()).
Returns: The previous value of fill().
basic_ios& copyfmt(const basic_ios& rhs);
Effects: If (this == &rhs) does nothing.
Otherwise assigns to the member objects of *this the corresponding member objects of rhs as follows:
  1. 1.
    calls each registered callback pair (fn, index) as (*fn)(erase_­event, *this, index);
  2. 2.
    assigns to the member objects of *this the corresponding member objects of rhs, except that
    • rdstate(), rdbuf(), and exceptions() are left unchanged;
    • the contents of arrays pointed at by pword and iword are copied, not the pointers themselves;296 and
    • if any newly stored pointer values in *this point at objects stored outside the object rhs and those objects are destroyed when rhs is destroyed, the newly stored pointer values are altered to point at newly constructed copies of the objects;
  3. 3.
    calls each callback pair that was copied from rhs as (*fn)(copyfmt_­event, *this, index);
  4. 4.
    calls exceptions(rhs.exceptions()).
[Note
:
The second pass through the callback pairs permits a copied pword value to be zeroed, or to have its referent deep copied or reference counted, or to have other special action taken.
end note
]
Postconditions: The postconditions of this function are indicated in Table 109.
Table 109basic_­ios​::​copyfmt() effects
Element
Value
rdbuf()
unchanged
tie()
rhs.tie()
rdstate()
unchanged
exceptions()
rhs.exceptions()
flags()
rhs.flags()
width()
rhs.width()
precision()
rhs.precision()
fill()
rhs.fill()
getloc()
rhs.getloc()
Returns: *this.
void move(basic_ios& rhs); void move(basic_ios&& rhs);
Postconditions: *this shall have the state that rhs had before the function call, except that rdbuf() shall return 0.
rhs shall be in a valid but unspecified state, except that rhs.rdbuf() shall return the same value as it returned before the function call, and rhs.tie() shall return 0.
void swap(basic_ios& rhs) noexcept;
Effects: The states of *this and rhs shall be exchanged, except that rdbuf() shall return the same value as it returned before the function call, and rhs.rdbuf() shall return the same value as it returned before the function call.
void set_rdbuf(basic_streambuf<charT, traits>* sb);
Requires: sb != nullptr.
Effects: Associates the basic_­streambuf object pointed to by sb with this stream without calling clear().
Postconditions: rdbuf() == sb.
Throws: Nothing.
This suggests an infinite amount of copying, but the implementation can keep track of the maximum element of the arrays that is nonzero.

30.5.5.4 basic_­ios flags functions [iostate.flags]

explicit operator bool() const;
Returns: !fail().
bool operator!() const;
Returns: fail().
iostate rdstate() const;
Returns: The error state of the stream buffer.
void clear(iostate state = goodbit);
Postconditions: If rdbuf() != 0 then state == rdstate(); otherwise rdstate() == (state | ios_­base​::​badbit).
Effects: If ((state | (rdbuf() ? goodbit : badbit)) & exceptions()) == 0, returns.
Otherwise, the function throws an object of class basic_­ios​::​failure ([ios::failure]), constructed with implementation-defined argument values.
void setstate(iostate state);
Effects: Calls clear(rdstate() | state) (which may throw basic_­ios​::​failure ([ios::failure])).
bool good() const;
Returns: rdstate() == 0
bool eof() const;
Returns: true if eofbit is set in rdstate().
bool fail() const;
Returns: true if failbit or badbit is set in rdstate().297
bool bad() const;
Returns: true if badbit is set in rdstate().
iostate exceptions() const;
Returns: A mask that determines what elements set in rdstate() cause exceptions to be thrown.
void exceptions(iostate except);
Postconditions: except == exceptions().
Effects: Calls clear(rdstate()).
Checking badbit also for fail() is historical practice.

30.5.6 ios_­base manipulators [std.ios.manip]

30.5.6.1 fmtflags manipulators [fmtflags.manip]

ios_base& boolalpha(ios_base& str);
Effects: Calls str.setf(ios_­base​::​boolalpha).
Returns: str.
ios_base& noboolalpha(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​boolalpha).
Returns: str.
ios_base& showbase(ios_base& str);
Effects: Calls str.setf(ios_­base​::​showbase).
Returns: str.
ios_base& noshowbase(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​showbase).
Returns: str.
ios_base& showpoint(ios_base& str);
Effects: Calls str.setf(ios_­base​::​showpoint).
Returns: str.
ios_base& noshowpoint(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​showpoint).
Returns: str.
ios_base& showpos(ios_base& str);
Effects: Calls str.setf(ios_­base​::​showpos).
Returns: str.
ios_base& noshowpos(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​showpos).
Returns: str.
ios_base& skipws(ios_base& str);
Effects: Calls str.setf(ios_­base​::​skipws).
Returns: str.
ios_base& noskipws(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​skipws).
Returns: str.
ios_base& uppercase(ios_base& str);
Effects: Calls str.setf(ios_­base​::​uppercase).
Returns: str.
ios_base& nouppercase(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​uppercase).
Returns: str.
ios_base& unitbuf(ios_base& str);
Effects: Calls str.setf(ios_­base​::​unitbuf).
Returns: str.
ios_base& nounitbuf(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​unitbuf).
Returns: str.

30.5.6.2 adjustfield manipulators [adjustfield.manip]

ios_base& internal(ios_base& str);
Effects: Calls str.setf(ios_­base​::​internal, ios_­base​::​adjustfield).
Returns: str.
ios_base& left(ios_base& str);
Effects: Calls str.setf(ios_­base​::​left, ios_­base​::​adjustfield).
Returns: str.
ios_base& right(ios_base& str);
Effects: Calls str.setf(ios_­base​::​right, ios_­base​::​adjustfield).
Returns: str.

30.5.6.3 basefield manipulators [basefield.manip]

ios_base& dec(ios_base& str);
Effects: Calls str.setf(ios_­base​::​dec, ios_­base​::​basefield).
Returns: str298.
ios_base& hex(ios_base& str);
Effects: Calls str.setf(ios_­base​::​hex, ios_­base​::​basefield).
Returns: str.
ios_base& oct(ios_base& str);
Effects: Calls str.setf(ios_­base​::​oct, ios_­base​::​basefield).
Returns: str.
The function signature dec(ios_­base&) can be called by the function signature basic_­ostream& stream​::​operator<<(ios_­base& (*)(ios_­base&)) to permit expressions of the form cout << dec to change the format flags stored in cout.

30.5.6.4 floatfield manipulators [floatfield.manip]

ios_base& fixed(ios_base& str);
Effects: Calls str.setf(ios_­base​::​fixed, ios_­base​::​floatfield).
Returns: str.
ios_base& scientific(ios_base& str);
Effects: Calls str.setf(ios_­base​::​scientific, ios_­base​::​floatfield).
Returns: str.
ios_base& hexfloat(ios_base& str);
Effects: Calls str.setf(ios_­base​::​fixed | ios_­base​::​scientific, ios_­base​::​floatfield).
Returns: str.
[Note
:
The more obvious use of ios_­base​::​hex to specify hexadecimal floating-point format would change the meaning of existing well defined programs.
C++ 2003 gives no meaning to the combination of fixed and scientific.
end note
]
ios_base& defaultfloat(ios_base& str);
Effects: Calls str.unsetf(ios_­base​::​floatfield).
Returns: str.

30.5.6.5 Error reporting [error.reporting]

error_code make_error_code(io_errc e) noexcept;
Returns: error_­code(static_­cast<int>(e), iostream_­category()).
error_condition make_error_condition(io_errc e) noexcept;
Returns: error_­condition(static_­cast<int>(e), iostream_­category()).
const error_category& iostream_category() noexcept;
Returns: A reference to an object of a type derived from class error_­category.
The object's default_­error_­condition and equivalent virtual functions shall behave as specified for the class error_­category.
The object's name virtual function shall return a pointer to the string "iostream".

30.6 Stream buffers [stream.buffers]

30.6.1 Header <streambuf> synopsis [streambuf.syn]

namespace std {
  template <class charT, class traits = char_traits<charT>>
    class basic_streambuf;
  using streambuf  = basic_streambuf<char>;
  using wstreambuf = basic_streambuf<wchar_t>;
}
The header <streambuf> defines types that control input from and output to character sequences.

30.6.2 Stream buffer requirements [streambuf.reqts]

Stream buffers can impose various constraints on the sequences they control.
Some constraints are:
  • The controlled input sequence can be not readable.
  • The controlled output sequence can be not writable.
  • The controlled sequences can be associated with the contents of other representations for character sequences, such as external files.
  • The controlled sequences can support operations directly to or from associated sequences.
  • The controlled sequences can impose limitations on how the program can read characters from a sequence, write characters to a sequence, put characters back into an input sequence, or alter the stream position.
Each sequence is characterized by three pointers which, if non-null, all point into the same charT array object.
The array object represents, at any moment, a (sub)sequence of characters from the sequence.
Operations performed on a sequence alter the values stored in these pointers, perform reads and writes directly to or from associated sequences, and alter “the stream position” and conversion state as needed to maintain this subsequence relationship.
The three pointers are:
  • the beginning pointer, or lowest element address in the array (called xbeg here);
  • the next pointer, or next element address that is a current candidate for reading or writing (called xnext here);
  • the end pointer, or first element address beyond the end of the array (called xend here).
The following semantic constraints shall always apply for any set of three pointers for a sequence, using the pointer names given immediately above:
  • If xnext is not a null pointer, then xbeg and xend shall also be non-null pointers into the same charT array, as described above; otherwise, xbeg and xend shall also be null.
  • If xnext is not a null pointer and xnext < xend for an output sequence, then a write position is available.
    In this case, *xnext shall be assignable as the next element to write (to put, or to store a character value, into the sequence).
  • If xnext is not a null pointer and xbeg < xnext for an input sequence, then a putback position is available.
    In this case, xnext[-1] shall have a defined value and is the next (preceding) element to store a character that is put back into the input sequence.
  • If xnext is not a null pointer and xnext < xend for an input sequence, then a read position is available.
    In this case, *xnext shall have a defined value and is the next element to read (to get, or to obtain a character value, from the sequence).

30.6.3 Class template basic_­streambuf [streambuf]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_streambuf {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    virtual ~basic_streambuf();

    // [streambuf.locales], locales
    locale   pubimbue(const locale& loc);
    locale   getloc() const;

    // [streambuf.buffer], buffer and positioning
    basic_streambuf* pubsetbuf(char_type* s, streamsize n);
    pos_type pubseekoff(off_type off, ios_base::seekdir way,
                        ios_base::openmode which
                          = ios_base::in | ios_base::out);
    pos_type pubseekpos(pos_type sp,
                        ios_base::openmode which
                          = ios_base::in | ios_base::out);
    int      pubsync();

    // Get and put areas
    // [streambuf.pub.get], get area
    streamsize in_avail();
    int_type snextc();
    int_type sbumpc();
    int_type sgetc();
    streamsize sgetn(char_type* s, streamsize n);

    // [streambuf.pub.pback], putback
    int_type sputbackc(char_type c);
    int_type sungetc();

    // [streambuf.pub.put], put area
    int_type   sputc(char_type c);
    streamsize sputn(const char_type* s, streamsize n);

  protected:
    basic_streambuf();
    basic_streambuf(const basic_streambuf& rhs);
    basic_streambuf& operator=(const basic_streambuf& rhs);

    void swap(basic_streambuf& rhs);

    // [streambuf.get.area], get area access
    char_type* eback() const;
    char_type* gptr()  const;
    char_type* egptr() const;
    void       gbump(int n);
    void       setg(char_type* gbeg, char_type* gnext, char_type* gend);

    // [streambuf.put.area], put area access
    char_type* pbase() const;
    char_type* pptr() const;
    char_type* epptr() const;
    void       pbump(int n);
    void       setp(char_type* pbeg, char_type* pend);

    // [streambuf.virtuals], virtual functions
    // [streambuf.virt.locales], locales
    virtual void imbue(const locale& loc);

    // [streambuf.virt.buffer], buffer management and positioning
    virtual basic_streambuf* setbuf(char_type* s, streamsize n);
    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
                             ios_base::openmode which
                               = ios_base::in | ios_base::out);
    virtual pos_type seekpos(pos_type sp,
                             ios_base::openmode which
                               = ios_base::in | ios_base::out);
    virtual int      sync();

    // [streambuf.virt.get], get area
    virtual streamsize showmanyc();
    virtual streamsize xsgetn(char_type* s, streamsize n);
    virtual int_type   underflow();
    virtual int_type   uflow();

    // [streambuf.virt.pback], putback
    virtual int_type   pbackfail(int_type c = traits::eof());

    // [streambuf.virt.put], put area
    virtual streamsize xsputn(const char_type* s, streamsize n);
    virtual int_type   overflow(int_type c = traits::eof());
  };
}
The class template basic_­streambuf serves as an abstract base class for deriving various stream buffers whose objects each control two character sequences:

30.6.3.1 basic_­streambuf constructors [streambuf.cons]

basic_streambuf();
Effects: Constructs an object of class basic_­streambuf<charT, traits> and initializes:299
  • all its pointer member objects to null pointers,
  • the getloc() member to a copy the global locale, locale(), at the time of construction.
Remarks: Once the getloc() member is initialized, results of calling locale member functions, and of members of facets so obtained, can safely be cached until the next time the member imbue is called.
basic_streambuf(const basic_streambuf& rhs);
Effects: Constructs a copy of rhs.
Postconditions:
  • eback() == rhs.eback()
  • gptr() == rhs.gptr()
  • egptr() == rhs.egptr()
  • pbase() == rhs.pbase()
  • pptr() == rhs.pptr()
  • epptr() == rhs.epptr()
  • getloc() == rhs.getloc()
~basic_streambuf();
Effects: None.
The default constructor is protected for class basic_­streambuf to assure that only objects for classes derived from this class may be constructed.

30.6.3.2 basic_­streambuf public member functions [streambuf.members]

30.6.3.2.1 Locales [streambuf.locales]

locale pubimbue(const locale& loc);
Postconditions: loc == getloc().
Effects: Calls imbue(loc).
Returns: Previous value of getloc().
locale getloc() const;
Returns: If pubimbue() has ever been called, then the last value of loc supplied, otherwise the current global locale, locale(), in effect at the time of construction.
If called after pubimbue() has been called but before pubimbue has returned (i.e., from within the call of imbue()) then it returns the previous value.

30.6.3.2.2 Buffer management and positioning [streambuf.buffer]

basic_streambuf* pubsetbuf(char_type* s, streamsize n);
Returns: setbuf(s, n).
pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out);
Returns: seekoff(off, way, which).
pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out);
Returns: seekpos(sp, which).
int pubsync();
Returns: sync().

30.6.3.2.3 Get area [streambuf.pub.get]

streamsize in_avail();
Returns: If a read position is available, returns egptr() - gptr().
Otherwise returns showmanyc() ([streambuf.virt.get]).
int_type snextc();
Effects: Calls sbumpc().
Returns: If that function returns traits​::​eof(), returns traits​::​eof().
Otherwise, returns sgetc().
int_type sbumpc();
Returns: If the input sequence read position is not available, returns uflow().
Otherwise, returns traits​::​to_­int_­type(*gptr()) and increments the next pointer for the input sequence.
int_type sgetc();
Returns: If the input sequence read position is not available, returns underflow().
Otherwise, returns traits​::​to_­int_­type(*gptr()).
streamsize sgetn(char_type* s, streamsize n);
Returns: xsgetn(s, n).

30.6.3.2.4 Putback [streambuf.pub.pback]

int_type sputbackc(char_type c);
Returns: If the input sequence putback position is not available, or if traits​::​eq(c, gptr()[-1]) is false, returns pbackfail(traits​::​to_­int_­type(c)).
Otherwise, decrements the next pointer for the input sequence and returns traits​::​to_­int_­type(*gptr()).
int_type sungetc();
Returns: If the input sequence putback position is not available, returns pbackfail().
Otherwise, decrements the next pointer for the input sequence and returns traits​::​to_­int_­type(*gptr()).

30.6.3.2.5 Put area [streambuf.pub.put]

int_type sputc(char_type c);
Returns: If the output sequence write position is not available, returns overflow(traits​::​to_­int_­type(c)).
Otherwise, stores c at the next pointer for the output sequence, increments the pointer, and returns traits​::​to_­int_­type(c).
streamsize sputn(const char_type* s, streamsize n);
Returns: xsputn(s, n).

30.6.3.3 basic_­streambuf protected member functions [streambuf.protected]

30.6.3.3.1 Assignment [streambuf.assign]

basic_streambuf& operator=(const basic_streambuf& rhs);
Effects: Assigns the data members of rhs to *this.
Postconditions:
  • eback() == rhs.eback()
  • gptr() == rhs.gptr()
  • egptr() == rhs.egptr()
  • pbase() == rhs.pbase()
  • pptr() == rhs.pptr()
  • epptr() == rhs.epptr()
  • getloc() == rhs.getloc()
Returns: *this.
void swap(basic_streambuf& rhs);
Effects: Swaps the data members of rhs and *this.

30.6.3.3.2 Get area access [streambuf.get.area]

char_type* eback() const;
Returns: The beginning pointer for the input sequence.
char_type* gptr() const;
Returns: The next pointer for the input sequence.
char_type* egptr() const;
Returns: The end pointer for the input sequence.
void gbump(int n);
Effects: Adds n to the next pointer for the input sequence.
void setg(char_type* gbeg, char_type* gnext, char_type* gend);
Postconditions: gbeg == eback(), gnext == gptr(), and gend == egptr().

30.6.3.3.3 Put area access [streambuf.put.area]

char_type* pbase() const;
Returns: The beginning pointer for the output sequence.
char_type* pptr() const;
Returns: The next pointer for the output sequence.
char_type* epptr() const;
Returns: The end pointer for the output sequence.
void pbump(int n);
Effects: Adds n to the next pointer for the output sequence.
void setp(char_type* pbeg, char_type* pend);
Postconditions: pbeg == pbase(), pbeg == pptr(), and pend == epptr().

30.6.3.4 basic_­streambuf virtual functions [streambuf.virtuals]

30.6.3.4.1 Locales [streambuf.virt.locales]

void imbue(const locale&);
Effects: Change any translations based on locale.
Remarks: Allows the derived class to be informed of changes in locale at the time they occur.
Between invocations of this function a class derived from streambuf can safely cache results of calls to locale functions and to members of facets so obtained.
Default behavior: Does nothing.

30.6.3.4.2 Buffer management and positioning [streambuf.virt.buffer]

basic_streambuf* setbuf(char_type* s, streamsize n);
Effects: Influences stream buffering in a way that is defined separately for each class derived from basic_­streambuf in this Clause ([stringbuf.virtuals], [filebuf.virtuals]).
Default behavior: Does nothing.
Returns this.
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out);
Effects: Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from basic_­streambuf in this Clause ([stringbuf.virtuals], [filebuf.virtuals]).
Default behavior: Returns pos_­type(off_­type(-1)).
pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out);
Effects: Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from basic_­streambuf in this Clause ([stringbuf], [filebuf]).
Default behavior: Returns pos_­type(off_­type(-1)).
int sync();
Effects: Synchronizes the controlled sequences with the arrays.
That is, if pbase() is non-null the characters between pbase() and pptr() are written to the controlled sequence.
The pointers may then be reset as appropriate.
Returns: -1 on failure.
What constitutes failure is determined by each derived class ([filebuf.virtuals]).
Default behavior: Returns zero.

30.6.3.4.3 Get area [streambuf.virt.get]

streamsize showmanyc();300
Returns: An estimate of the number of characters available in the sequence, or -1.
If it returns a positive value, then successive calls to underflow() will not return traits​::​eof() until at least that number of characters have been extracted from the stream.
If showmanyc() returns -1, then calls to underflow() or uflow() will fail.301
Default behavior: Returns zero.
Remarks: Uses traits​::​eof().
streamsize xsgetn(char_type* s, streamsize n);
Effects: Assigns up to n characters to successive elements of the array whose first element is designated by s.
The characters assigned are read from the input sequence as if by repeated calls to sbumpc().
Assigning stops when either n characters have been assigned or a call to sbumpc() would return traits​::​eof().
Returns: The number of characters assigned.302
Remarks: Uses traits​::​eof().
int_type underflow();
Remarks: The public members of basic_­streambuf call this virtual function only if gptr() is null or gptr() >= egptr()
Returns: traits​::​to_­int_­type(c), where c is the first character of the pending sequence, without moving the input sequence position past it.
If the pending sequence is null then the function returns traits​::​eof() to indicate failure.
The pending sequence of characters is defined as the concatenation of
  • the empty sequence if gptr() is null, otherwise the characters in [gptr(), egptr()), followed by
  • some (possibly empty) sequence of characters read from the input sequence.
The result character is the first character of the pending sequence if it is non-empty, otherwise the next character that would be read from the input sequence.
The backup sequence is the empty sequence if eback() is null, otherwise the characters in [eback(), gptr()).
Effects: The function sets up the gptr() and egptr() such that if the pending sequence is non-empty, then egptr() is non-null and the characters in [gptr(), egptr()) are the characters in the pending sequence, otherwise either gptr() is null or gptr() == egptr().
If eback() and gptr() are non-null then the function is not constrained as to their contents, but the “usual backup condition” is that either
  • the backup sequence contains at least gptr() - eback() characters, in which case the characters in [eback(), gptr()) agree with the last gptr() - eback() characters of the backup sequence, or
  • the characters in [gptr() - n, gptr()) agree with the backup sequence (where n is the length of the backup sequence).
Default behavior: Returns traits​::​eof().
int_type uflow();
Requires: The constraints are the same as for underflow(), except that the result character shall be transferred from the pending sequence to the backup sequence, and the pending sequence shall not be empty before the transfer.
Default behavior: Calls underflow().
If underflow() returns traits​::​eof(), returns traits​::​eof().
Otherwise, returns the value of traits​::​to_­int_­type(*gptr()) and increment the value of the next pointer for the input sequence.
Returns: traits​::​eof() to indicate failure.
The morphemes of showmanyc are “es-how-many-see”, not “show-manic”.
underflow or uflow might fail by throwing an exception prematurely.
The intention is not only that the calls will not return eof() but that they will return “immediately”.
Classes derived from basic_­streambuf can provide more efficient ways to implement xsgetn() and xsputn() by overriding these definitions from the base class.

30.6.3.4.4 Putback [streambuf.virt.pback]

int_type pbackfail(int_type c = traits::eof());
Remarks: The public functions of basic_­streambuf call this virtual function only when gptr() is null, gptr() == eback(), or traits​::​eq(traits​::​to_­char_­type(c), gptr()[-1]) returns false.
Other calls shall also satisfy that constraint.
The pending sequence is defined as for underflow(), with the modifications that
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns true, then the input sequence is backed up one character before the pending sequence is determined.
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns false, then c is prepended.
    Whether the input sequence is backed up or modified in any other way is unspecified.
Postconditions: On return, the constraints of gptr(), eback(), and pptr() are the same as for underflow().
Returns: traits​::​eof() to indicate failure.
Failure may occur because the input sequence could not be backed up, or if for some other reason the pointers could not be set consistent with the constraints.
pbackfail() is called only when put back has really failed.
Returns some value other than traits​::​eof() to indicate success.
Default behavior: Returns traits​::​eof().

30.6.3.4.5 Put area [streambuf.virt.put]

streamsize xsputn(const char_type* s, streamsize n);
Effects: Writes up to n characters to the output sequence as if by repeated calls to sputc(c).
The characters written are obtained from successive elements of the array whose first element is designated by s.
Writing stops when either n characters have been written or a call to sputc(c) would return traits​::​eof().
It is unspecified whether the function calls overflow() when pptr() == epptr() becomes true or whether it achieves the same effects by other means.
Returns: The number of characters written.
int_type overflow(int_type c = traits::eof());
Effects: Consumes some initial subsequence of the characters of the pending sequence.
The pending sequence is defined as the concatenation of
  • the empty sequence if pbase() is not null, otherwise the pptr() - pbase() characters beginning at pbase(), followed by
  • the empty sequence if traits​::​eq_­int_­type(c, traits​::​eof()) returns true, otherwise the sequence consisting of c.
Remarks: The member functions sputc() and sputn() call this function in case that no room can be found in the put buffer enough to accommodate the argument character sequence.
Requires: Every overriding definition of this virtual function shall obey the following constraints:
  1. 1.
    The effect of consuming a character on the associated output sequence is specified303
  2. 2.
    Let r be the number of characters in the pending sequence not consumed.
    If r is nonzero then pbase() and pptr() shall be set so that: pptr() - pbase() == r and the r characters starting at pbase() are the associated output stream.
    In case r is zero (all characters of the pending sequence have been consumed) then either pbase() is set to nullptr, or pbase() and pptr() are both set to the same non-null value.
  3. 3.
    The function may fail if either appending some character to the associated output stream fails or if it is unable to establish pbase() and pptr() according to the above rules.
Returns: traits​::​eof() or throws an exception if the function fails.
Otherwise, returns some value other than traits​::​eof() to indicate success.304
Default behavior: Returns traits​::​eof().
That is, for each class derived from an instance of basic_­streambuf in this Clause ([stringbuf], [filebuf]), a specification of how consuming a character effects the associated output sequence is given.
There is no requirement on a program-defined class.
Typically, overflow returns c to indicate success, except when traits​::​eq_­int_­type(c, traits​::​eof()) returns true, in which case it returns traits​::​not_­eof(c).

30.7 Formatting and manipulators [iostream.format]

30.7.1 Header <istream> synopsis [istream.syn]

namespace std {
  template <class charT, class traits = char_traits<charT>>
    class basic_istream;

  using istream  = basic_istream<char>;
  using wistream = basic_istream<wchar_t>;

  template <class charT, class traits = char_traits<charT>>
    class basic_iostream;

  using iostream  = basic_iostream<char>;
  using wiostream = basic_iostream<wchar_t>;

  template <class charT, class traits>
    basic_istream<charT, traits>& ws(basic_istream<charT, traits>& is);

  template <class charT, class traits, class T>
    basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&& is, T&& x);
}

30.7.2 Header <ostream> synopsis [ostream.syn]

namespace std {
  template <class charT, class traits = char_traits<charT>>
    class basic_ostream;

  using ostream  = basic_ostream<char>;
  using wostream = basic_ostream<wchar_t>;

  template <class charT, class traits>
    basic_ostream<charT, traits>& endl(basic_ostream<charT, traits>& os);
  template <class charT, class traits>
    basic_ostream<charT, traits>& ends(basic_ostream<charT, traits>& os);
  template <class charT, class traits>
    basic_ostream<charT, traits>& flush(basic_ostream<charT, traits>& os);

  template <class charT, class traits, class T>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&& os, const T& x);
}

30.7.3 Header <iomanip> synopsis [iomanip.syn]

namespace std {
  // types T1, T2, ... are unspecified implementation types
  T1 resetiosflags(ios_base::fmtflags mask);
  T2 setiosflags  (ios_base::fmtflags mask);
  T3 setbase(int base);
  template<charT> T4 setfill(charT c);
  T5 setprecision(int n);
  T6 setw(int n);
  template <class moneyT> T7 get_money(moneyT& mon, bool intl = false);
  template <class moneyT> T8 put_money(const moneyT& mon, bool intl = false);
  template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
  template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);

  template <class charT>
    T11 quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\'));

  template <class charT, class traits, class Allocator>
    T12 quoted(const basic_string<charT, traits, Allocator>& s,
               charT delim = charT('"'), charT escape = charT('\\'));

  template <class charT, class traits, class Allocator>
    T13 quoted(basic_string<charT, traits, Allocator>& s,
               charT delim = charT('"'), charT escape = charT('\\'));

  template <class charT, class traits>
    T14 quoted(basic_string_view<charT, traits> s,
               charT delim = charT('"'), charT escape = charT('\\'));
}

30.7.4 Input streams [input.streams]

The header <istream> defines two types and a function signature that control input from a stream buffer along with a function template that extracts from stream rvalues.

30.7.4.1 Class template basic_­istream [istream]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_istream : virtual public basic_ios<charT, traits> {
  public:
    // types (inherited from basic_­ios ([ios])):
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [istream.cons], constructor/destructor
    explicit basic_istream(basic_streambuf<charT, traits>* sb);
    virtual ~basic_istream();

    // [istream::sentry], prefix/suffix
    class sentry;

    // [istream.formatted], formatted input
    basic_istream<charT, traits>&
      operator>>(basic_istream<charT, traits>& (*pf)(basic_istream<charT, traits>&));
    basic_istream<charT, traits>&
      operator>>(basic_ios<charT, traits>& (*pf)(basic_ios<charT, traits>&));
    basic_istream<charT, traits>&
      operator>>(ios_base& (*pf)(ios_base&));

    basic_istream<charT, traits>& operator>>(bool& n);
    basic_istream<charT, traits>& operator>>(short& n);
    basic_istream<charT, traits>& operator>>(unsigned short& n);
    basic_istream<charT, traits>& operator>>(int& n);
    basic_istream<charT, traits>& operator>>(unsigned int& n);
    basic_istream<charT, traits>& operator>>(long& n);
    basic_istream<charT, traits>& operator>>(unsigned long& n);
    basic_istream<charT, traits>& operator>>(long long& n);
    basic_istream<charT, traits>& operator>>(unsigned long long& n);
    basic_istream<charT, traits>& operator>>(float& f);
    basic_istream<charT, traits>& operator>>(double& f);
    basic_istream<charT, traits>& operator>>(long double& f);

    basic_istream<charT, traits>& operator>>(void*& p);
    basic_istream<charT, traits>& operator>>(basic_streambuf<char_type, traits>* sb);

    // [istream.unformatted], unformatted input
    streamsize gcount() const;
    int_type get();
    basic_istream<charT, traits>& get(char_type& c);
    basic_istream<charT, traits>& get(char_type* s, streamsize n);
    basic_istream<charT, traits>& get(char_type* s, streamsize n, char_type delim);
    basic_istream<charT, traits>& get(basic_streambuf<char_type, traits>& sb);
    basic_istream<charT, traits>& get(basic_streambuf<char_type, traits>& sb, char_type delim);

    basic_istream<charT, traits>& getline(char_type* s, streamsize n);
    basic_istream<charT, traits>& getline(char_type* s, streamsize n, char_type delim);

    basic_istream<charT, traits>& ignore(streamsize n = 1, int_type delim = traits::eof());
    int_type                      peek();
    basic_istream<charT, traits>& read    (char_type* s, streamsize n);
    streamsize                    readsome(char_type* s, streamsize n);

    basic_istream<charT, traits>& putback(char_type c);
    basic_istream<charT, traits>& unget();
    int sync();

    pos_type tellg();
    basic_istream<charT, traits>& seekg(pos_type);
    basic_istream<charT, traits>& seekg(off_type, ios_base::seekdir);

  protected:
    // [istream.cons], copy/move constructor
    basic_istream(const basic_istream& rhs) = delete;
    basic_istream(basic_istream&& rhs);

    // [istream.assign], assign and swap
    basic_istream& operator=(const basic_istream& rhs) = delete;
    basic_istream& operator=(basic_istream&& rhs);
    void swap(basic_istream& rhs);
  };

  // [istream.extractors], character extraction templates
  template<class charT, class traits>
    basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&, charT&);
  template<class traits>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, unsigned char&);
  template<class traits>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, signed char&);

  template<class charT, class traits>
    basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&, charT*);
  template<class traits>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, unsigned char*);
  template<class traits>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, signed char*);
}
The class template basic_­istream defines a number of member function signatures that assist in reading and interpreting input from sequences controlled by a stream buffer.
Two groups of member function signatures share common properties: the formatted input functions (or extractors) and the unformatted input functions. Both groups of input functions are described as if they obtain (or extract) input characters by calling rdbuf()->sbumpc() or rdbuf()->sgetc().
They may use other public members of istream.
If rdbuf()->sbumpc() or rdbuf()->sgetc() returns traits​::​eof(), then the input function, except as explicitly noted otherwise, completes its actions and does setstate(eofbit), which may throw ios_­base​::​failure ([iostate.flags]), before returning.
If one of these called functions throws an exception, then unless explicitly noted otherwise, the input function sets badbit in error state.
If badbit is on in exceptions(), the input function rethrows the exception without completing its actions, otherwise it does not throw anything and proceeds as if the called function had returned a failure indication.

30.7.4.1.1 basic_­istream constructors [istream.cons]

explicit basic_istream(basic_streambuf<charT, traits>* sb);
Effects: Constructs an object of class basic_­istream, initializing the base class subobject with basic_­ios​::​init(sb) ([basic.ios.cons]).
Postconditions: gcount() == 0.
basic_istream(basic_istream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by default constructing the base class, copying the gcount() from rhs, calling basic_­ios<charT, traits>​::​move(rhs) to initialize the base class, and setting the gcount() for rhs to 0.
virtual ~basic_istream();
Effects: Destroys an object of class basic_­istream.
Remarks: Does not perform any operations of rdbuf().

30.7.4.1.2 Class basic_­istream assign and swap [istream.assign]

basic_istream& operator=(basic_istream&& rhs);
Effects: As if by swap(rhs).
Returns: *this.
void swap(basic_istream& rhs);
Effects: Calls basic_­ios<charT, traits>​::​swap(rhs).
Exchanges the values returned by gcount() and rhs.gcount().

30.7.4.1.3 Class basic_­istream​::​sentry [istream::sentry]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_istream<charT, traits>::sentry {
    using traits_type = traits;
    bool ok_; // exposition only
  public:
    explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);
    ~sentry();
    explicit operator bool() const { return ok_; }
    sentry(const sentry&) = delete;
    sentry& operator=(const sentry&) = delete;
  };
}
The class sentry defines a class that is responsible for doing exception safe prefix and suffix operations.
explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);
Effects: If is.good() is false, calls is.setstate(failbit).
Otherwise, prepares for formatted or unformatted input.
First, if is.tie() is not a null pointer, the function calls is.tie()->flush() to synchronize the output sequence with any associated external C stream.
Except that this call can be suppressed if the put area of is.tie() is empty.
Further an implementation is allowed to defer the call to flush until a call of is.rdbuf()->underflow() occurs.
If no such call occurs before the sentry object is destroyed, the call to flush may be eliminated entirely.305
If noskipws is zero and is.flags() & ios_­base​::​skipws is nonzero, the function extracts and discards each character as long as the next available input character c is a whitespace character.
If is.rdbuf()->sbumpc() or is.rdbuf()->sgetc() returns traits​::​eof(), the function calls setstate(failbit | eofbit) (which may throw ios_­base​::​failure).
Remarks: The constructor
explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false)
uses the currently imbued locale in is, to determine whether the next input character is whitespace or not.
To decide if the character c is a whitespace character, the constructor performs as if it executes the following code fragment:
const ctype<charT>& ctype = use_facet<ctype<charT>>(is.getloc());
if (ctype.is(ctype.space, c) != 0)
  // c is a whitespace character.
If, after any preparation is completed, is.good() is true, ok_­ != false otherwise, ok_­ == false.
During preparation, the constructor may call setstate(failbit) (which may throw ios_­base​::​​failure ([iostate.flags]))306
~sentry();
Effects: None.
explicit operator bool() const;
Effects: Returns ok_­.
This will be possible only in functions that are part of the library.
The semantics of the constructor used in user code is as specified.
The sentry constructor and destructor can also perform additional implementation-dependent operations.

30.7.4.2 Formatted input functions [istream.formatted]

30.7.4.2.1 Common requirements [istream.formatted.reqmts]

Each formatted input function begins execution by constructing an object of class sentry with the noskipws (second) argument false.
If the sentry object returns true, when converted to a value of type bool, the function endeavors to obtain the requested input.
If an exception is thrown during input then ios​::​badbit is turned on307 in *this's error state.
If (exceptions()&badbit) != 0 then the exception is rethrown.
In any case, the formatted input function destroys the sentry object.
If no exception has been thrown, it returns *this.
This is done without causing an ios​::​failure to be thrown.

30.7.4.2.2 Arithmetic extractors [istream.formatted.arithmetic]

operator>>(unsigned short& val); operator>>(unsigned int& val); operator>>(long& val); operator>>(unsigned long& val); operator>>(long long& val); operator>>(unsigned long long& val); operator>>(float& val); operator>>(double& val); operator>>(long double& val); operator>>(bool& val); operator>>(void*& val);
As in the case of the inserters, these extractors depend on the locale's num_­get<> ([locale.num.get]) object to perform parsing the input stream data.
These extractors behave as formatted input functions (as described in [istream.formatted.reqmts]).
After a sentry object is constructed, the conversion occurs as if performed by the following code fragment:
using numget = num_get<charT, istreambuf_iterator<charT, traits>>;
iostate err = iostate::goodbit;
use_facet<numget>(loc).get(*this, 0, *this, err, val);
setstate(err);
In the above fragment, loc stands for the private member of the basic_­ios class.
[Note
:
The first argument provides an object of the istreambuf_­iterator class which is an iterator pointed to an input stream.
It bypasses istreams and uses streambufs directly.
end note
]
Class locale relies on this type as its interface to istream, so that it does not need to depend directly on istream.
operator>>(short& val);
The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment):
using numget = num_get<charT, istreambuf_iterator<charT, traits>>;
iostate err = ios_base::goodbit;
long lval;
use_facet<numget>(loc).get(*this, 0, *this, err, lval);
if (lval < numeric_limits<short>::min()) {
  err |= ios_base::failbit;
  val = numeric_limits<short>::min();
} else if (numeric_limits<short>::max() < lval) {
  err |= ios_base::failbit;
  val = numeric_limits<short>::max();
}  else
  val = static_cast<short>(lval);
setstate(err);
operator>>(int& val);
The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment):
using numget = num_get<charT, istreambuf_iterator<charT, traits>>;
iostate err = ios_base::goodbit;
long lval;
use_facet<numget>(loc).get(*this, 0, *this, err, lval);
if (lval < numeric_limits<int>::min()) {
  err |= ios_base::failbit;
  val = numeric_limits<int>::min();
} else if (numeric_limits<int>::max() < lval) {
  err |= ios_base::failbit;
  val = numeric_limits<int>::max();
}  else
  val = static_cast<int>(lval);
setstate(err);

30.7.4.2.3 basic_­istream​::​operator>> [istream.extractors]

basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& (*pf)(basic_istream<charT, traits>&));
Effects: None.
This extractor does not behave as a formatted input function (as described in [istream.formatted.reqmts]).
Returns: pf(*this).308
basic_istream<charT, traits>& operator>>(basic_ios<charT, traits>& (*pf)(basic_ios<charT, traits>&));
Effects: Calls pf(*this).
This extractor does not behave as a formatted input function (as described in [istream.formatted.reqmts]).
Returns: *this.
basic_istream<charT, traits>& operator>>(ios_base& (*pf)(ios_base&));
Effects: Calls pf(*this).309
This extractor does not behave as a formatted input function (as described in [istream.formatted.reqmts]).
Returns: *this.
template<class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& in, charT* s); template<class traits> basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in, unsigned char* s); template<class traits> basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in, signed char* s);
Effects: Behaves like a formatted input member (as described in [istream.formatted.reqmts]) of in.
After a sentry object is constructed, operator>> extracts characters and stores them into successive locations of an array whose first element is designated by s.
If width() is greater than zero, n is width().
Otherwise n is the number of elements of the largest array of char_­type that can store a terminating charT().
n is the maximum number of characters stored.
Characters are extracted and stored until any of the following occurs:
  • n-1 characters are stored;
  • end of file occurs on the input sequence;
  • letting ct be use_­facet<ctype<charT>>(in.getloc()), ct.is(ct.space, c) is true.
operator>> then stores a null byte (charT()) in the next position, which may be the first position if no characters were extracted.
operator>> then calls width(0).
If the function extracted no characters, it calls setstate(failbit), which may throw ios_­base​::​​failure ([iostate.flags]).
Returns: in.
template<class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& in, charT& c); template<class traits> basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in, unsigned char& c); template<class traits> basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in, signed char& c);
Effects: Behaves like a formatted input member (as described in [istream.formatted.reqmts]) of in.
After a sentry object is constructed a character is extracted from in, if one is available, and stored in c.
Otherwise, the function calls in.setstate(failbit).
Returns: in.
basic_istream<charT, traits>& operator>>(basic_streambuf<charT, traits>* sb);
Effects: Behaves as an unformatted input function ([istream.unformatted]).
If sb is null, calls setstate(failbit), which may throw ios_­base​::​failure ([iostate.flags]).
After a sentry object is constructed, extracts characters from *this and inserts them in the output sequence controlled by sb.
Characters are extracted and inserted until any of the following occurs:
  • end-of-file occurs on the input sequence;
  • inserting in the output sequence fails (in which case the character to be inserted is not extracted);
  • an exception occurs (in which case the exception is caught).
If the function inserts no characters, it calls setstate(failbit), which may throw ios_­base​::​​failure ([iostate.flags]).
If it inserted no characters because it caught an exception thrown while extracting characters from *this and failbit is on in exceptions() ([iostate.flags]), then the caught exception is rethrown.
Returns: *this.
See, for example, the function signature ws(basic_­istream&) ([istream.manip]).
See, for example, the function signature dec(ios_­base&) ([basefield.manip]).

30.7.4.3 Unformatted input functions [istream.unformatted]

Each unformatted input function begins execution by constructing an object of class sentry with the default argument noskipws (second) argument true.
If the sentry object returns true, when converted to a value of type bool, the function endeavors to obtain the requested input.
Otherwise, if the sentry constructor exits by throwing an exception or if the sentry object returns false, when converted to a value of type bool, the function returns without attempting to obtain any input.
In either case the number of extracted characters is set to 0; unformatted input functions taking a character array of nonzero size as an argument shall also store a null character (using charT()) in the first location of the array.
If an exception is thrown during input then ios​::​badbit is turned on310 in *this's error state.
(Exceptions thrown from basic_­ios<>​::​clear() are not caught or rethrown.)
If (exceptions()&badbit) != 0 then the exception is rethrown.
It also counts the number of characters extracted.
If no exception has been thrown it ends by storing the count in a member object and returning the value specified.
In any event the sentry object is destroyed before leaving the unformatted input function.
streamsize gcount() const;
Effects: None.
This member function does not behave as an unformatted input function (as described above).
Returns: The number of characters extracted by the last unformatted input member function called for the object.
int_type get();
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, extracts a character c, if one is available.
Otherwise, the function calls setstate(failbit), which may throw ios_­base​::​failure ([iostate.flags]),
Returns: c if available, otherwise traits​::​eof().
basic_istream<charT, traits>& get(char_type& c);
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, extracts a character, if one is available, and assigns it to c.311
Otherwise, the function calls setstate(failbit) (which may throw ios_­base​::​failure ([iostate.flags])).
Returns: *this.
basic_istream<charT, traits>& get(char_type* s, streamsize n, char_type delim);
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, extracts characters and stores them into successive locations of an array whose first element is designated by s.312
Characters are extracted and stored until any of the following occurs:
  • n is less than one or n - 1 characters are stored;
  • end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit));
  • traits​::​eq(c, delim) for the next available input character c (in which case c is not extracted).
If the function stores no characters, it calls setstate(failbit) (which may throw ios_­base​::​​failure ([iostate.flags])).
In any case, if n is greater than zero it then stores a null character into the next successive location of the array.
Returns: *this.
basic_istream<charT, traits>& get(char_type* s, streamsize n);
Effects: Calls get(s, n, widen('\n')).
Returns: Value returned by the call.
basic_istream<charT, traits>& get(basic_streambuf<char_type, traits>& sb, char_type delim);
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, extracts characters and inserts them in the output sequence controlled by sb.
Characters are extracted and inserted until any of the following occurs:
  • end-of-file occurs on the input sequence;
  • inserting in the output sequence fails (in which case the character to be inserted is not extracted);
  • traits​::​eq(c, delim) for the next available input character c (in which case c is not extracted);
  • an exception occurs (in which case, the exception is caught but not rethrown).
If the function inserts no characters, it calls setstate(failbit), which may throw ios_­base​::​​failure ([iostate.flags]).
Returns: *this.
basic_istream<charT, traits>& get(basic_streambuf<char_type, traits>& sb);
Effects: Calls get(sb, widen('\n')).
Returns: Value returned by the call.
basic_istream<charT, traits>& getline(char_type* s, streamsize n, char_type delim);
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, extracts characters and stores them into successive locations of an array whose first element is designated by s.313
Characters are extracted and stored until one of the following occurs:
  1. 1.
    end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit));
  2. 2.
    traits​::​eq(c, delim) for the next available input character c (in which case the input character is extracted but not stored);314
  3. 3.
    n is less than one or n - 1 characters are stored (in which case the function calls setstate(​failbit)).
These conditions are tested in the order shown.315
If the function extracts no characters, it calls setstate(failbit) (which may throw ios_­base​::​​failure ([iostate.flags])).316
In any case, if n is greater than zero, it then stores a null character (using charT()) into the next successive location of the array.
Returns: *this.
[Example
:
#include <iostream>

int main() {
  using namespace std;
  const int line_buffer_size = 100;

  char buffer[line_buffer_size];
  int line_number = 0;
  while (cin.getline(buffer, line_buffer_size, '\n') || cin.gcount()) {
    int count = cin.gcount();
    if (cin.eof())
      cout << "Partial final line";   // cin.fail() is false
    else if (cin.fail()) {
      cout << "Partial long line";
      cin.clear(cin.rdstate() & ~ios_base::failbit);
    } else {
      count--;                        // Don't include newline in count
      cout << "Line " << ++line_number;
    }
    cout << " (" << count << " chars): " << buffer << endl;
  }
}
end example
]
basic_istream<charT, traits>& getline(char_type* s, streamsize n);
Returns: getline(s, n, widen('\n'))
basic_istream<charT, traits>& ignore(streamsize n = 1, int_type delim = traits::eof());
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, extracts characters and discards them.
Characters are extracted until any of the following occurs:
  • n != numeric_­limits<streamsize>​::​max() ([numeric.limits]) and n characters have been extracted so far
  • end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit), which may throw ios_­base​::​failure ([iostate.flags]));
  • traits​::​eq_­int_­type(traits​::​to_­int_­type(c), delim) for the next available input character c (in which case c is extracted).
Remarks: The last condition will never occur if traits​::​eq_­int_­type(delim, traits​::​eof()).
Returns: *this.
int_type peek();
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, reads but does not extract the current input character.
Returns: traits​::​eof() if good() is false.
Otherwise, returns rdbuf()->sgetc().
basic_istream<charT, traits>& read(char_type* s, streamsize n);
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, if !good() calls setstate(failbit) which may throw an exception, and return.
Otherwise extracts characters and stores them into successive locations of an array whose first element is designated by s.317
Characters are extracted and stored until either of the following occurs:
  • n characters are stored;
  • end-of-file occurs on the input sequence (in which case the function calls setstate(failbit | eofbit), which may throw ios_­base​::​failure ([iostate.flags])).
Returns: *this.
streamsize readsome(char_type* s, streamsize n);
Effects: Behaves as an unformatted input function (as described above).
After constructing a sentry object, if !good() calls setstate(failbit) which may throw an exception, and return.
Otherwise extracts characters and stores them into successive locations of an array whose first element is designated by s.
If rdbuf()->in_­avail() == -1, calls setstate(eofbit) (which may throw ios_­base​::​failure ([iostate.flags])), and extracts no characters;
  • If rdbuf()->in_­avail() == 0, extracts no characters
  • If rdbuf()->in_­avail() > 0, extracts min(rdbuf()->in_­avail(), n)).
Returns: The number of characters extracted.
basic_istream<charT, traits>& putback(char_type c);
Effects: Behaves as an unformatted input function (as described above), except that the function first clears eofbit.
After constructing a sentry object, if !good() calls setstate(failbit) which may throw an exception, and return.
If rdbuf() is not null, calls rdbuf->sputbackc().
If rdbuf() is null, or if sputbackc() returns traits​::​eof(), calls setstate(badbit) (which may throw ios_­base​::​failure ([iostate.flags])).
[Note
:
This function extracts no characters, so the value returned by the next call to gcount() is 0.
end note
]
Returns: *this.
basic_istream<charT, traits>& unget();
Effects: Behaves as an unformatted input function (as described above), except that the function first clears eofbit.
After constructing a sentry object, if !good() calls setstate(failbit) which may throw an exception, and return.
If rdbuf() is not null, calls rdbuf()->sungetc().
If rdbuf() is null, or if sungetc() returns traits​::​eof(), calls setstate(badbit) (which may throw ios_­base​::​failure ([iostate.flags])).
[Note
:
This function extracts no characters, so the value returned by the next call to gcount() is 0.
end note
]
Returns: *this.
int sync();
Effects: Behaves as an unformatted input function (as described above), except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to gcount().
After constructing a sentry object, if rdbuf() is a null pointer, returns -1.
Otherwise, calls rdbuf()->pubsync() and, if that function returns -1 calls setstate(badbit) (which may throw ios_­base​::​failure ([iostate.flags]), and returns -1.
Otherwise, returns zero.
pos_type tellg();
Effects: Behaves as an unformatted input function (as described above), except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to gcount().
Returns: After constructing a sentry object, if fail() != false, returns pos_­type(-1) to indicate failure.
Otherwise, returns rdbuf()->pubseekoff(0, cur, in).
basic_istream<charT, traits>& seekg(pos_type pos);
Effects: Behaves as an unformatted input function (as described above), except that the function first clears eofbit, it does not count the number of characters extracted, and it does not affect the value returned by subsequent calls to gcount().
After constructing a sentry object, if fail() != true, executes rdbuf()->pubseekpos(pos, ios_­base​::​in).
In case of failure, the function calls setstate(failbit) (which may throw ios_­base​::​failure).
Returns: *this.
basic_istream<charT, traits>& seekg(off_type off, ios_base::seekdir dir);
Effects: Behaves as an unformatted input function (as described above), except that the function first clears eofbit, does not count the number of characters extracted, and does not affect the value returned by subsequent calls to gcount().
After constructing a sentry object, if fail() != true, executes rdbuf()->pubseekoff(off, dir, ios_­base​::​in).
In case of failure, the function calls setstate(​failbit) (which may throw ios_­base​::​failure).
Returns: *this.
This is done without causing an ios​::​failure to be thrown.
Note that this function is not overloaded on types signed char and unsigned char.
Note that this function is not overloaded on types signed char and unsigned char.
Note that this function is not overloaded on types signed char and unsigned char.
Since the final input character is “extracted”, it is counted in the gcount(), even though it is not stored.
This allows an input line which exactly fills the buffer, without setting failbit.
This is different behavior than the historical AT&T implementation.
This implies an empty input line will not cause failbit to be set.
Note that this function is not overloaded on types signed char and unsigned char.

30.7.4.4 Standard basic_­istream manipulators [istream.manip]

template <class charT, class traits> basic_istream<charT, traits>& ws(basic_istream<charT, traits>& is);
Effects: Behaves as an unformatted input function ([istream.unformatted]), except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to is.
gcount().
After constructing a sentry object extracts characters as long as the next available character c is whitespace or until there are no more characters in the sequence.
Whitespace characters are distinguished with the same criterion as used by sentry​::​sentry ([istream::sentry]).
If ws stops extracting characters because there are no more available it sets eofbit, but not failbit.
Returns: is.

30.7.4.5 Rvalue stream extraction [istream.rvalue]

template <class charT, class traits, class T> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&& is, T&& x);
Effects: Equivalent to:
is >> std::forward<T>(x);
return is;
Remarks: This function shall not participate in overload resolution unless the expression is >> std​::​forward<T>(x) is well-formed.

30.7.4.6 Class template basic_­iostream [iostreamclass]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_iostream
    : public basic_istream<charT, traits>,
      public basic_ostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [iostream.cons], constructor
    explicit basic_iostream(basic_streambuf<charT, traits>* sb);

    // [iostream.dest], destructor
    virtual ~basic_iostream();

  protected:
    // [iostream.cons], constructor
    basic_iostream(const basic_iostream& rhs) = delete;
    basic_iostream(basic_iostream&& rhs);

    // [iostream.assign], assign and swap
    basic_iostream& operator=(const basic_iostream& rhs) = delete;
    basic_iostream& operator=(basic_iostream&& rhs);
    void swap(basic_iostream& rhs);
  };
}
The class template basic_­iostream inherits a number of functions that allow reading input and writing output to sequences controlled by a stream buffer.

30.7.4.6.1 basic_­iostream constructors [iostream.cons]

explicit basic_iostream(basic_streambuf<charT, traits>* sb);
Effects: Constructs an object of class basic_­iostream, initializing the base class subobjects with basic_­istream<charT, traits>(sb) ([istream]) and basic_­ostream<charT, traits>(sb) ([ostream]).
Postconditions: rdbuf() == sb and gcount() == 0.
basic_iostream(basic_iostream&& rhs);
Effects: Move constructs from the rvalue rhs by constructing the basic_­istream base class with move(rhs).

30.7.4.6.2 basic_­iostream destructor [iostream.dest]

virtual ~basic_iostream();
Effects: Destroys an object of class basic_­iostream.
Remarks: Does not perform any operations on rdbuf().

30.7.4.6.3 basic_­iostream assign and swap [iostream.assign]

basic_iostream& operator=(basic_iostream&& rhs);
Effects: As if by swap(rhs).
void swap(basic_iostream& rhs);
Effects: Calls basic_­istream<charT, traits>​::​swap(rhs).

30.7.5 Output streams [output.streams]

The header <ostream> defines a type and several function signatures that control output to a stream buffer along with a function template that inserts into stream rvalues.

30.7.5.1 Class template basic_­ostream [ostream]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_ostream : virtual public basic_ios<charT, traits> {
  public:
    // types (inherited from basic_­ios ([ios])):
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [ostream.cons], constructor/destructor
    explicit basic_ostream(basic_streambuf<char_type, traits>* sb);
    virtual ~basic_ostream();

    // [ostream::sentry], prefix/suffix
    class sentry;

    // [ostream.formatted], formatted output
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& (*pf)(basic_ostream<charT, traits>&));
    basic_ostream<charT, traits>&
      operator<<(basic_ios<charT, traits>& (*pf)(basic_ios<charT, traits>&));
    basic_ostream<charT, traits>&
      operator<<(ios_base& (*pf)(ios_base&));

    basic_ostream<charT, traits>& operator<<(bool n);
    basic_ostream<charT, traits>& operator<<(short n);
    basic_ostream<charT, traits>& operator<<(unsigned short n);
    basic_ostream<charT, traits>& operator<<(int n);
    basic_ostream<charT, traits>& operator<<(unsigned int n);
    basic_ostream<charT, traits>& operator<<(long n);
    basic_ostream<charT, traits>& operator<<(unsigned long n);
    basic_ostream<charT, traits>& operator<<(long long n);
    basic_ostream<charT, traits>& operator<<(unsigned long long n);
    basic_ostream<charT, traits>& operator<<(float f);
    basic_ostream<charT, traits>& operator<<(double f);
    basic_ostream<charT, traits>& operator<<(long double f);

    basic_ostream<charT, traits>& operator<<(const void* p);
    basic_ostream<charT, traits>& operator<<(nullptr_t);
    basic_ostream<charT, traits>& operator<<(basic_streambuf<char_type, traits>* sb);

    // [ostream.unformatted], unformatted output
    basic_ostream<charT, traits>& put(char_type c);
    basic_ostream<charT, traits>& write(const char_type* s, streamsize n);

    basic_ostream<charT, traits>& flush();

    // [ostream.seeks], seeks
    pos_type tellp();
    basic_ostream<charT, traits>& seekp(pos_type);
    basic_ostream<charT, traits>& seekp(off_type, ios_base::seekdir);

  protected:
    // [ostream.cons], copy/move constructor
    basic_ostream(const basic_ostream& rhs) = delete;
    basic_ostream(basic_ostream&& rhs);

    // [ostream.assign], assign and swap
    basic_ostream& operator=(const basic_ostream& rhs) = delete;
    basic_ostream& operator=(basic_ostream&& rhs);
    void swap(basic_ostream& rhs);
  };

  // [ostream.inserters.character], character inserters
  template<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, charT);
  template<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, char);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char);

  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, signed char);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, unsigned char);

  template<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const charT*);
  template<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const char*);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char*);

  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const signed char*);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const unsigned char*);
}
The class template basic_­ostream defines a number of member function signatures that assist in formatting and writing output to output sequences controlled by a stream buffer.
Two groups of member function signatures share common properties: the formatted output functions (or inserters) and the unformatted output functions. Both groups of output functions generate (or insert) output characters by actions equivalent to calling rdbuf()->sputc(int_­type).
They may use other public members of basic_­ostream except that they shall not invoke any virtual members of rdbuf() except overflow(), xsputn(), and sync().
If one of these called functions throws an exception, then unless explicitly noted otherwise the output function sets badbit in error state.
If badbit is on in exceptions(), the output function rethrows the exception without completing its actions, otherwise it does not throw anything and treat as an error.

30.7.5.1.1 basic_­ostream constructors [ostream.cons]

explicit basic_ostream(basic_streambuf<charT, traits>* sb);
Effects: Constructs an object of class basic_­ostream, initializing the base class subobject with basic_­ios<charT, traits>​::​init(sb) ([basic.ios.cons]).
Postconditions: rdbuf() == sb.
basic_ostream(basic_ostream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by default constructing the base class and calling basic_­ios<charT, traits>​::​move(rhs) to initialize the base class.
virtual ~basic_ostream();
Effects: Destroys an object of class basic_­ostream.
Remarks: Does not perform any operations on rdbuf().

30.7.5.1.2 Class basic_­ostream assign and swap [ostream.assign]

basic_ostream& operator=(basic_ostream&& rhs);
Effects: As if by swap(rhs).
Returns: *this.
void swap(basic_ostream& rhs);
Effects: Calls basic_­ios<charT, traits>​::​swap(rhs).

30.7.5.1.3 Class basic_­ostream​::​sentry [ostream::sentry]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_ostream<charT, traits>::sentry {
    bool ok_; // exposition only
  public:
    explicit sentry(basic_ostream<charT, traits>& os);
    ~sentry();
    explicit operator bool() const { return ok_; }

    sentry(const sentry&) = delete;
    sentry& operator=(const sentry&) = delete;
  };
}
The class sentry defines a class that is responsible for doing exception safe prefix and suffix operations.
explicit sentry(basic_ostream<charT, traits>& os);
If os.good() is nonzero, prepares for formatted or unformatted output.
If os.tie() is not a null pointer, calls os.tie()->flush().318
If, after any preparation is completed, os.good() is true, ok_­ == true otherwise, ok_­ == false.
During preparation, the constructor may call setstate(failbit) (which may throw ios_­base​::​​failure ([iostate.flags]))319
~sentry();
If (os.flags() & ios_­base​::​unitbuf) && !uncaught_­exceptions() && os.good() is true, calls os.rdbuf()->pubsync().
If that function returns -1, sets badbit in os.rdstate() without propagating an exception.
explicit operator bool() const;
Effects: Returns ok_­.
The call os.tie()->flush() does not necessarily occur if the function can determine that no synchronization is necessary.
The sentry constructor and destructor can also perform additional implementation-dependent operations.

30.7.5.1.4 basic_­ostream seek members [ostream.seeks]

Each seek member function begins execution by constructing an object of class sentry.
It returns by destroying the sentry object.
pos_type tellp();
Returns: If fail() != false, returns pos_­type(-1) to indicate failure.
Otherwise, returns rdbuf()->​pubseekoff(​0, cur, out).
basic_ostream<charT, traits>& seekp(pos_type pos);
Effects: If fail() != true, executes rdbuf()->pubseekpos(pos, ios_­base​::​out).
In case of failure, the function calls setstate(failbit) (which may throw ios_­base​::​failure).
Returns: *this.
basic_ostream<charT, traits>& seekp(off_type off, ios_base::seekdir dir);
Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir, ios_­base​::​out).
In case of failure, the function calls setstate(failbit) (which may throw ios_­base​::​failure).
Returns: *this.

30.7.5.2 Formatted output functions [ostream.formatted]

30.7.5.2.1 Common requirements [ostream.formatted.reqmts]

Each formatted output function begins execution by constructing an object of class sentry.
If this object returns true when converted to a value of type bool, the function endeavors to generate the requested output.
If the generation fails, then the formatted output function does setstate(ios_­base​::​failbit), which might throw an exception.
If an exception is thrown during output, then ios​::​badbit is turned on320 in *this's error state.
If (exceptions()&badbit) != 0 then the exception is rethrown.
Whether or not an exception is thrown, the sentry object is destroyed before leaving the formatted output function.
If no exception is thrown, the result of the formatted output function is *this.
The descriptions of the individual formatted output functions describe how they perform output and do not mention the sentry object.
If a formatted output function of a stream os determines padding, it does so as follows.
Given a charT character sequence seq where charT is the character type of the stream, if the length of seq is less than os.width(), then enough copies of os.fill() are added to this sequence as necessary to pad to a width of os.width() characters.
If (os.flags() & ios_­base​::​adjustfield) == ios_­base​::​left is true, the fill characters are placed after the character sequence; otherwise, they are placed before the character sequence.
without causing an ios​::​failure to be thrown.

30.7.5.2.2 Arithmetic inserters [ostream.inserters.arithmetic]

operator<<(bool val); operator<<(short val); operator<<(unsigned short val); operator<<(int val); operator<<(unsigned int val); operator<<(long val); operator<<(unsigned long val); operator<<(long long val); operator<<(unsigned long long val); operator<<(float val); operator<<(double val); operator<<(long double val); operator<<(const void* val);
Effects: The classes num_­get<> and num_­put<> handle locale-dependent numeric formatting and parsing.
These inserter functions use the imbued locale value to perform numeric formatting.
When val is of type bool, long, unsigned long, long long, unsigned long long, double, long double, or const void*, the formatting conversion occurs as if it performed the following code fragment:
bool failed = use_facet<
  num_put<charT, ostreambuf_iterator<charT, traits>>
    >(getloc()).put(*this, *this, fill(), val).failed();
When val is of type short the formatting conversion occurs as if it performed the following code fragment:
ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
bool failed = use_facet<
  num_put<charT, ostreambuf_iterator<charT, traits>>
    >(getloc()).put(*this, *this, fill(),
    baseflags == ios_base::oct || baseflags == ios_base::hex
      ? static_cast<long>(static_cast<unsigned short>(val))
      : static_cast<long>(val)).failed();
When val is of type int the formatting conversion occurs as if it performed the following code fragment:
ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
bool failed = use_facet<
  num_put<charT, ostreambuf_iterator<charT, traits>>
    >(getloc()).put(*this, *this, fill(),
    baseflags == ios_base::oct || baseflags == ios_base::hex
      ? static_cast<long>(static_cast<unsigned int>(val))
      : static_cast<long>(val)).failed();
When val is of type unsigned short or unsigned int the formatting conversion occurs as if it performed the following code fragment:
bool failed = use_facet<
  num_put<charT, ostreambuf_iterator<charT, traits>>
    >(getloc()).put(*this, *this, fill(),
      static_cast<unsigned long>(val)).failed();
When val is of type float the formatting conversion occurs as if it performed the following code fragment:
bool failed = use_facet<
  num_put<charT, ostreambuf_iterator<charT, traits>>
    >(getloc()).put(*this, *this, fill(),
      static_cast<double>(val)).failed();
The first argument provides an object of the ostreambuf_­iterator<> class which is an iterator for class basic_­ostream<>.
It bypasses ostreams and uses streambufs directly.
Class locale relies on these types as its interface to iostreams, since for flexibility it has been abstracted away from direct dependence on ostream.
The second parameter is a reference to the base class subobject of type ios_­base.
It provides formatting specifications such as field width, and a locale from which to obtain other facets.
If failed is true then does setstate(badbit), which may throw an exception, and returns.
Returns: *this.

30.7.5.2.3 basic_­ostream​::​operator<< [ostream.inserters]

basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& (*pf)(basic_ostream<charT, traits>&));
Effects: None.
Does not behave as a formatted output function (as described in [ostream.formatted.reqmts]).
Returns: pf(*this).321
basic_ostream<charT, traits>& operator<<(basic_ios<charT, traits>& (*pf)(basic_ios<charT, traits>&));
Effects: Calls pf(*this).
This inserter does not behave as a formatted output function (as described in [ostream.formatted.reqmts]).
Returns: *this.322
basic_ostream<charT, traits>& operator<<(ios_base& (*pf)(ios_base&));
Effects: Calls pf(*this).
This inserter does not behave as a formatted output function (as described in [ostream.formatted.reqmts]).
Returns: *this.
basic_ostream<charT, traits>& operator<<(basic_streambuf<charT, traits>* sb);
Effects: Behaves as an unformatted output function ([ostream.unformatted]).
After the sentry object is constructed, if sb is null calls setstate(badbit) (which may throw ios_­base​::​failure).
Gets characters from sb and inserts them in *this.
Characters are read from sb and inserted until any of the following occurs:
  • end-of-file occurs on the input sequence;
  • inserting in the output sequence fails (in which case the character to be inserted is not extracted);
  • an exception occurs while getting a character from sb.
If the function inserts no characters, it calls setstate(failbit) (which may throw ios_­base​::​​failure ([iostate.flags])).
If an exception was thrown while extracting a character, the function sets failbit in error state, and if failbit is on in exceptions() the caught exception is rethrown.
Returns: *this.
basic_ostream<charT, traits>& operator<<(nullptr_t);
Effects: Equivalent to:
return *this << s;
where s is an implementation-defined NTCTS ([defns.ntcts]).
See, for example, the function signature endl(basic_­ostream&) ([ostream.manip]).
See, for example, the function signature dec(ios_­base&) ([basefield.manip]).

30.7.5.2.4 Character inserter function templates [ostream.inserters.character]

template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, charT c); template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, char c); // specialization template<class traits> basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, char c); // signed and unsigned template<class traits> basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, signed char c); template<class traits> basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, unsigned char c);
Effects: Behaves as a formatted output function ([ostream.formatted.reqmts]) of out.
Constructs a character sequence seq.
If c has type char and the character type of the stream is not char, then seq consists of out.widen(c); otherwise seq consists of c.
Determines padding for seq as described in [ostream.formatted.reqmts].
Inserts seq into out.
Calls os.width(0).
Returns: out.
template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, const charT* s); template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, const char* s); template<class traits> basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, const char* s); template<class traits> basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, const signed char* s); template<class traits> basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, const unsigned char* s);
Requires: s shall not be a null pointer.
Effects: Behaves like a formatted inserter (as described in [ostream.formatted.reqmts]) of out.
Creates a character sequence seq of n characters starting at s, each widened using out.widen() ([basic.ios.members]), where n is the number that would be computed as if by:
  • traits​::​length(s) for the overload where the first argument is of type basic_­ostream<charT, traits>& and the second is of type const charT*, and also for the overload where the first argument is of type basic_­ostream<char, traits>& and the second is of type const char*,
  • char_­traits<char>​::​length(s) for the overload where the first argument is of type basic_­ostream<charT, traits>& and the second is of type const char*,
  • traits​::​length(reinterpret_­cast<const char*>(s)) for the other two overloads.
Determines padding for seq as described in [ostream.formatted.reqmts].
Inserts seq into out.
Calls width(0).
Returns: out.

30.7.5.3 Unformatted output functions [ostream.unformatted]

Each unformatted output function begins execution by constructing an object of class sentry.
If this object returns true, while converting to a value of type bool, the function endeavors to generate the requested output.
If an exception is thrown during output, then ios​::​badbit is turned on323 in *this's error state.
If (exceptions() & badbit) != 0 then the exception is rethrown.
In any case, the unformatted output function ends by destroying the sentry object, then, if no exception was thrown, returning the value specified for the unformatted output function.
basic_ostream<charT, traits>& put(char_type c);
Effects: Behaves as an unformatted output function (as described above).
After constructing a sentry object, inserts the character c, if possible.324
Otherwise, calls setstate(badbit) (which may throw ios_­base​::​failure ([iostate.flags])).
Returns: *this.
basic_ostream& write(const char_type* s, streamsize n);
Effects: Behaves as an unformatted output function (as described above).
After constructing a sentry object, obtains characters to insert from successive locations of an array whose first element is designated by s.325
Characters are inserted until either of the following occurs:
  • n characters are inserted;
  • inserting in the output sequence fails (in which case the function calls setstate(badbit), which may throw ios_­base​::​failure ([iostate.flags])).
Returns: *this.
basic_ostream& flush();
Effects: Behaves as an unformatted output function (as described above).
If rdbuf() is not a null pointer, constructs a sentry object.
If this object returns true when converted to a value of type bool the function calls rdbuf()->pubsync().
If that function returns -1 calls setstate(badbit) (which may throw ios_­base​::​failure ([iostate.flags])).
Otherwise, if the sentry object returns false, does nothing.
Returns: *this.
without causing an ios​::​failure to be thrown.
Note that this function is not overloaded on types signed char and unsigned char.
Note that this function is not overloaded on types signed char and unsigned char.

30.7.5.4 Standard basic_­ostream manipulators [ostream.manip]

template <class charT, class traits> basic_ostream<charT, traits>& endl(basic_ostream<charT, traits>& os);
Effects: Calls os.put(os.widen('\n')), then os.flush().
Returns: os.
template <class charT, class traits> basic_ostream<charT, traits>& ends(basic_ostream<charT, traits>& os);
Effects: Inserts a null character into the output sequence: calls os.put(charT()).
Returns: os.
template <class charT, class traits> basic_ostream<charT, traits>& flush(basic_ostream<charT, traits>& os);
Effects: Calls os.flush().
Returns: os.

30.7.5.5 Rvalue stream insertion [ostream.rvalue]

template <class charT, class traits, class T> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&& os, const T& x);
Effects: As if by: os << x;
Returns: os.
Remarks: This function shall not participate in overload resolution unless the expression os << x is well-formed.

30.7.6 Standard manipulators [std.manip]

The header <iomanip> defines several functions that support extractors and inserters that alter information maintained by class ios_­base and its derived classes.
unspecified resetiosflags(ios_base::fmtflags mask);
Returns: An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> then the expression out << resetiosflags(mask) behaves as if it called f(out, mask), or if in is an object of type basic_­istream<charT, traits> then the expression in >> resetiosflags(​mask) behaves as if it called f(in, mask), where the function f is defined as:326
void f(ios_base& str, ios_base::fmtflags mask) {
  // reset specified flags
  str.setf(ios_base::fmtflags(0), mask);
}
The expression out << resetiosflags(mask) shall have type basic_­ostream<charT, traits>& and value out.
The expression in >> resetiosflags(mask) shall have type basic_­istream<charT, traits>& and value in.
unspecified setiosflags(ios_base::fmtflags mask);
Returns: An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> then the expression out << setiosflags(mask) behaves as if it called f(out, mask), or if in is an object of type basic_­istream<charT, traits> then the expression in >> setiosflags(mask) behaves as if it called f(in, mask), where the function f is defined as:
void f(ios_base& str, ios_base::fmtflags mask) {
  // set specified flags
  str.setf(mask);
}
The expression out << setiosflags(mask) shall have type basic_­ostream<charT, traits>& and value out.
The expression in >> setiosflags(mask) shall have type basic_­istream<charT,
traits>&
and value in.
unspecified setbase(int base);
Returns: An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> then the expression out << setbase(base) behaves as if it called f(out, base), or if in is an object of type basic_­istream<charT, traits> then the expression in >> setbase(base) behaves as if it called f(in, base), where the function f is defined as:
void f(ios_base& str, int base) {
  // set basefield
  str.setf(base ==  8 ? ios_base::oct :
      base == 10 ? ios_base::dec :
      base == 16 ? ios_base::hex :
      ios_base::fmtflags(0), ios_base::basefield);
}
The expression out << setbase(base) shall have type basic_­ostream<charT, traits>& and value out.
The expression in >> setbase(base) shall have type basic_­istream<charT, traits>& and value in.
unspecified setfill(char_type c);
Returns: An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> and c has type charT then the expression out << setfill(c) behaves as if it called f(out, c), where the function f is defined as:
template<class charT, class traits>
void f(basic_ios<charT, traits>& str, charT c) {
  // set fill character
  str.fill(c);
}
The expression out << setfill(c) shall have type basic_­ostream<charT, traits>& and value out.
unspecified setprecision(int n);
Returns: An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> then the expression out << setprecision(n) behaves as if it called f(out, n), or if in is an object of type basic_­istream<charT, traits> then the expression in >> setprecision(n) behaves as if it called f(in, n), where the function f is defined as:
void f(ios_base& str, int n) {
  // set precision
  str.precision(n);
}
The expression out << setprecision(n) shall have type basic_­ostream<charT, traits>& and value out.
The expression in >> setprecision(n) shall have type basic_­istream<charT, traits>& and value in.
unspecified setw(int n);
Returns: An object of unspecified type such that if out is an instance of basic_­ostream<charT, traits> then the expression out << setw(n) behaves as if it called f(out, n), or if in is an object of type basic_­istream<charT, traits> then the expression in >> setw(n) behaves as if it called f(in, n), where the function f is defined as:
void f(ios_base& str, int n) {
  // set width
  str.width(n);
}
The expression out << setw(n) shall have type basic_­ostream<charT, traits>& and value out.
The expression in >> setw(n) shall have type basic_­istream<charT, traits>& and value in.
The expression cin >> resetiosflags(ios_­base​::​skipws) clears ios_­base​::​skipws in the format flags stored in the basic_­istream<charT, traits> object cin (the same as cin >> noskipws), and the expression cout << resetiosflags(ios_­base​::​showbase) clears ios_­base​::​showbase in the format flags stored in the basic_­ostream<charT, traits> object cout (the same as cout << noshowbase).

30.7.7 Extended manipulators [ext.manip]

The header <iomanip> defines several functions that support extractors and inserters that allow for the parsing and formatting of sequences and values for money and time.
template <class moneyT> unspecified get_money(moneyT& mon, bool intl = false);
Requires: The type moneyT shall be either long double or a specialization of the basic_­string template (Clause [strings]).
Effects: The expression in >> get_­money(mon, intl) described below behaves as a formatted input function ([istream.formatted.reqmts]).
Returns: An object of unspecified type such that if in is an object of type basic_­istream<charT, traits> then the expression in >> get_­money(mon, intl) behaves as if it called f(in, mon, intl), where the function f is defined as:
template <class charT, class traits, class moneyT>
void f(basic_ios<charT, traits>& str, moneyT& mon, bool intl) {
  using Iter     = istreambuf_iterator<charT, traits>;
  using MoneyGet = money_get<charT, Iter>;

  ios_base::iostate err = ios_base::goodbit;
  const MoneyGet& mg = use_facet<MoneyGet>(str.getloc());

  mg.get(Iter(str.rdbuf()), Iter(), intl, str, err, mon);

  if (ios_base::goodbit != err)
    str.setstate(err);
}
The expression in >> get_­money(mon, intl) shall have type basic_­istream<charT, traits>& and value in.
template <class moneyT> unspecified put_money(const moneyT& mon, bool intl = false);
Requires: The type moneyT shall be either long double or a specialization of the basic_­string template (Clause [strings]).
Returns: An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> then the expression out << put_­money(mon, intl) behaves as a formatted output function ([ostream.formatted.reqmts]) that calls f(out, mon, intl), where the function f is defined as:
template <class charT, class traits, class moneyT>
void f(basic_ios<charT, traits>& str, const moneyT& mon, bool intl) {
  using Iter     = ostreambuf_iterator<charT, traits>;
  using MoneyPut = money_put<charT, Iter>;

  const MoneyPut& mp = use_facet<MoneyPut>(str.getloc());
  const Iter end = mp.put(Iter(str.rdbuf()), intl, str, str.fill(), mon);

  if (end.failed())
    str.setstate(ios::badbit);
}
The expression out << put_­money(mon, intl) shall have type basic_­ostream<charT, traits>& and value out.
template <class charT> unspecified get_time(struct tm* tmb, const charT* fmt);
Requires: The argument tmb shall be a valid pointer to an object of type struct tm.
The argument fmt shall be a valid pointer to an array of objects of type charT with char_­traits<charT>​::​length(fmt) elements.
Returns: An object of unspecified type such that if in is an object of type basic_­istream<charT, traits> then the expression in >> get_­time(tmb, fmt) behaves as if it called f(in, tmb, fmt), where the function f is defined as:
template <class charT, class traits>
void f(basic_ios<charT, traits>& str, struct tm* tmb, const charT* fmt) {
  using Iter    = istreambuf_iterator<charT, traits>;
  using TimeGet = time_get<charT, Iter>;

  ios_base::iostate err = ios_base::goodbit;
  const TimeGet& tg = use_facet<TimeGet>(str.getloc());

  tg.get(Iter(str.rdbuf()), Iter(), str, err, tmb,
    fmt, fmt + traits::length(fmt));

  if (err != ios_base::goodbit)
    str.setstate(err);
}
The expression in >> get_­time(tmb, fmt) shall have type basic_­istream<charT, traits>& and value in.
template <class charT> unspecified put_time(const struct tm* tmb, const charT* fmt);
Requires: The argument tmb shall be a valid pointer to an object of type struct tm, and the argument fmt shall be a valid pointer to an array of objects of type charT with char_­traits<charT>​::​length(​fmt) elements.
Returns: An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> then the expression out << put_­time(tmb, fmt) behaves as if it called f(out, tmb, fmt), where the function f is defined as:
template <class charT, class traits>
void f(basic_ios<charT, traits>& str, const struct tm* tmb, const charT* fmt) {
  using Iter    = ostreambuf_iterator<charT, traits>;
  using TimePut = time_put<charT, Iter>;

  const TimePut& tp = use_facet<TimePut>(str.getloc());
  const Iter end = tp.put(Iter(str.rdbuf()), str, str.fill(), tmb,
    fmt, fmt + traits::length(fmt));

  if (end.failed())
    str.setstate(ios_base::badbit);
}
The expression out << put_­time(tmb, fmt) shall have type basic_­ostream<charT, traits>& and value out.

30.7.8 Quoted manipulators [quoted.manip]

[Note
:
Quoted manipulators provide string insertion and extraction of quoted strings (for example, XML and CSV formats).
Quoted manipulators are useful in ensuring that the content of a string with embedded spaces remains unchanged if inserted and then extracted via stream I/O.
end note
]
template <class charT> unspecified quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\')); template <class charT, class traits, class Allocator> unspecified quoted(const basic_string<charT, traits, Allocator>& s, charT delim = charT('"'), charT escape = charT('\\')); template <class charT, class traits> unspecified quoted(basic_string_view<charT, traits> s, charT delim = charT('"'), charT escape = charT('\\'));
Returns: An object of unspecified type such that if out is an instance of basic_­ostream with member type char_­type the same as charT and with member type traits_­type, which in the second and third forms is the same as traits, then the expression out << quoted(s, delim, escape) behaves as a formatted output function ([ostream.formatted.reqmts]) of out.
This forms a character sequence seq, initially consisting of the following elements:
  • delim.
  • Each character in s.
    If the character to be output is equal to escape or delim, as determined by traits_­type​::​eq, first output escape.
  • delim.
Let x be the number of elements initially in seq.
Then padding is determined for seq as described in [ostream.formatted.reqmts], seq is inserted as if by calling out.rdbuf()->sputn(seq, n), where n is the larger of out.width() and x, and out.width(0) is called.
The expression out << quoted(s, delim, escape) shall have type basic_­ostream<charT, traits>& and value out.
template <class charT, class traits, class Allocator> unspecified quoted(basic_string<charT, traits, Allocator>& s, charT delim = charT('"'), charT escape = charT('\\'));
Returns: An object of unspecified type such that:
  • If in is an instance of basic_­istream with member types char_­type and traits_­type the same as charT and traits, respectively, then the expression in >> quoted(s, delim, escape) behaves as if it extracts the following characters from in using operator>>(basic_­istream<charT, traits>&, charT&) ([istream.extractors]) which may throw ios_­base​::​failure ([ios::failure]):
    • If the first character extracted is equal to delim, as determined by traits_­type​::​eq, then:
      • Turn off the skipws flag.
      • s.clear()
      • Until an unescaped delim character is reached or !in, extract characters from in and append them to s, except that if an escape is reached, ignore it and append the next character to s.
      • Discard the final delim character.
      • Restore the skipws flag to its original value.
    • Otherwise, in >> s.
  • If out is an instance of basic_­ostream with member types char_­type and traits_­type the same as charT and traits, respectively, then the expression out << quoted(s, delim, escape) behaves as specified for the const basic_­string<charT, traits, Allocator>& overload of the quoted function.
The expression in >> quoted(s, delim, escape) shall have type basic_­istream<charT, traits>& and value in.
The expression out << quoted(s, delim, escape) shall have type basic_­ostream​<charT, traits>& and value out.

30.8 String-based streams [string.streams]

30.8.1 Header <sstream> synopsis [sstream.syn]

namespace std {
  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
    class basic_stringbuf;

  using stringbuf  = basic_stringbuf<char>;
  using wstringbuf = basic_stringbuf<wchar_t>;

  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
    class basic_istringstream;

  using istringstream  = basic_istringstream<char>;
  using wistringstream = basic_istringstream<wchar_t>;

  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
    class basic_ostringstream;
  using ostringstream  = basic_ostringstream<char>;
  using wostringstream = basic_ostringstream<wchar_t>;

  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
    class basic_stringstream;
  using stringstream  = basic_stringstream<char>;
  using wstringstream = basic_stringstream<wchar_t>;
}
The header <sstream> defines four class templates and eight types that associate stream buffers with objects of class basic_­string, as described in [string.classes].

30.8.2 Class template basic_­stringbuf [stringbuf]

namespace std {
  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
  class basic_stringbuf : public basic_streambuf<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = typename traits::int_type;
    using pos_type       = typename traits::pos_type;
    using off_type       = typename traits::off_type;
    using traits_type    = traits;
    using allocator_type = Allocator;

    // [stringbuf.cons], constructors
    explicit basic_stringbuf(
      ios_base::openmode which = ios_base::in | ios_base::out);
    explicit basic_stringbuf(
      const basic_string<charT, traits, Allocator>& str,
      ios_base::openmode which = ios_base::in | ios_base::out);
    basic_stringbuf(const basic_stringbuf& rhs) = delete;
    basic_stringbuf(basic_stringbuf&& rhs);

    // [stringbuf.assign], assign and swap
    basic_stringbuf& operator=(const basic_stringbuf& rhs) = delete;
    basic_stringbuf& operator=(basic_stringbuf&& rhs);
    void swap(basic_stringbuf& rhs);

    // [stringbuf.members], get and set
    basic_string<charT, traits, Allocator> str() const;
    void str(const basic_string<charT, traits, Allocator>& s);

  protected:
    // [stringbuf.virtuals], overridden virtual functions
    int_type underflow() override;
    int_type pbackfail(int_type c = traits::eof()) override;
    int_type overflow (int_type c = traits::eof()) override;
    basic_streambuf<charT, traits>* setbuf(charT*, streamsize) override;

    pos_type seekoff(off_type off, ios_base::seekdir way,
                     ios_base::openmode which
                      = ios_base::in | ios_base::out) override;
    pos_type seekpos(pos_type sp,
                     ios_base::openmode which
                      = ios_base::in | ios_base::out) override;

  private:
    ios_base::openmode mode;  // exposition only
  };

  template <class charT, class traits, class Allocator>
    void swap(basic_stringbuf<charT, traits, Allocator>& x,
              basic_stringbuf<charT, traits, Allocator>& y);
}
The class basic_­stringbuf is derived from basic_­streambuf to associate possibly the input sequence and possibly the output sequence with a sequence of arbitrary characters.
The sequence can be initialized from, or made available as, an object of class basic_­string.
For the sake of exposition, the maintained data is presented here as:
  • ios_­base​::​openmode mode, has in set if the input sequence can be read, and out set if the output sequence can be written.

30.8.2.1 basic_­stringbuf constructors [stringbuf.cons]

explicit basic_stringbuf( ios_base::openmode which = ios_base::in | ios_base::out);
Effects: Constructs an object of class basic_­stringbuf, initializing the base class with basic_­streambuf() ([streambuf.cons]), and initializing mode with which.
Postconditions: str() == "".
explicit basic_stringbuf( const basic_string<charT, traits, Allocator>& s, ios_base::openmode which = ios_base::in | ios_base::out);
Effects: Constructs an object of class basic_­stringbuf, initializing the base class with basic_­streambuf() ([streambuf.cons]), and initializing mode with which.
Then calls str(s).
basic_stringbuf(basic_stringbuf&& rhs);
Effects: Move constructs from the rvalue rhs.
It is implementation-defined whether the sequence pointers in *this (eback(), gptr(), egptr(), pbase(), pptr(), epptr()) obtain the values which rhs had.
Whether they do or not, *this and rhs reference separate buffers (if any at all) after the construction.
The openmode, locale and any other state of rhs is also copied.
Postconditions: Let rhs_­p refer to the state of rhs just prior to this construction and let rhs_­a refer to the state of rhs just after this construction.
  • str() == rhs_­p.str()
  • gptr() - eback() == rhs_­p.gptr() - rhs_­p.eback()
  • egptr() - eback() == rhs_­p.egptr() - rhs_­p.eback()
  • pptr() - pbase() == rhs_­p.pptr() - rhs_­p.pbase()
  • epptr() - pbase() == rhs_­p.epptr() - rhs_­p.pbase()
  • if (eback()) eback() != rhs_­a.eback()
  • if (gptr()) gptr() != rhs_­a.gptr()
  • if (egptr()) egptr() != rhs_­a.egptr()
  • if (pbase()) pbase() != rhs_­a.pbase()
  • if (pptr()) pptr() != rhs_­a.pptr()
  • if (epptr()) epptr() != rhs_­a.epptr()

30.8.2.2 Assign and swap [stringbuf.assign]

basic_stringbuf& operator=(basic_stringbuf&& rhs);
Effects: After the move assignment *this has the observable state it would have had if it had been move constructed from rhs (see [stringbuf.cons]).
Returns: *this.
void swap(basic_stringbuf& rhs);
Effects: Exchanges the state of *this and rhs.
template <class charT, class traits, class Allocator> void swap(basic_stringbuf<charT, traits, Allocator>& x, basic_stringbuf<charT, traits, Allocator>& y);
Effects: As if by x.swap(y).

30.8.2.3 Member functions [stringbuf.members]

basic_string<charT, traits, Allocator> str() const;
Returns: A basic_­string object whose content is equal to the basic_­stringbuf underlying character sequence.
If the basic_­stringbuf was created only in input mode, the resultant basic_­string contains the character sequence in the range [eback(), egptr()).
If the basic_­stringbuf was created with which & ios_­base​::​out being nonzero then the resultant basic_­string contains the character sequence in the range [pbase(), high_­mark), where high_­mark represents the position one past the highest initialized character in the buffer.
Characters can be initialized by writing to the stream, by constructing the basic_­stringbuf with a basic_­string, or by calling the str(basic_­string) member function.
In the case of calling the str(basic_­string) member function, all characters initialized prior to the call are now considered uninitialized (except for those characters re-initialized by the new basic_­string).
Otherwise the basic_­stringbuf has been created in neither input nor output mode and a zero length basic_­string is returned.
void str(const basic_string<charT, traits, Allocator>& s);
Effects: Copies the content of s into the basic_­stringbuf underlying character sequence and initializes the input and output sequences according to mode.
Postconditions: If mode & ios_­base​::​out is nonzero, pbase() points to the first underlying character and epptr() >= pbase() + s.size() holds; in addition, if mode & ios_­base​::​ate is nonzero, pptr() == pbase() + s.size() holds, otherwise pptr() == pbase() is true.
If mode & ios_­base​::​in is nonzero, eback() points to the first underlying character, and both gptr() == eback() and egptr() == eback() + s.size() hold.

30.8.2.4 Overridden virtual functions [stringbuf.virtuals]

int_type underflow() override;
Returns: If the input sequence has a read position available, returns traits​::​to_­int_­type(*gptr()).
Otherwise, returns traits​::​eof().
Any character in the underlying buffer which has been initialized is considered to be part of the input sequence.
int_type pbackfail(int_type c = traits::eof()) override;
Effects: Puts back the character designated by c to the input sequence, if possible, in one of three ways:
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns false and if the input sequence has a putback position available, and if traits​::​eq(to_­char_­type(c), gptr()[-1]) returns true, assigns gptr() - 1 to gptr().
    Returns: c.
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns false and if the input sequence has a putback position available, and if mode & ios_­base​::​out is nonzero, assigns c to *--gptr().
    Returns: c.
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns true and if the input sequence has a putback position available, assigns gptr() - 1 to gptr().
    Returns: traits​::​not_­eof(c).
Returns: traits​::​eof() to indicate failure.
Remarks: If the function can succeed in more than one of these ways, it is unspecified which way is chosen.
int_type overflow(int_type c = traits::eof()) override;
Effects: Appends the character designated by c to the output sequence, if possible, in one of two ways:
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns false and if either the output sequence has a write position available or the function makes a write position available (as described below), the function calls sputc(c).
    Signals success by returning c.
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns true, there is no character to append.
    Signals success by returning a value other than traits​::​eof().
Remarks: The function can alter the number of write positions available as a result of any call.
Returns: traits​::​eof() to indicate failure.
The function can make a write position available only if (mode & ios_­base​::​out) != 0.
To make a write position available, the function reallocates (or initially allocates) an array object with a sufficient number of elements to hold the current array object (if any), plus at least one additional write position.
If (mode & ios_­base​::​in) != 0, the function alters the read end pointer egptr() to point just past the new write position.
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;
Effects: Alters the stream position within one of the controlled sequences, if possible, as indicated in Table 110.
Table 110seekoff positioning
Conditions
Result
(which & ios_­base​::​in) == ios_­base​::​in
positions the input sequence
(which & ios_­base​::​out) == ios_­base​::​out
positions the output sequence
(which & (ios_­base​::​in |
ios_­base​::​out)) ==
(ios_­base​::​in) |
ios_­base​::​out))
and way == either
ios_­base​::​beg or
ios_­base​::​end
positions both the input and the output sequences
Otherwise
the positioning operation fails.
For a sequence to be positioned, if its next pointer (either gptr() or pptr()) is a null pointer and the new offset newoff is nonzero, the positioning operation fails.
Otherwise, the function determines newoff as indicated in Table 111.
Table 111newoff values
Condition
newoff Value
way == ios_­base​::​beg
0
way == ios_­base​::​cur
the next pointer minus the beginning pointer (xnext - xbeg).
way == ios_­base​::​end
the high mark pointer minus the beginning pointer (high_­mark - xbeg).
If (newoff + off) < 0, or if newoff + off refers to an uninitialized character ([stringbuf.members]), the positioning operation fails.
Otherwise, the function assigns xbeg + newoff + off to the next pointer xnext.
Returns: pos_­type(newoff), constructed from the resultant offset newoff (of type off_­type), that stores the resultant stream position, if possible.
If the positioning operation fails, or if the constructed object cannot represent the resultant stream position, the return value is pos_­type(off_­type(-1)).
pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out) override;
Effects: Equivalent to seekoff(off_­type(sp), ios_­base​::​beg, which).
Returns: sp to indicate success, or pos_­type(off_­type(-1)) to indicate failure.
basic_streambuf<charT, traits>* setbuf(charT* s, streamsize n);
Effects: implementation-defined, except that setbuf(0, 0) has no effect.
Returns: this.

30.8.3 Class template basic_­istringstream [istringstream]

namespace std {
  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
  class basic_istringstream : public basic_istream<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = typename traits::int_type;
    using pos_type       = typename traits::pos_type;
    using off_type       = typename traits::off_type;
    using traits_type    = traits;
    using allocator_type = Allocator;

    // [istringstream.cons], constructors
    explicit basic_istringstream(
      ios_base::openmode which = ios_base::in);
    explicit basic_istringstream(
      const basic_string<charT, traits, Allocator>& str,
      ios_base::openmode which = ios_base::in);
    basic_istringstream(const basic_istringstream& rhs) = delete;
    basic_istringstream(basic_istringstream&& rhs);

    // [istringstream.assign], assign and swap
    basic_istringstream& operator=(const basic_istringstream& rhs) = delete;
    basic_istringstream& operator=(basic_istringstream&& rhs);
    void swap(basic_istringstream& rhs);

    // [istringstream.members], members
    basic_stringbuf<charT, traits, Allocator>* rdbuf() const;

    basic_string<charT, traits, Allocator> str() const;
    void str(const basic_string<charT, traits, Allocator>& s);
  private:
    basic_stringbuf<charT, traits, Allocator> sb; // exposition only
  };

  template <class charT, class traits, class Allocator>
    void swap(basic_istringstream<charT, traits, Allocator>& x,
              basic_istringstream<charT, traits, Allocator>& y);
}
The class basic_­istringstream<charT, traits, Allocator> supports reading objects of class basic_­string<​charT, traits, Allocator>.
It uses a basic_­stringbuf<charT, traits, Allocator> object to control the associated storage.
For the sake of exposition, the maintained data is presented here as:
  • sb, the stringbuf object.

30.8.3.1 basic_­istringstream constructors [istringstream.cons]

explicit basic_istringstream(ios_base::openmode which = ios_base::in);
Effects: Constructs an object of class basic_­istringstream<charT, traits>, initializing the base class with basic_­istream(&sb) and initializing sb with basic_­stringbuf<charT, traits, Allocator>(which | ios_­base​::​in)) ([stringbuf.cons]).
explicit basic_istringstream( const basic_string<charT, traits, Allocator>& str, ios_base::openmode which = ios_base::in);
Effects: Constructs an object of class basic_­istringstream<charT, traits>, initializing the base class with basic_­istream(&sb) and initializing sb with basic_­stringbuf<charT, traits, Allocator>(str, which | ios_­base​::​in)) ([stringbuf.cons]).
basic_istringstream(basic_istringstream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by move constructing the base class, and the contained basic_­stringbuf.
Next basic_­istream<charT, traits>​::​set_­rdbuf(&sb) is called to install the contained basic_­stringbuf.

30.8.3.2 Assign and swap [istringstream.assign]

basic_istringstream& operator=(basic_istringstream&& rhs);
Effects: Move assigns the base and members of *this from the base and corresponding members of rhs.
Returns: *this.
void swap(basic_istringstream& rhs);
Effects: Exchanges the state of *this and rhs by calling basic_­istream<charT, traits>​::​swap(rhs) and sb.swap(rhs.sb).
template <class charT, class traits, class Allocator> void swap(basic_istringstream<charT, traits, Allocator>& x, basic_istringstream<charT, traits, Allocator>& y);
Effects: As if by x.swap(y).

30.8.3.3 Member functions [istringstream.members]

basic_stringbuf<charT, traits, Allocator>* rdbuf() const;
Returns: const_­cast<basic_­stringbuf<charT, traits, Allocator>*>(&sb).
basic_string<charT, traits, Allocator> str() const;
Returns: rdbuf()->str().
void str(const basic_string<charT, traits, Allocator>& s);
Effects: Calls rdbuf()->str(s).

30.8.4 Class template basic_­ostringstream [ostringstream]

namespace std {
  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
  class basic_ostringstream : public basic_ostream<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = typename traits::int_type;
    using pos_type       = typename traits::pos_type;
    using off_type       = typename traits::off_type;
    using traits_type    = traits;
    using allocator_type = Allocator;

    // [ostringstream.cons], constructors
    explicit basic_ostringstream(
      ios_base::openmode which = ios_base::out);
    explicit basic_ostringstream(
      const basic_string<charT, traits, Allocator>& str,
      ios_base::openmode which = ios_base::out);
    basic_ostringstream(const basic_ostringstream& rhs) = delete;
    basic_ostringstream(basic_ostringstream&& rhs);

    // [ostringstream.assign], assign and swap
    basic_ostringstream& operator=(const basic_ostringstream& rhs) = delete;
    basic_ostringstream& operator=(basic_ostringstream&& rhs);
    void swap(basic_ostringstream& rhs);

    // [ostringstream.members], members
    basic_stringbuf<charT, traits, Allocator>* rdbuf() const;

    basic_string<charT, traits, Allocator> str() const;
    void str(const basic_string<charT, traits, Allocator>& s);
   private:
    basic_stringbuf<charT, traits, Allocator> sb; // exposition only
  };

  template <class charT, class traits, class Allocator>
    void swap(basic_ostringstream<charT, traits, Allocator>& x,
              basic_ostringstream<charT, traits, Allocator>& y);
}
The class basic_­ostringstream<charT, traits, Allocator> supports writing objects of class basic_­string<​charT, traits, Allocator>.
It uses a basic_­stringbuf object to control the associated storage.
For the sake of exposition, the maintained data is presented here as:
  • sb, the stringbuf object.

30.8.4.1 basic_­ostringstream constructors [ostringstream.cons]

explicit basic_ostringstream( ios_base::openmode which = ios_base::out);
Effects: Constructs an object of class basic_­ostringstream, initializing the base class with basic_­ostream(​&sb) and initializing sb with basic_­stringbuf<charT, traits, Allocator>(which | ​ios_­base​::​out)) ([stringbuf.cons]).
explicit basic_ostringstream( const basic_string<charT, traits, Allocator>& str, ios_base::openmode which = ios_base::out);
Effects: Constructs an object of class basic_­ostringstream<charT, traits>, initializing the base class with basic_­ostream(&sb) and initializing sb with basic_­stringbuf<charT, traits, Allocator>(str, which | ios_­base​::​out)) ([stringbuf.cons]).
basic_ostringstream(basic_ostringstream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by move constructing the base class, and the contained basic_­stringbuf.
Next basic_­ostream<charT, traits>​::​set_­rdbuf(&sb) is called to install the contained basic_­stringbuf.

30.8.4.2 Assign and swap [ostringstream.assign]

basic_ostringstream& operator=(basic_ostringstream&& rhs);
Effects: Move assigns the base and members of *this from the base and corresponding members of rhs.
Returns: *this.
void swap(basic_ostringstream& rhs);
Effects: Exchanges the state of *this and rhs by calling basic_­ostream<charT, traits>​::​swap(rhs) and sb.swap(rhs.sb).
template <class charT, class traits, class Allocator> void swap(basic_ostringstream<charT, traits, Allocator>& x, basic_ostringstream<charT, traits, Allocator>& y);
Effects: As if by x.swap(y).

30.8.4.3 Member functions [ostringstream.members]

basic_stringbuf<charT, traits, Allocator>* rdbuf() const;
Returns: const_­cast<basic_­stringbuf<charT, traits, Allocator>*>(&sb).
basic_string<charT, traits, Allocator> str() const;
Returns: rdbuf()->str().
void str(const basic_string<charT, traits, Allocator>& s);
Effects: Calls rdbuf()->str(s).

30.8.5 Class template basic_­stringstream [stringstream]

namespace std {
  template <class charT, class traits = char_traits<charT>,
            class Allocator = allocator<charT>>
  class basic_stringstream : public basic_iostream<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = typename traits::int_type;
    using pos_type       = typename traits::pos_type;
    using off_type       = typename traits::off_type;
    using traits_type    = traits;
    using allocator_type = Allocator;

    // [stringstream.cons], constructors
    explicit basic_stringstream(
      ios_base::openmode which = ios_base::out | ios_base::in);
    explicit basic_stringstream(
      const basic_string<charT, traits, Allocator>& str,
      ios_base::openmode which = ios_base::out | ios_base::in);
    basic_stringstream(const basic_stringstream& rhs) = delete;
    basic_stringstream(basic_stringstream&& rhs);

    // [stringstream.assign], assign and swap
    basic_stringstream& operator=(const basic_stringstream& rhs) = delete;
    basic_stringstream& operator=(basic_stringstream&& rhs);
    void swap(basic_stringstream& rhs);

    // [stringstream.members], members
    basic_stringbuf<charT, traits, Allocator>* rdbuf() const;
    basic_string<charT, traits, Allocator> str() const;
    void str(const basic_string<charT, traits, Allocator>& str);

  private:
    basic_stringbuf<charT, traits> sb;  // exposition only
  };

  template <class charT, class traits, class Allocator>
    void swap(basic_stringstream<charT, traits, Allocator>& x,
              basic_stringstream<charT, traits, Allocator>& y);
}
The class template basic_­stringstream<charT, traits> supports reading and writing from objects of class basic_­string<charT, traits, Allocator>.
It uses a basic_­stringbuf<charT, traits, Allocator> object to control the associated sequence.
For the sake of exposition, the maintained data is presented here as
  • sb, the stringbuf object.

30.8.5.1 basic_­stringstream constructors [stringstream.cons]

explicit basic_stringstream( ios_base::openmode which = ios_base::out | ios_base::in);
Effects: Constructs an object of class basic_­stringstream<charT, traits>, initializing the base class with basic_­iostream(&sb) and initializing sb with basic_­stringbuf<charT, traits, Allocator>(which).
explicit basic_stringstream( const basic_string<charT, traits, Allocator>& str, ios_base::openmode which = ios_base::out | ios_base::in);
Effects: Constructs an object of class basic_­stringstream<charT, traits>, initializing the base class with basic_­iostream(&sb) and initializing sb with basic_­stringbuf<charT, traits, Allocator>(str, which).
basic_stringstream(basic_stringstream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by move constructing the base class, and the contained basic_­stringbuf.
Next basic_­istream<charT, traits>​::​set_­rdbuf(&sb) is called to install the contained basic_­stringbuf.

30.8.5.2 Assign and swap [stringstream.assign]

basic_stringstream& operator=(basic_stringstream&& rhs);
Effects: Move assigns the base and members of *this from the base and corresponding members of rhs.
Returns: *this.
void swap(basic_stringstream& rhs);
Effects: Exchanges the state of *this and rhs by calling basic_­iostream<charT,traits>​::​swap(rhs) and sb.swap(rhs.sb).
template <class charT, class traits, class Allocator> void swap(basic_stringstream<charT, traits, Allocator>& x, basic_stringstream<charT, traits, Allocator>& y);
Effects: As if by x.swap(y).

30.8.5.3 Member functions [stringstream.members]

basic_stringbuf<charT, traits, Allocator>* rdbuf() const;
Returns: const_­cast<basic_­stringbuf<charT, traits, Allocator>*>(&sb)
basic_string<charT, traits, Allocator> str() const;
Returns: rdbuf()->str().
void str(const basic_string<charT, traits, Allocator>& str);
Effects: Calls rdbuf()->str(str).

30.9 File-based streams [file.streams]

30.9.1 Header <fstream> synopsis [fstream.syn]

namespace std {
  template <class charT, class traits = char_traits<charT>>
    class basic_filebuf;
  using filebuf  = basic_filebuf<char>;
  using wfilebuf = basic_filebuf<wchar_t>;

  template <class charT, class traits = char_traits<charT>>
    class basic_ifstream;
  using ifstream  = basic_ifstream<char>;
  using wifstream = basic_ifstream<wchar_t>;

  template <class charT, class traits = char_traits<charT>>
    class basic_ofstream;
  using ofstream  = basic_ofstream<char>;
  using wofstream = basic_ofstream<wchar_t>;

  template <class charT, class traits = char_traits<charT>>
    class basic_fstream;
  using fstream  = basic_fstream<char>;
  using wfstream = basic_fstream<wchar_t>;
}
The header <fstream> defines four class templates and eight types that associate stream buffers with files and assist reading and writing files.
[Note
:
The class template basic_­filebuf treats a file as a source or sink of bytes.
In an environment that uses a large character set, the file typically holds multibyte character sequences and the basic_­filebuf object converts those multibyte sequences into wide character sequences.
end note
]
In this subclause, member functions taking arguments of const filesystem​::​path​::​value_­type* are only be provided on systems where filesystem​::​path​::​value_­type ([fs.class.path]) is not char.
[Note
:
These functions enable class path support for systems with a wide native path character type, such as wchar_­t.
end note
]

30.9.2 Class template basic_­filebuf [filebuf]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_filebuf : public basic_streambuf<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [filebuf.cons], constructors/destructor
    basic_filebuf();
    basic_filebuf(const basic_filebuf& rhs) = delete;
    basic_filebuf(basic_filebuf&& rhs);
    virtual ~basic_filebuf();

    // [filebuf.assign], assign and swap
    basic_filebuf& operator=(const basic_filebuf& rhs) = delete;
    basic_filebuf& operator=(basic_filebuf&& rhs);
    void swap(basic_filebuf& rhs);

    // [filebuf.members], members
    bool is_open() const;
    basic_filebuf* open(const char* s, ios_base::openmode mode);
    basic_filebuf* open(const filesystem::path::value_type* s,
                        ios_base::openmode mode);  // wide systems only; see [fstream.syn]
    basic_filebuf* open(const string& s,
                        ios_base::openmode mode);
    basic_filebuf* open(const filesystem::path& s,
                        ios_base::openmode mode);
    basic_filebuf* close();

  protected:
    // [filebuf.virtuals], overridden virtual functions
    streamsize showmanyc() override;
    int_type underflow() override;
    int_type uflow() override;
    int_type pbackfail(int_type c = traits::eof()) override;
    int_type overflow (int_type c = traits::eof()) override;

    basic_streambuf<charT, traits>* setbuf(char_type* s,
                                           streamsize n) override;
    pos_type seekoff(off_type off, ios_base::seekdir way,
                     ios_base::openmode which
                      = ios_base::in | ios_base::out) override;
    pos_type seekpos(pos_type sp,
                     ios_base::openmode which
                      = ios_base::in | ios_base::out) override;
    int      sync() override;
    void     imbue(const locale& loc) override;
  };

  template <class charT, class traits>
    void swap(basic_filebuf<charT, traits>& x,
              basic_filebuf<charT, traits>& y);
}
The class basic_­filebuf<charT, traits> associates both the input sequence and the output sequence with a file.
The restrictions on reading and writing a sequence controlled by an object of class basic_­filebuf<charT, traits> are the same as for reading and writing with the C standard library FILEs.
In particular:
  • If the file is not open for reading the input sequence cannot be read.
  • If the file is not open for writing the output sequence cannot be written.
  • A joint file position is maintained for both the input sequence and the output sequence.
An instance of basic_­filebuf behaves as described in [filebuf] provided traits​::​pos_­type is fpos<traits​::​​state_­type>.
Otherwise the behavior is undefined.
In order to support file I/O and multibyte/wide character conversion, conversions are performed using members of a facet, referred to as a_­codecvt in following sections, obtained as if by
const codecvt<charT, char, typename traits::state_type>& a_codecvt =
  use_facet<codecvt<charT, char, typename traits::state_type>>(getloc());

30.9.2.1 basic_­filebuf constructors [filebuf.cons]

basic_filebuf();
Effects: Constructs an object of class basic_­filebuf<charT, traits>, initializing the base class with basic_­streambuf<charT, traits>() ([streambuf.cons]).
Postconditions: is_­open() == false.
basic_filebuf(basic_filebuf&& rhs);
Effects: Move constructs from the rvalue rhs.
It is implementation-defined whether the sequence pointers in *this (eback(), gptr(), egptr(), pbase(), pptr(), epptr()) obtain the values which rhs had.
Whether they do or not, *this and rhs reference separate buffers (if any at all) after the construction.
Additionally *this references the file which rhs did before the construction, and rhs references no file after the construction.
The openmode, locale and any other state of rhs is also copied.
Postconditions: Let rhs_­p refer to the state of rhs just prior to this construction and let rhs_­a refer to the state of rhs just after this construction.
  • is_­open() == rhs_­p.is_­open()
  • rhs_­a.is_­open() == false
  • gptr() - eback() == rhs_­p.gptr() - rhs_­p.eback()
  • egptr() - eback() == rhs_­p.egptr() - rhs_­p.eback()
  • pptr() - pbase() == rhs_­p.pptr() - rhs_­p.pbase()
  • epptr() - pbase() == rhs_­p.epptr() - rhs_­p.pbase()
  • if (eback()) eback() != rhs_­a.eback()
  • if (gptr()) gptr() != rhs_­a.gptr()
  • if (egptr()) egptr() != rhs_­a.egptr()
  • if (pbase()) pbase() != rhs_­a.pbase()
  • if (pptr()) pptr() != rhs_­a.pptr()
  • if (epptr()) epptr() != rhs_­a.epptr()
virtual ~basic_filebuf();
Effects: Destroys an object of class basic_­filebuf<charT, traits>.
Calls close().
If an exception occurs during the destruction of the object, including the call to close(), the exception is caught but not rethrown (see [res.on.exception.handling]).

30.9.2.2 Assign and swap [filebuf.assign]

basic_filebuf& operator=(basic_filebuf&& rhs);
Effects: Calls close() then move assigns from rhs.
After the move assignment *this has the observable state it would have had if it had been move constructed from rhs (see [filebuf.cons]).
Returns: *this.
void swap(basic_filebuf& rhs);
Effects: Exchanges the state of *this and rhs.
template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
Effects: As if by x.swap(y).

30.9.2.3 Member functions [filebuf.members]

bool is_open() const;
Returns: true if a previous call to open succeeded (returned a non-null value) and there has been no intervening call to close.
basic_filebuf* open(const char* s, ios_base::openmode mode); basic_filebuf* open(const filesystem::path::value_type* s, ios_base::openmode mode); // wide systems only; see [fstream.syn]
Effects: If is_­open() != false, returns a null pointer.
Otherwise, initializes the filebuf as required.
It then opens a file, if possible, whose name is the ntbs s (as if by calling fopen(s, modstr)).
The ntbs modstr is determined from mode & ~ios_­base​::​ate as indicated in Table 112.
If mode is not some combination of flags shown in the table then the open fails.
Table 112 — File open modes
ios_­base flag combination
stdio equivalent
binary
in
out
trunc
app
+
"w"
+
+
"a"
+
"a"
+
+
"w"
+
"r"
+
+
"r+"
+
+
+
"w+"
+
+
+
"a+"
+
+
"a+"
+
+
"wb"
+
+
+
"ab"
+
+
"ab"
+
+
+
"wb"
+
+
"rb"
+
+
+
"r+b"
+
+
+
+
"w+b"
+
+
+
+
"a+b"
+
+
+
"a+b"
If the open operation succeeds and (mode & ios_­base​::​ate) != 0, positions the file to the end (as if by calling fseek(file, 0, SEEK_­END)).327
If the repositioning operation fails, calls close() and returns a null pointer to indicate failure.
Returns: this if successful, a null pointer otherwise.
basic_filebuf* open(const string& s, ios_base::openmode mode); basic_filebuf* open(const filesystem::path& s, ios_base::openmode mode);
Returns: open(s.c_­str(), mode);
basic_filebuf* close();
Effects: If is_­open() == false, returns a null pointer.
If a put area exists, calls overflow(traits​::​​eof()) to flush characters.
If the last virtual member function called on *this (between underflow, overflow, seekoff, and seekpos) was overflow then calls a_­codecvt.unshift (possibly several times) to determine a termination sequence, inserts those characters and calls overflow(traits​::​​eof()) again.
Finally, regardless of whether any of the preceding calls fails or throws an exception, the function closes the file (as if by calling fclose(file)).
If any of the calls made by the function, including fclose, fails, close fails by returning a null pointer.
If one of these calls throws an exception, the exception is caught and rethrown after closing the file.
Returns: this on success, a null pointer otherwise.
Postconditions: is_­open() == false.
The macro SEEK_­END is defined, and the function signatures fopen(const char*, const char*) and fseek(FILE*, long, int) are declared, in <cstdio> ([cstdio.syn]).

30.9.2.4 Overridden virtual functions [filebuf.virtuals]

streamsize showmanyc() override;
Effects: Behaves the same as basic_­streambuf​::​showmanyc() ([streambuf.virtuals]).
Remarks: An implementation might well provide an overriding definition for this function signature if it can determine that more characters can be read from the input sequence.
int_type underflow() override;
Effects: Behaves according to the description of basic_­streambuf<charT, traits>​::​underflow(), with the specialization that a sequence of characters is read from the input sequence as if by reading from the associated file into an internal buffer (extern_­buf) and then as if by doing:
char   extern_buf[XSIZE];
char*  extern_end;
charT  intern_buf[ISIZE];
charT* intern_end;
codecvt_base::result r =
  a_codecvt.in(state, extern_buf, extern_buf+XSIZE, extern_end,
               intern_buf, intern_buf+ISIZE, intern_end);
This shall be done in such a way that the class can recover the position (fpos_­t) corresponding to each character between intern_­buf and intern_­end.
If the value of r indicates that a_­codecvt.in() ran out of space in intern_­buf, retry with a larger intern_­buf.
int_type uflow() override;
Effects: Behaves according to the description of basic_­streambuf<charT, traits>​::​uflow(), with the specialization that a sequence of characters is read from the input with the same method as used by underflow.
int_type pbackfail(int_type c = traits::eof()) override;
Effects: Puts back the character designated by c to the input sequence, if possible, in one of three ways:
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns false and if the function makes a putback position available and if traits​::​eq(to_­char_­type(c), gptr()[-1]) returns true, decrements the next pointer for the input sequence, gptr().
    Returns: c.
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns false and if the function makes a putback position available and if the function is permitted to assign to the putback position, decrements the next pointer for the input sequence, and stores c there.
    Returns: c.
  • If traits​::​eq_­int_­type(c, traits​::​eof()) returns true, and if either the input sequence has a putback position available or the function makes a putback position available, decrements the next pointer for the input sequence, gptr().
    Returns: traits​::​not_­eof(c).
Returns: traits​::​eof() to indicate failure.
Remarks: If is_­open() == false, the function always fails.
The function does not put back a character directly to the input sequence.
If the function can succeed in more than one of these ways, it is unspecified which way is chosen.
The function can alter the number of putback positions available as a result of any call.
int_type overflow(int_type c = traits::eof()) override;
Effects: Behaves according to the description of basic_­streambuf<charT, traits>​::​overflow(c), except that the behavior of “consuming characters” is performed by first converting as if by:
charT* b = pbase();
charT* p = pptr();
charT* end;
char   xbuf[XSIZE];
char*  xbuf_end;
codecvt_base::result r =
  a_codecvt.out(state, b, p, end, xbuf, xbuf+XSIZE, xbuf_end);
and then
  • If r == codecvt_­base​::​error then fail.
  • If r == codecvt_­base​::​noconv then output characters from b up to (and not including) p.
  • If r == codecvt_­base​::​partial then output to the file characters from xbuf up to xbuf_­end, and repeat using characters from end to p.
    If output fails, fail (without repeating).
  • Otherwise output from xbuf to xbuf_­end, and fail if output fails.
    At this point if b != p and b == end (xbuf isn't large enough) then increase XSIZE and repeat from the beginning.
Returns: traits​::​not_­eof(c) to indicate success, and traits​::​eof() to indicate failure.
If is_­open() == false, the function always fails.
basic_streambuf* setbuf(char_type* s, streamsize n) override;
Effects: If setbuf(0, 0) is called on a stream before any I/O has occurred on that stream, the stream becomes unbuffered.
Otherwise the results are implementation-defined.
“Unbuffered” means that pbase() and pptr() always return null and output to the file should appear as soon as possible.
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;
Effects: Let width denote a_­codecvt.encoding().
If is_­open() == false, or off != 0 && width <= 0, then the positioning operation fails.
Otherwise, if way != basic_­ios​::​cur or off != 0, and if the last operation was output, then update the output sequence and write any unshift sequence.
Next, seek to the new position: if width > 0, call fseek(file, width * off, whence), otherwise call fseek(file, 0, whence).
Remarks: “The last operation was output” means either the last virtual operation was overflow or the put buffer is non-empty.
“Write any unshift sequence” means, if width if less than zero then call a_­codecvt.unshift(state, xbuf, xbuf+XSIZE, xbuf_­end) and output the resulting unshift sequence.
The function determines one of three values for the argument whence, of type int, as indicated in Table 113.
Table 113seekoff effects
way Value
stdio Equivalent
basic_­ios​::​beg
SEEK_­SET
basic_­ios​::​cur
SEEK_­CUR
basic_­ios​::​end
SEEK_­END
Returns: A newly constructed pos_­type object that stores the resultant stream position, if possible.
If the positioning operation fails, or if the object cannot represent the resultant stream position, returns pos_­type(off_­type(-1)).
pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out) override;
Alters the file position, if possible, to correspond to the position stored in sp (as described below).
Altering the file position performs as follows:
  1. 1.
    if (om & ios_­base​::​out) != 0, then update the output sequence and write any unshift sequence;
  2. 2.
    set the file position to sp as if by a call to fsetpos;
  3. 3.
    if (om & ios_­base​::​in) != 0, then update the input sequence;
where om is the open mode passed to the last call to open().
The operation fails if is_­open() returns false.
If sp is an invalid stream position, or if the function positions neither sequence, the positioning operation fails.
If sp has not been obtained by a previous successful call to one of the positioning functions (seekoff or seekpos) on the same file the effects are undefined.
Returns: sp on success.
Otherwise returns pos_­type(off_­type(-1)).
int sync() override;
Effects: If a put area exists, calls filebuf​::​overflow to write the characters to the file, then flushes the file as if by calling fflush(file).
If a get area exists, the effect is implementation-defined.
void imbue(const locale& loc) override;
Requires: If the file is not positioned at its beginning and the encoding of the current locale as determined by a_­codecvt.encoding() is state-dependent ([locale.codecvt.virtuals]) then that facet is the same as the corresponding facet of loc.
Effects: Causes characters inserted or extracted after this call to be converted according to loc until another call of imbue.
Remarks: This may require reconversion of previously converted characters.
This in turn may require the implementation to be able to reconstruct the original contents of the file.

30.9.3 Class template basic_­ifstream [ifstream]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_ifstream : public basic_istream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [ifstream.cons], constructors
    basic_ifstream();
    explicit basic_ifstream(const char* s,
                            ios_base::openmode mode = ios_base::in);
    explicit basic_ifstream(const filesystem::path::value_type* s,
                            ios_base::openmode mode = ios_base::in);  // wide systems only; see [fstream.syn]
    explicit basic_ifstream(const string& s,
                            ios_base::openmode mode = ios_base::in);
    explicit basic_ifstream(const filesystem::path& s,
                            ios_base::openmode mode = ios_base::in);
    basic_ifstream(const basic_ifstream& rhs) = delete;
    basic_ifstream(basic_ifstream&& rhs);

    // [ifstream.assign], assign and swap
    basic_ifstream& operator=(const basic_ifstream& rhs) = delete;
    basic_ifstream& operator=(basic_ifstream&& rhs);
    void swap(basic_ifstream& rhs);

    // [ifstream.members], members
    basic_filebuf<charT, traits>* rdbuf() const;

    bool is_open() const;
    void open(const char* s, ios_base::openmode mode = ios_base::in);
    void open(const filesystem::path::value_type* s,
              ios_base::openmode mode = ios_base::in);  // wide systems only; see [fstream.syn]
    void open(const string& s, ios_base::openmode mode = ios_base::in);
    void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in);
    void close();
  private:
    basic_filebuf<charT, traits> sb; // exposition only
  };

  template <class charT, class traits>
    void swap(basic_ifstream<charT, traits>& x,
              basic_ifstream<charT, traits>& y);
}
The class basic_­ifstream<charT, traits> supports reading from named files.
It uses a basic_­filebuf<​charT, traits> object to control the associated sequence.
For the sake of exposition, the maintained data is presented here as:

30.9.3.1 basic_­ifstream constructors [ifstream.cons]

basic_ifstream();
Effects: Constructs an object of class basic_­ifstream<charT, traits>, initializing the base class with basic_­istream(&sb) and initializing sb with basic_­filebuf<charT, traits>()) ([istream.cons], [filebuf.cons]).
explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in); // wide systems only; see [fstream.syn]
Effects: Constructs an object of class basic_­ifstream, initializing the base class with basic_­istream(&sb) and initializing sb with basic_­filebuf<charT, traits>()) ([istream.cons], [filebuf.cons]), then calls rdbuf()->open(s, mode | ios_­base​::​in).
If that function returns a null pointer, calls setstate(failbit).
explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const filesystem::path& s, ios_base::openmode mode = ios_base::in);
Effects: The same as basic_­ifstream(s.c_­str(), mode).
basic_ifstream(basic_ifstream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by move constructing the base class, and the contained basic_­filebuf.
Next basic_­istream<charT, traits>​::​set_­rdbuf(&sb) is called to install the contained basic_­filebuf.

30.9.3.2 Assign and swap [ifstream.assign]

basic_ifstream& operator=(basic_ifstream&& rhs);
Effects: Move assigns the base and members of *this from the base and corresponding members of rhs.
Returns: *this.
void swap(basic_ifstream& rhs);
Effects: Exchanges the state of *this and rhs by calling basic_­istream<charT, traits>​::​swap(rhs) and sb.swap(rhs.sb).
template <class charT, class traits> void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
Effects: As if by x.swap(y).

30.9.3.3 Member functions [ifstream.members]

basic_filebuf<charT, traits>* rdbuf() const;
Returns: const_­cast<basic_­filebuf<charT, traits>*>(&sb).
bool is_open() const;
Returns: rdbuf()->is_­open().
void open(const char* s, ios_base::openmode mode = ios_base::in); void open(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in); // wide systems only; see [fstream.syn]
Effects: Calls rdbuf()->open(s, mode | ios_­base​::​in).
If that function does not return a null pointer calls clear(), otherwise calls setstate(failbit) (which may throw ios_­base​::​failure) ([iostate.flags]).
void open(const string& s, ios_base::openmode mode = ios_base::in); void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in);
Effects: Calls open(s.c_­str(), mode).
void close();
Effects: Calls rdbuf()->close() and, if that function returns a null pointer, calls setstate(failbit) (which may throw ios_­base​::​failure) ([iostate.flags]).

30.9.4 Class template basic_­ofstream [ofstream]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_ofstream : public basic_ostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [ofstream.cons], constructors
    basic_ofstream();
    explicit basic_ofstream(const char* s,
                            ios_base::openmode mode = ios_base::out);
    explicit basic_ofstream(const filesystem::path::value_type* s,
                            ios_base::openmode mode = ios_base::out);  // wide systems only; see [fstream.syn]
    explicit basic_ofstream(const string& s,
                            ios_base::openmode mode = ios_base::out);
    explicit basic_ofstream(const filesystem::path& s,
                            ios_base::openmode mode = ios_base::out);
    basic_ofstream(const basic_ofstream& rhs) = delete;
    basic_ofstream(basic_ofstream&& rhs);

    // [ofstream.assign], assign and swap
    basic_ofstream& operator=(const basic_ofstream& rhs) = delete;
    basic_ofstream& operator=(basic_ofstream&& rhs);
    void swap(basic_ofstream& rhs);

    // [ofstream.members], members
    basic_filebuf<charT, traits>* rdbuf() const;

    bool is_open() const;
    void open(const char* s, ios_base::openmode mode = ios_base::out);
    void open(const filesystem::path::value_type* s,
              ios_base::openmode mode = ios_base::out);  // wide systems only; see [fstream.syn]
    void open(const string& s, ios_base::openmode mode = ios_base::out);
    void open(const filesystem::path& s, ios_base::openmode mode = ios_base::out);
    void close();
  private:
    basic_filebuf<charT, traits> sb; // exposition only
  };

  template <class charT, class traits>
    void swap(basic_ofstream<charT, traits>& x,
              basic_ofstream<charT, traits>& y);
}
The class basic_­ofstream<charT, traits> supports writing to named files.
It uses a basic_­filebuf<​charT, traits> object to control the associated sequence.
For the sake of exposition, the maintained data is presented here as:

30.9.4.1 basic_­ofstream constructors [ofstream.cons]

basic_ofstream();
Effects: Constructs an object of class basic_­ofstream<charT, traits>, initializing the base class with basic_­ostream(&sb) and initializing sb with basic_­filebuf<charT, traits>()) ([ostream.cons], [filebuf.cons]).
explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::out); // wide systems only; see [fstream.syn]
Effects: Constructs an object of class basic_­ofstream<charT, traits>, initializing the base class with basic_­ostream(&sb) and initializing sb with basic_­filebuf<charT, traits>()) ([ostream.cons], [filebuf.cons]), then calls rdbuf()->open(s, mode | ios_­base​::​out).
If that function returns a null pointer, calls setstate(​failbit).
explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const filesystem::path& s, ios_base::openmode mode = ios_base::out);
Effects: The same as basic_­ofstream(s.c_­str(), mode).
basic_ofstream(basic_ofstream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by move constructing the base class, and the contained basic_­filebuf.
Next basic_­ostream<charT, traits>​::​set_­rdbuf(&sb) is called to install the contained basic_­filebuf.

30.9.4.2 Assign and swap [ofstream.assign]

basic_ofstream& operator=(basic_ofstream&& rhs);
Effects: Move assigns the base and members of *this from the base and corresponding members of rhs.
Returns: *this.
void swap(basic_ofstream& rhs);
Effects: Exchanges the state of *this and rhs by calling basic_­ostream<charT, traits>​::​swap(rhs) and sb.swap(rhs.sb).
template <class charT, class traits> void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
Effects: As if by x.swap(y).

30.9.4.3 Member functions [ofstream.members]

basic_filebuf<charT, traits>* rdbuf() const;
Returns: const_­cast<basic_­filebuf<charT, traits>*>(&sb).
bool is_open() const;
Returns: rdbuf()->is_­open().
void open(const char* s, ios_base::openmode mode = ios_base::out); void open(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::out); // wide systems only; see [fstream.syn]
Effects: Calls rdbuf()->open(s, mode | ios_­base​::​out).
If that function does not return a null pointer calls clear(), otherwise calls setstate(​failbit) (which may throw ios_­base​::​failure) ([iostate.flags]).
void close();
Effects: Calls rdbuf()->close() and, if that function fails (returns a null pointer), calls setstate(​failbit) (which may throw ios_­base​::​failure) ([iostate.flags]).
void open(const string& s, ios_base::openmode mode = ios_base::out); void open(const filesystem::path& s, ios_base::openmode mode = ios_base::out);
Effects: Calls open(s.c_­str(), mode).

30.9.5 Class template basic_­fstream [fstream]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_fstream : public basic_iostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    // [fstream.cons], constructors
    basic_fstream();
    explicit basic_fstream(
      const char* s,
      ios_base::openmode mode = ios_base::in | ios_base::out);
    explicit basic_fstream(
      const std::filesystem::path::value_type* s,
      ios_base::openmode mode = ios_base::in|ios_base::out);  // wide systems only; see [fstream.syn]
    explicit basic_fstream(
      const string& s,
      ios_base::openmode mode = ios_base::in | ios_base::out);
    explicit basic_fstream(
      const filesystem::path& s,
      ios_base::openmode mode = ios_base::in | ios_base::out);
    basic_fstream(const basic_fstream& rhs) = delete;
    basic_fstream(basic_fstream&& rhs);

    // [fstream.assign], assign and swap
    basic_fstream& operator=(const basic_fstream& rhs) = delete;
    basic_fstream& operator=(basic_fstream&& rhs);
    void swap(basic_fstream& rhs);

    // [fstream.members], members
    basic_filebuf<charT, traits>* rdbuf() const;
    bool is_open() const;
    void open(
      const char* s,
      ios_base::openmode mode = ios_base::in | ios_base::out);
    void open(
      const std::filesystem::path::value_type* s,
      ios_base::openmode mode = ios_base::in|ios_base::out);  // wide systems only; see [fstream.syn]
    void open(
      const string& s,
      ios_base::openmode mode = ios_base::in | ios_base::out);
    void open(
      const filesystem::path& s,
      ios_base::openmode mode = ios_base::in | ios_base::out);
    void close();

  private:
    basic_filebuf<charT, traits> sb; // exposition only
  };

  template <class charT, class traits>
    void swap(basic_fstream<charT, traits>& x,
              basic_fstream<charT, traits>& y);
}
The class template basic_­fstream<charT, traits> supports reading and writing from named files.
It uses a basic_­filebuf<charT, traits> object to control the associated sequences.
For the sake of exposition, the maintained data is presented here as:
  • sb, the basic_­filebuf object.

30.9.5.1 basic_­fstream constructors [fstream.cons]

basic_fstream();
Effects: Constructs an object of class basic_­fstream<charT, traits>, initializing the base class with basic_­iostream(&sb) and initializing sb with basic_­filebuf<charT, traits>().
explicit basic_fstream( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); explicit basic_fstream( const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see [fstream.syn]
Effects: Constructs an object of class basic_­fstream<charT, traits>, initializing the base class with basic_­iostream(&sb) and initializing sb with basic_­filebuf<charT, traits>().
Then calls rdbuf()->open(s, mode).
If that function returns a null pointer, calls setstate(failbit).
explicit basic_fstream( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); explicit basic_fstream( const filesystem::path& s, ios_base::openmode mode = ios_base::in | ios_base::out);
Effects: The same as basic_­fstream(s.c_­str(), mode).
basic_fstream(basic_fstream&& rhs);
Effects: Move constructs from the rvalue rhs.
This is accomplished by move constructing the base class, and the contained basic_­filebuf.
Next basic_­istream<charT, traits>​::​set_­rdbuf(&sb) is called to install the contained basic_­filebuf.

30.9.5.2 Assign and swap [fstream.assign]

basic_fstream& operator=(basic_fstream&& rhs);
Effects: Move assigns the base and members of *this from the base and corresponding members of rhs.
Returns: *this.
void swap(basic_fstream& rhs);
Effects: Exchanges the state of *this and rhs by calling basic_­iostream<charT,traits>​::​swap(rhs) and sb.swap(rhs.sb).
template <class charT, class traits> void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
Effects: As if by x.swap(y).

30.9.5.3 Member functions [fstream.members]

basic_filebuf<charT, traits>* rdbuf() const;
Returns: const_­cast<basic_­filebuf<charT, traits>*>(&sb).
bool is_open() const;
Returns: rdbuf()->is_­open().
void open( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); void open( const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see [fstream.syn]
Effects: Calls rdbuf()->open(s, mode).
If that function does not return a null pointer calls clear(), otherwise calls setstate(failbit) (which may throw ios_­base​::​failure) ([iostate.flags]).
void open( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); void open( const filesystem::path& s, ios_base::openmode mode = ios_base::in | ios_base::out);
Effects: Calls open(s.c_­str(), mode).
void close();
Effects: Calls rdbuf()->close() and, if that function returns a null pointer, calls setstate(failbit) (which may throw ios_­base​::​failure) ([iostate.flags]).

30.10 File systems [filesystems]

30.10.1 General [fs.general]

This subclause describes operations on file systems and their components, such as paths, regular files, and directories.

30.10.2 Conformance [fs.conformance]

Conformance is specified in terms of behavior.
Ideal behavior is not always implementable, so the conformance subclauses take that into account.

30.10.2.1 POSIX conformance [fs.conform.9945]

Some behavior is specified by reference to POSIX ([fs.norm.ref]).
How such behavior is actually implemented is unspecified.
[Note
:
This constitutes an “as if” rule allowing implementations to call native operating system or other APIs.
end note
]
Implementations are encouraged to provide such behavior as it is defined by POSIX.
Implementations shall document any behavior that differs from the behavior defined by POSIX.
Implementations that do not support exact POSIX behavior are encouraged to provide behavior as close to POSIX behavior as is reasonable given the limitations of actual operating systems and file systems.
If an implementation cannot provide any reasonable behavior, the implementation shall report an error as specified in [fs.err.report].
[Note
:
This allows users to rely on an exception being thrown or an error code being set when an implementation cannot provide any reasonable behavior.
end note
]
Implementations are not required to provide behavior that is not supported by a particular file system.
[Example
:
The FAT file system used by some memory cards, camera memory, and floppy disks does not support hard links, symlinks, and many other features of more capable file systems, so implementations are not required to support those features on the FAT file system but instead are required to report an error as described above.
end example
]

30.10.2.2 Operating system dependent behavior conformance [fs.conform.os]

Some behavior is specified as being operating system dependent ([fs.def.osdep]).
The operating system an implementation is dependent upon is implementation-defined.
It is permissible for an implementation to be dependent upon an operating system emulator rather than the actual underlying operating system.

30.10.2.3 File system race behavior [fs.race.behavior]

Behavior is undefined if calls to functions provided by this subclause introduce a file system race ([fs.def.race]).
If the possibility of a file system race would make it unreliable for a program to test for a precondition before calling a function described herein, Requires: is not specified for the function.
[Note
:
As a design practice, preconditions are not specified when it is unreasonable for a program to detect them prior to calling the function.
end note
]

30.10.3 Normative references [fs.norm.ref]

This subclause mentions commercially available operating systems for purposes of exposition.328
POSIX® is a registered trademark of The IEEE.
Windows® is a registered trademark of Microsoft Corporation.
This information is given for the convenience of users of this document and does not constitute an endorsement by ISO or IEC of these products.

30.10.4 Terms and definitions [fs.definitions]

30.10.4.1 absolute path [fs.def.absolute.path]

A path that unambiguously identifies the location of a file without reference to an additional starting location.
The elements of a path that determine if it is absolute are operating system dependent.

30.10.4.2 directory [fs.def.directory]

A file within a file system that acts as a container of directory entries that contain information about other files, possibly including other directory files.

30.10.4.3 file [fs.def.file]

An object within a file system that holds user or system data.
Files can be written to, or read from, or both.
A file has certain attributes, including type.
File types include regular files and directories.
Other types of files, such as symbolic links ([fs.def.symlink]), may be supported by the implementation.

30.10.4.4 file system [fs.def.filesystem]

A collection of files and their attributes.

30.10.4.5 file system race [fs.def.race]

The condition that occurs when multiple threads, processes, or computers interleave access and modification of the same object within a file system.

30.10.4.6 filename [fs.def.filename]

The name of a file.
Filenames dot and dot-dot, consisting solely of one and two period characters respectively, have special meaning.
The following characteristics of filenames are operating system dependent:
  • The permitted characters.
    [Example
    :
    Some operating systems prohibit the ASCII control characters (0x00 – 0x1F) in filenames.
    end example
    ]
  • The maximum permitted length.
  • Filenames that are not permitted.
  • Filenames that have special meaning.
  • Case awareness and sensitivity during path resolution.
  • Special rules that may apply to file types other than regular files, such as directories.

30.10.4.9 native encoding [fs.def.native.encode]

For narrow character strings, the operating system dependent current encoding for pathnames ([fs.def.pathname]).
For wide character strings, the implementation-defined execution wide-character set encoding ([lex.charset]).

30.10.4.10 native pathname format [fs.def.native]

The operating system dependent pathname format accepted by the host operating system.

30.10.4.11 normal form [fs.def.normal.form]

A path in normal form is said to be normalized.
The process of obtaining a normalized path from a path that is not in normal form is called normalization.
Normalization of a generic format pathname means:
  1. If the path is empty, stop.
  2. Replace each slash character in the root-name with a preferred-separator.
  3. [Note
    :
    The generic pathname grammar ([fs.path.generic]) defines directory-separator as one or more slashes and preferred-separators.
    end note
    ]
  4. Remove each dot filename and any immediately following directory-separator.
  5. As long as any appear, remove a non-dot-dot filename immediately followed by a directory-separator and a dot-dot filename, along with any immediately following directory-separator.
  6. If there is a root-directory, remove all dot-dot filenames and any directory-separators immediately following them.
    [Note
    :
    These dot-dot filenames attempt to refer to nonexistent parent directories.
    end note
    ]
  7. If the last filename is dot-dot, remove any trailing directory-separator.
  8. If the path is empty, add a dot.

30.10.4.12 operating system dependent behavior [fs.def.osdep]

Behavior that is dependent upon the behavior and characteristics of an operating system.

30.10.4.13 parent directory [fs.def.parent]

⟨of a directory⟩ the directory that both contains a directory entry for the given directory and is represented by the filename dot-dot in the given directory.

30.10.4.14 parent directory [fs.def.parent.other]

⟨of other types of files⟩ a directory containing a directory entry for the file under discussion.

30.10.4.15 path [fs.def.path]

A sequence of elements that identify the location of a file within a filesystem.
The elements are the root-name, root-directory, and an optional sequence of filenames.
The maximum number of elements in the sequence is operating system dependent.

30.10.4.16 pathname [fs.def.pathname]

A character string that represents the name of a path.
Pathnames are formatted according to the generic pathname format grammar ([fs.path.generic]) or an operating system dependent native pathname format.

30.10.4.17 pathname resolution [fs.def.pathres]

Pathname resolution is the operating system dependent mechanism for resolving a pathname to a particular file in a file hierarchy.
There may be multiple pathnames that resolve to the same file.
[Example
:
POSIX specifies the mechanism in section 4.
11, Pathname resolution.
end example
]

30.10.4.18 relative path [fs.def.rel.path]

A path that is not absolute, and as such, only unambiguously identifies the location of a file when resolved ([fs.def.pathres]) relative to an implied starting location.
The elements of a path that determine if it is relative are operating system dependent.
[Note
:
Pathnames “.
” and “.
” are relative paths.
end note
]

30.10.5 Requirements [fs.req]

Throughout this subclause, char, wchar_­t, char16_­t, and char32_­t are collectively called encoded character types.
Functions with template parameters named EcharT shall not participate in overload resolution unless EcharT is one of the encoded character types.
Template parameters named InputIterator shall meet the input iterator requirements ([input.iterators]) and shall have a value type that is one of the encoded character types.
[Note
:
Use of an encoded character type implies an associated character set and encoding.
Since signed char and unsigned char have no implied character set and encoding, they are not included as permitted types.
end note
]
Template parameters named Allocator shall meet the Allocator requirements ([allocator.requirements]).

30.10.5.1 Namespaces and headers [fs.req.namespace]

Unless otherwise specified, references to entities described in this subclause are assumed to be qualified with ​::​std​::​filesystem​::​.

30.10.6 Header <filesystem> synopsis [fs.filesystem.syn]

namespace std::filesystem {
  // [fs.class.path], paths
  class path;

  // [fs.path.nonmember], path non-member functions
  void swap(path& lhs, path& rhs) noexcept;
  size_t hash_value(const path& p) noexcept;

  bool operator==(const path& lhs, const path& rhs) noexcept;
  bool operator!=(const path& lhs, const path& rhs) noexcept;
  bool operator< (const path& lhs, const path& rhs) noexcept;
  bool operator<=(const path& lhs, const path& rhs) noexcept;
  bool operator> (const path& lhs, const path& rhs) noexcept;
  bool operator>=(const path& lhs, const path& rhs) noexcept;

  path operator/ (const path& lhs, const path& rhs);

  // [fs.path.io], path inserter and extractor
  template <class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const path& p);
  template <class charT, class traits>
    basic_istream<charT, traits>&
      operator>>(basic_istream<charT, traits>& is, path& p);

  // [fs.path.factory], path factory functions
  template <class Source>
    path u8path(const Source& source);
  template <class InputIterator>
    path u8path(InputIterator first, InputIterator last);

  // [fs.class.filesystem_error], filesystem errors
  class filesystem_error;

  // [fs.class.directory_entry], directory entries
  class directory_entry;

  // [fs.class.directory_iterator], directory iterators
  class directory_iterator;

  // [fs.dir.itr.nonmembers], range access for directory iterators
  directory_iterator begin(directory_iterator iter) noexcept;
  directory_iterator end(const directory_iterator&) noexcept;

  // [fs.class.rec.dir.itr], recursive directory iterators
  class recursive_directory_iterator;

  // [fs.rec.dir.itr.nonmembers], range access for recursive directory iterators
  recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
  recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;

  // [fs.class.file_status], file status
  class file_status;

  struct space_info {
    uintmax_t capacity;
    uintmax_t free;
    uintmax_t available;
  };

  // [fs.enum], enumerations
  enum class file_type;
  enum class perms;
  enum class perm_options;
  enum class copy_options;
  enum class directory_options;

  using file_time_type = chrono::time_point<trivial-clock>;

  // [fs.op.funcs], filesystem operations
  path absolute(const path& p, const path& base = current_path());

  path canonical(const path& p, const path& base = current_path());
  path canonical(const path& p, error_code& ec);
  path canonical(const path& p, const path& base, error_code& ec);

  void copy(const path& from, const path& to);
  void copy(const path& from, const path& to, error_code& ec) noexcept;
  void copy(const path& from, const path& to, copy_options options);
  void copy(const path& from, const path& to, copy_options options,
            error_code& ec) noexcept;

  bool copy_file(const path& from, const path& to);
  bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
  bool copy_file(const path& from, const path& to, copy_options option);
  bool copy_file(const path& from, const path& to, copy_options option,
                 error_code& ec) noexcept;

  void copy_symlink(const path& existing_symlink, const path& new_symlink);
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
                    error_code& ec) noexcept;

  bool create_directories(const path& p);
  bool create_directories(const path& p, error_code& ec) noexcept;

  bool create_directory(const path& p);
  bool create_directory(const path& p, error_code& ec) noexcept;

  bool create_directory(const path& p, const path& attributes);
  bool create_directory(const path& p, const path& attributes,
                        error_code& ec) noexcept;

  void create_directory_symlink(const path& to, const path& new_symlink);
  void create_directory_symlink(const path& to, const path& new_symlink,
                                error_code& ec) noexcept;

  void create_hard_link(const path& to, const path& new_hard_link);
  void create_hard_link(const path& to, const path& new_hard_link,
                        error_code& ec) noexcept;

  void create_symlink(const path& to, const path& new_symlink);
  void create_symlink(const path& to, const path& new_symlink,
                      error_code& ec) noexcept;

  path current_path();
  path current_path(error_code& ec);
  void current_path(const path& p);
  void current_path(const path& p, error_code& ec) noexcept;

  bool exists(file_status s) noexcept;
  bool exists(const path& p);
  bool exists(const path& p, error_code& ec) noexcept;

  bool equivalent(const path& p1, const path& p2);
  bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;

  uintmax_t file_size(const path& p);
  uintmax_t file_size(const path& p, error_code& ec) noexcept;

  uintmax_t hard_link_count(const path& p);
  uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;

  bool is_block_file(file_status s) noexcept;
  bool is_block_file(const path& p);
  bool is_block_file(const path& p, error_code& ec) noexcept;

  bool is_character_file(file_status s) noexcept;
  bool is_character_file(const path& p);
  bool is_character_file(const path& p, error_code& ec) noexcept;

  bool is_directory(file_status s) noexcept;
  bool is_directory(const path& p);
  bool is_directory(const path& p, error_code& ec) noexcept;

  bool is_empty(const path& p);
  bool is_empty(const path& p, error_code& ec) noexcept;

  bool is_fifo(file_status s) noexcept;
  bool is_fifo(const path& p);
  bool is_fifo(const path& p, error_code& ec) noexcept;

  bool is_other(file_status s) noexcept;
  bool is_other(const path& p);
  bool is_other(const path& p, error_code& ec) noexcept;

  bool is_regular_file(file_status s) noexcept;
  bool is_regular_file(const path& p);
  bool is_regular_file(const path& p, error_code& ec) noexcept;

  bool is_socket(file_status s) noexcept;
  bool is_socket(const path& p);
  bool is_socket(const path& p, error_code& ec) noexcept;

  bool is_symlink(file_status s) noexcept;
  bool is_symlink(const path& p);
  bool is_symlink(const path& p, error_code& ec) noexcept;

  file_time_type last_write_time(const path& p);
  file_time_type last_write_time(const path& p, error_code& ec) noexcept;
  void last_write_time(const path& p, file_time_type new_time);
  void last_write_time(const path& p, file_time_type new_time,
                       error_code& ec) noexcept;

  void permissions(const path& p, perms prms, perm_options opts=perm_options::replace);
  void permissions(const path& p, perms prms, error_code& ec) noexcept;
  void permissions(const path& p, perms prms, perm_options opts, error_code& ec);

  path proximate(const path& p, error_code& ec);
  path proximate(const path& p, const path& base = current_path());
  path proximate(const path& p, const path& base, error_code& ec);

  path read_symlink(const path& p);
  path read_symlink(const path& p, error_code& ec);

  path relative(const path& p, error_code& ec);
  path relative(const path& p, const path& base = current_path());
  path relative(const path& p, const path& base, error_code& ec);

  bool remove(const path& p);
  bool remove(const path& p, error_code& ec) noexcept;

  uintmax_t remove_all(const path& p);
  uintmax_t remove_all(const path& p, error_code& ec) noexcept;

  void rename(const path& from, const path& to);
  void rename(const path& from, const path& to, error_code& ec) noexcept;

  void resize_file(const path& p, uintmax_t size);
  void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept;

  space_info space(const path& p);
  space_info space(const path& p, error_code& ec) noexcept;

  file_status status(const path& p);
  file_status status(const path& p, error_code& ec) noexcept;

  bool status_known(file_status s) noexcept;

  file_status symlink_status(const path& p);
  file_status symlink_status(const path& p, error_code& ec) noexcept;

  path temp_directory_path();
  path temp_directory_path(error_code& ec);

  path weakly_canonical(const path& p);
  path weakly_canonical(const path& p, error_code& ec);
}
trivial-clock is an implementation-defined type that satisfies the TrivialClock requirements ([time.clock.req]) and that is capable of representing and measuring file time values.
Implementations should ensure that the resolution and range of file_­time_­type reflect the operating system dependent resolution and range of file time values.

30.10.7 Error reporting [fs.err.report]

Filesystem library functions often provide two overloads, one that throws an exception to report file system errors, and another that sets an error_­code.
[Note
:
This supports two common use cases:
  • Uses where file system errors are truly exceptional and indicate a serious failure.
    Throwing an exception is an appropriate response.
  • Uses where file system errors are routine and do not necessarily represent failure.
    Returning an error code is the most appropriate response.
    This allows application specific error handling, including simply ignoring the error.
end note
]
Functions not having an argument of type error_­code& handle errors as follows, unless otherwise specified:
  • When a call by the implementation to an operating system or other underlying API results in an error that prevents the function from meeting its specifications, an exception of type filesystem_­error shall be thrown.
    For functions with a single path argument, that argument shall be passed to the filesystem_­error constructor with a single path argument.
    For functions with two path arguments, the first of these arguments shall be passed to the filesystem_­error constructor as the path1 argument, and the second shall be passed as the path2 argument.
    The filesystem_­error constructor's error_­code argument is set as appropriate for the specific operating system dependent error.
  • Failure to allocate storage is reported by throwing an exception as described in [res.on.exception.handling].
  • Destructors throw nothing.
Functions having an argument of type error_­code& handle errors as follows, unless otherwise specified:
  • If a call by the implementation to an operating system or other underlying API results in an error that prevents the function from meeting its specifications, the error_­code& argument is set as appropriate for the specific operating system dependent error.
    Otherwise, clear() is called on the error_­code& argument.

30.10.8 Class path [fs.class.path]

An object of class path represents a path ([fs.def.path]) and contains a pathname ([fs.def.pathname]).
Such an object is concerned only with the lexical and syntactic aspects of a path.
The path does not necessarily exist in external storage, and the pathname is not necessarily valid for the current operating system or for a particular file system.
[Note
:
Class path is used to support the differences between the string types used by different operating systems to represent pathnames, and to perform conversions between encodings when necessary.
end note
]
namespace std::filesystem {
  class path {
  public:
    using value_type  = see below;
    using string_type = basic_string<value_type>;
    static constexpr value_type preferred_separator = see below;

    // [fs.enum.path.format], enumeration format
    enum format;

    // [fs.path.construct], constructors and destructor
    path() noexcept;
    path(const path& p);
    path(path&& p) noexcept;
    path(string_type&& source, format fmt = auto_format);
    template <class Source>
      path(const Source& source, format fmt = auto_format);
    template <class InputIterator>
      path(InputIterator first, InputIterator last, format fmt = auto_format);
    template <class Source>
      path(const Source& source, const locale& loc, format fmt = auto_format);
    template <class InputIterator>
      path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
    ~path();

    // [fs.path.assign], assignments
    path& operator=(const path& p);
    path& operator=(path&& p) noexcept;
    path& operator=(string_type&& source);
    path& assign(string_type&& source);
    template <class Source>
      path& operator=(const Source& source);
    template <class Source>
      path& assign(const Source& source)
    template <class InputIterator>
      path& assign(InputIterator first, InputIterator last);

    // [fs.path.append], appends
    path& operator/=(const path& p);
    template <class Source>
      path& operator/=(const Source& source);
    template <class Source>
      path& append(const Source& source);
    template <class InputIterator>
      path& append(InputIterator first, InputIterator last);

    // [fs.path.concat], concatenation
    path& operator+=(const path& x);
    path& operator+=(const string_type& x);
    path& operator+=(basic_string_view<value_type> x);
    path& operator+=(const value_type* x);
    path& operator+=(value_type x);
    template <class Source>
      path& operator+=(const Source& x);
    template <class EcharT>
      path& operator+=(EcharT x);
    template <class Source>
      path& concat(const Source& x);
    template <class InputIterator>
      path& concat(InputIterator first, InputIterator last);

    // [fs.path.modifiers], modifiers
    void  clear() noexcept;
    path& make_preferred();
    path& remove_filename();
    path& replace_filename(const path& replacement);
    path& replace_extension(const path& replacement = path());
    void  swap(path& rhs) noexcept;

    // [fs.path.native.obs], native format observers
    const string_type& native() const noexcept;
    const value_type*  c_str() const noexcept;
    operator string_type() const;

    template <class EcharT, class traits = char_traits<EcharT>,
              class Allocator = allocator<EcharT>>
      basic_string<EcharT, traits, Allocator>
        string(const Allocator& a = Allocator()) const;
    std::string    string() const;
    std::wstring   wstring() const;
    std::string    u8string() const;
    std::u16string u16string() const;
    std::u32string u32string() const;

    // [fs.path.generic.obs], generic format observers
    template <class EcharT, class traits = char_traits<EcharT>,
              class Allocator = allocator<EcharT>>
      basic_string<EcharT, traits, Allocator>
        generic_string(const Allocator& a = Allocator()) const;
    std::string    generic_string() const;
    std::wstring   generic_wstring() const;
    std::string    generic_u8string() const;
    std::u16string generic_u16string() const;
    std::u32string generic_u32string() const;

    // [fs.path.compare], compare
    int  compare(const path& p) const noexcept;
    int  compare(const string_type& s) const;
    int  compare(basic_string_view<value_type> s) const;
    int  compare(const value_type* s) const;

    // [fs.path.decompose], decomposition
    path root_name() const;
    path root_directory() const;
    path root_path() const;
    path relative_path() const;
    path parent_path() const;
    path filename() const;
    path stem() const;
    path extension() const;

    // [fs.path.query], query
    bool empty() const noexcept;
    bool has_root_name() const;
    bool has_root_directory() const;
    bool has_root_path() const;
    bool has_relative_path() const;
    bool has_parent_path() const;
    bool has_filename() const;
    bool has_stem() const;
    bool has_extension() const;
    bool is_absolute() const;
    bool is_relative() const;

    // [fs.path.gen], generation
    path lexically_normal() const;
    path lexically_relative(const path& base) const;
    path lexically_proximate(const path& base) const;

    // [fs.path.itr], iterators
    class iterator;
    using const_iterator = iterator;

    iterator begin() const;
    iterator end() const;
  };
}
value_­type is a typedef for the operating system dependent encoded character type used to represent pathnames.
The value of the preferred_­separator member is the operating system dependent preferred-separator character ([fs.path.generic]).
[Example
:
For POSIX-based operating systems, value_­type is char and preferred_­separator is the slash character ('/').
For Windows-based operating systems, value_­type is wchar_­t and preferred_­separator is the backslash character (L'\\').
end example
]

30.10.8.1 Generic pathname format [fs.path.generic]

pathname:
	root-name root-directory relative-path
root-name:
	operating system dependent sequences of characters
	implementation-defined sequences of characters
root-directory:
	directory-separator
relative-path:
	filename
	filename directory-separator relative-path
	an empty path
filename:
	non-empty sequence of characters other than directory-separator characters
directory-separator:
	preferred-separator directory-separator
	fallback-separator directory-separator
preferred-separator:
	operating system dependent directory separator character
fallback-separator:
	/, if preferred-separator is not /
[Note
:
Operating systems often place restrictions on the characters that may be used in a filename.
For wide portability, users may wish to limit filename characters to the POSIX Portable Filename Character Set:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 . _­ -
end note
]
Except in a root-name, multiple successive directory-separator characters are considered to be the same as one directory-separator character.
The filename dot ([fs.def.filename]) is treated as a reference to the current directory.
The filename dot-dot ([fs.def.filename]) is treated as a reference to the parent directory.
What the filename dot-dot refers to relative to root-directory is implementation-defined.
Specific filenames may have special meanings for a particular operating system.
A root-name identifies the starting location for pathname resolution ([fs.def.pathres]).
If there are no operating system dependent root-names, at least one implementation-defined root-name is required.
[Note
:
Many operating systems define a name beginning with two directory-separator characters as a root-name that identifies network or other resource locations.
Some operating systems define a single letter followed by a colon as a drive specifier – a root-name identifying a specific device such as a disk drive.
end note
]
If a root-name is otherwise ambiguous, the possibility with the longest sequence of characters is chosen.
[Note
:
On a POSIX-like operating system, it is impossible to have a root-name and a relative-path without an intervening root-directory element.
end note
]

30.10.8.2 path conversions [fs.path.cvt]

30.10.8.2.1 path argument format conversions [fs.path.fmt.cvt]

[Note
:
The format conversions described in this section are not applied on POSIX-based operating systems because on these systems:
  • The generic format is acceptable as a native path.
  • There is no need to distinguish between native format and generic format in function arguments.
  • Paths for regular files and paths for directories share the same syntax.
end note
]
Several functions are defined to accept detected-format arguments, which are character sequences.
A detected-format argument represents a path using either a pathname in the generic format ([fs.path.generic]) or a pathname in the native format ([fs.def.native]).
Such an argument is taken to be in the generic format if and only if it matches the generic format and is not acceptable to the operating system as a native path.
[Note
:
Some operating systems may have no unambiguous way to distinguish between native format and generic format arguments.
This is by design as it simplifies use for operating systems that do not require disambiguation.
An implementation for an operating system where disambiguation is required is permitted to distinguish between the formats.
end note
]
Pathnames are converted as needed between the generic and native formats in an operating-system-dependent manner.
Let G(n) and N(g) in a mathematical sense be the implementation's functions that convert native-to-generic and generic-to-native formats respectively.
If g=G(n) for some n, then G(N(g))=g; if n=N(g) for some g, then N(G(n))=n.
[Note
:
Neither G nor N need be invertible.
end note
]
If the native format requires paths for regular files to be formatted differently from paths for directories, the path shall be treated as a directory path if its last element is a directory-separator, otherwise it shall be treated as a path to a regular file.
[Note
:
A path stores a native format pathname ([fs.path.native.obs]) and acts as if it also stores a generic format pathname, related as given below.
The implementation may generate the generic format pathname based on the native format pathname (and possibly other information) when requested.
end note
]
When a path is constructed from or is assigned a single representation separate from any path, the other representation is selected by the appropriate conversion function (G or N).
When the (new) value p of one representation of a path is derived from the representation of that or another path, a value q is chosen for the other representation.
The value q converts to p (by G or N as appropriate) if any such value does so; q is otherwise unspecified.
[Note
:
If q is the result of converting any path at all, it is the result of converting p.
end note
]

30.10.8.2.2 path type and encoding conversions [fs.path.type.cvt]

For member function arguments that take character sequences representing paths and for member functions returning strings, value type and encoding conversion is performed if the value type of the argument or return value differs from path​::​value_­type.
For the argument or return value, the method of conversion and the encoding to be converted to is determined by its value type:
  • char: The encoding is the native narrow encoding ([fs.def.native.encode]).
    The method of conversion, if any, is operating system dependent.
    [Note
    :
    For POSIX-based operating systems path​::​value_­type is char so no conversion from char value type arguments or to char value type return values is performed.
    For Windows-based operating systems, the native narrow encoding is determined by calling a Windows API function.
    end note
    ]
    [Note
    :
    This results in behavior identical to other C and C++ standard library functions that perform file operations using narrow character strings to identify paths.
    Changing this behavior would be surprising and error prone.
    end note
    ]
  • wchar_­t: The encoding is the native wide encoding ([fs.def.native.encode]).
    The method of conversion is unspecified.
    [Note
    :
    For Windows-based operating systems path​::​value_­type is wchar_­t so no conversion from wchar_­t value type arguments or to wchar_­t value type return values is performed.
    end note
    ]
  • char16_­t: The encoding is UTF-16.
    The method of conversion is unspecified.
  • char32_­t: The encoding is UTF-32.
    The method of conversion is unspecified.
If the encoding being converted to has no representation for source characters, the resulting converted characters, if any, are unspecified.
Implementations should not modify member function arguments if already of type path​::​value_­type.

30.10.8.3 path requirements [fs.path.req]

In addition to the requirements ([fs.req]), function template parameters named Source shall be one of:
  • basic_­string<EcharT, traits, Allocator>.
    A function argument const Source& source shall have an effective range [source.begin(), source.end()).
  • basic_­string_­view<EcharT, traits>.
    A function argument const Source& source shall have an effective range [source.begin(), source.end()).
  • A type meeting the input iterator requirements that iterates over a NTCTS.
    The value type shall be an encoded character type.
    A function argument const Source& source shall have an effective range [source, end) where end is the first iterator value with an element value equal to iterator_­traits<Source>​::​value_­type().
  • A character array that after array-to-pointer decay results in a pointer to the start of a NTCTS.
    The value type shall be an encoded character type.
    A function argument const Source& source shall have an effective range [source, end) where end is the first iterator value with an element value equal to iterator_­traits<decay_­t<Source>>​::​value_­type().
Functions taking template parameters named Source shall not participate in overload resolution unless either
  • Source is a specialization of basic_­string or basic_­string_­view, or
  • the qualified-id iterator_­traits<decay_­t<Source>>​::​value_­type is valid and denotes a possibly const encoded character type ([temp.deduct]).
[Note
:
See path conversions ([fs.path.cvt]) for how the value types above and their encodings convert to path​::​value_­type and its encoding.
end note
]
Arguments of type Source shall not be null pointers.

30.10.8.4 path members [fs.path.member]

30.10.8.4.1 path constructors [fs.path.construct]

path() noexcept;
Effects: Constructs an object of class path.
Postconditions: empty() == true.
path(const path& p); path(path&& p) noexcept;
Effects: Constructs an object of class path having the same pathname in the native and generic formats, respectively, as the original value of p.
In the second form, p is left in a valid but unspecified state.
path(string_type&& source, format fmt = auto_format);
Effects: Constructs an object of class path for which the pathname in the detected-format of source has the original value of source ([fs.path.fmt.cvt]), converting format if required ([fs.path.fmt.cvt]).
source is left in a valid but unspecified state.
template <class Source> path(const Source& source, format fmt = auto_format); template <class InputIterator> path(InputIterator first, InputIterator last, format fmt = auto_format);
Effects: Let s be the effective range of source ([fs.path.req]) or the range [first, last), with the encoding converted if required ([fs.path.cvt]).
Finds the detected-format of s ([fs.path.fmt.cvt]) and constructs an object of class path for which the pathname in that format is s.
template <class Source> path(const Source& source, const locale& loc, format fmt = auto_format); template <class InputIterator> path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format);
Requires: The value type of Source and InputIterator is char.
Effects: Let s be the effective range of source or the range [first, last), after converting the encoding as follows:
  • If value_­type is wchar_­t, converts to the native wide encoding ([fs.def.native.encode]) using the codecvt<​wchar_­t, char, mbstate_­t> facet of loc.
  • Otherwise a conversion is performed using the codecvt<wchar_­t, char, mbstate_­t> facet of loc, and then a second conversion to the current narrow encoding.
Finds the detected-format of s ([fs.path.fmt.cvt]) and constructs an object of class path for which the pathname in that format is s.
[Example
:
A string is to be read from a database that is encoded in ISO/IEC 8859-1, and used to create a directory:
namespace fs = std::filesystem;
std::string latin1_string = read_latin1_data();
codecvt_8859_1<wchar_t> latin1_facet;
std::locale latin1_locale(std::locale(), latin1_facet);
fs::create_directory(fs::path(latin1_string, latin1_locale));
For POSIX-based operating systems, the path is constructed by first using latin1_­facet to convert ISO/IEC 8859-1 encoded latin1_­string to a wide character string in the native wide encoding ([fs.def.native.encode]).
The resulting wide string is then converted to a narrow character pathname string in the current native narrow encoding.
If the native wide encoding is UTF-16 or UTF-32, and the current native narrow encoding is UTF-8, all of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation, but for other native narrow encodings some characters may have no representation.
For Windows-based operating systems, the path is constructed by using latin1_­facet to convert ISO/IEC 8859-1 encoded latin1_­string to a UTF-16 encoded wide character pathname string.
All of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation.
end example
]

30.10.8.4.2 path assignments [fs.path.assign]

path& operator=(const path& p);
Effects: If *this and p are the same object, has no effect.
Otherwise, sets both respective pathnames of *this to the respective pathnames of p.
Returns: *this.
path& operator=(path&& p) noexcept;
Effects: If *this and p are the same object, has no effect.
Otherwise, sets both respective pathnames of *this to the respective pathnames of p.
p is left in a valid but unspecified state.
[Note
:
A valid implementation is swap(p).
end note
]
Returns: *this.
path& operator=(string_type&& source); path& assign(string_type&& source);
Effects: Sets the pathname in the detected-format of source to the original value of source.
source is left in a valid but unspecified state.
Returns: *this.
template <class Source> path& operator=(const Source& source); template <class Source> path& assign(const Source& source); template <class InputIterator> path& assign(InputIterator first, InputIterator last);
Effects: Let s be the effective range of source ([fs.path.req]) or the range [first, last), with the encoding converted if required ([fs.path.cvt]).
Finds the detected-format of s ([fs.path.fmt.cvt]) and sets the pathname in that format to s.
Returns: *this.

30.10.8.4.3 path appends [fs.path.append]

The append operations use operator/= to denote their semantic effect of appending preferred-separator when needed.
path& operator/=(const path& p);
Effects: If p.is_­absolute() || (p.has_­root_­name() && p.root_­name() != root_­name()), then operator=(p).
Otherwise, modifies *this as if by these steps:
  • If p.has_­root_­directory(), then removes any root directory and relative path from the generic format pathname.
    Otherwise, if !has_­root_­directory() && is_­absolute() is true or if has_­filename() is true, then appends path​::​preferred_­separator to the generic format pathname.
  • Then appends the native format pathname of p, omitting any root-name from its generic format pathname, to the native format pathname.
[Example
:
Even if //host is interpreted as a root-name, both of the paths path("//host")/"foo" and path("//host/")/"foo" equal "//host/foo".
Expression examples:
// On POSIX,
path("foo") / "";     // yields "foo/"
path("foo") / "/bar"; // yields "/bar"
// On Windows, backslashes replace slashes in the above yields

// On Windows,
path("foo") / "c:/bar";  // yields "c:/bar"
path("foo") / "c:";      // yields "c:"
path("c:") / "";         // yields "c:"
path("c:foo") / "/bar";  // yields "c:/bar"
path("c:foo") / "c:bar"; // yields "c:foo/bar"
end example
]
Returns: *this.
template <class Source> path& operator/=(const Source& source); template <class Source> path& append(const Source& source);
Effects: Equivalent to: return operator/=(path(source));
template <class InputIterator> path& append(InputIterator first, InputIterator last);
Effects: Equivalent to: return operator/=(path(first, last));

30.10.8.4.4 path concatenation [fs.path.concat]

path& operator+=(const path& x); path& operator+=(const string_type& x); path& operator+=(basic_string_view<value_type> x); path& operator+=(const value_type* x); path& operator+=(value_type x); template <class Source> path& operator+=(const Source& x); template <class EcharT> path& operator+=(EcharT x); template <class Source> path& concat(const Source& x);
Effects: Appends path(x).native() to the pathname in the native format.
[Note
:
This directly manipulates the value of native() and may not be portable between operating systems.
end note
]
Returns: *this.
template <class InputIterator> path& concat(InputIterator first, InputIterator last);
Effects: Equivalent to return *this += path(first, last).

30.10.8.4.5 path modifiers [fs.path.modifiers]

void clear() noexcept;
Postconditions: empty() == true.
path& make_preferred();
Effects: Each directory-separator of the pathname in the generic format is converted to preferred-separator.
Returns: *this.
[Example
:
path p("foo/bar");
std::cout << p << '\n';
p.make_preferred();
std::cout << p << '\n';
On an operating system where preferred-separator is a slash, the output is:
"foo/bar"
"foo/bar"
On an operating system where preferred-separator is a backslash, the output is:
"foo/bar"
"foo\bar"
end example
]
path& remove_filename();
Postconditions: !has_­filename().
Effects: Remove the generic format pathname of filename() from the generic format pathname.
Returns: *this.
[Example
:
path("foo/bar").remove_filename(); // yields "foo/"
path("foo/").remove_filename();    // yields "foo/"
path("/foo").remove_filename();    // yields "/"
path("/").remove_filename();       // yields "/"
end example
]
path& replace_filename(const path& replacement);
Effects: Equivalent to:
remove_filename();
operator/=(replacement);
Returns: *this.
[Example
:
path("/foo").replace_filename("bar");  // yields "/bar" on POSIX
path("/").replace_filename("bar");     // yields "/bar" on POSIX
end example
]
path& replace_extension(const path& replacement = path());
Effects:
  • Any existing extension()([fs.path.decompose]) is removed from the pathname in the generic format, then
  • If replacement is not empty and does not begin with a dot character, a dot character is appended to the pathname in the generic format, then
  • operator+=(replacement);.
Returns: *this.
void swap(path& rhs) noexcept;
Effects: Swaps the contents (in all formats) of the two paths.
Complexity: Constant time.

30.10.8.4.6 path native format observers [fs.path.native.obs]

The string returned by all native format observers is in the native pathname format ([fs.def.native]).
const string_type& native() const noexcept;
Returns: The pathname in the native format.
const value_type* c_str() const noexcept;
Returns: Equivalent to native().c_­str().
operator string_type() const;
Returns: native().
[Note
:
Conversion to string_­type is provided so that an object of class path can be given as an argument to existing standard library file stream constructors and open functions.
end note
]
template <class EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>> basic_string<EcharT, traits, Allocator> string(const Allocator& a = Allocator()) const;
Returns: native().
Remarks: All memory allocation, including for the return value, shall be performed by a.
Conversion, if any, is specified by [fs.path.cvt].
std::string string() const; std::wstring wstring() const; std::string u8string() const; std::u16string u16string() const; std::u32string u32string() const;
Returns: pathstring.
Remarks: Conversion, if any, is performed as specified by [fs.path.cvt].
The encoding of the string returned by u8string() is always UTF-8.

30.10.8.4.7 path generic format observers [fs.path.generic.obs]

Generic format observer functions return strings formatted according to the generic pathname format ([fs.path.generic]).
A single slash ('/') character is used as the directory-separator.
[Example
:
On an operating system that uses backslash as its preferred-separator,
path("foo\\bar").generic_string()
returns "foo/bar".
end example
]
template <class EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>> basic_string<EcharT, traits, Allocator> generic_string(const Allocator& a = Allocator()) const;
Returns: The pathname in the generic format.
Remarks: All memory allocation, including for the return value, shall be performed by a.
Conversion, if any, is specified by [fs.path.cvt].
std::string generic_string() const; std::wstring generic_wstring() const; std::string generic_u8string() const; std::u16string generic_u16string() const; std::u32string generic_u32string() const;
Returns: The pathname in the generic format.
Remarks: Conversion, if any, is specified by [fs.path.cvt].
The encoding of the string returned by generic_­u8string() is always UTF-8.

30.10.8.4.8 path compare [fs.path.compare]

int compare(const path& p) const noexcept;
Returns:
  • A value less than 0, if native() for the elements of *this are lexicographically less than native() for the elements of p; otherwise,
  • a value greater than 0, if native() for the elements of *this are lexicographically greater than native() for the elements of p; otherwise,
  • 0.
Remarks: The elements are determined as if by iteration over the half-open range [begin(), end()) for *this and p.
int compare(const string_type& s) const int compare(basic_string_view<value_type> s) const;
Returns: compare(path(s)).
int compare(const value_type* s) const
Returns: compare(path(s)).

30.10.8.4.9 path decomposition [fs.path.decompose]

path root_name() const;
Returns: root-name, if the pathname in the generic format includes root-name, otherwise path().
path root_directory() const;
Returns: root-directory, if the pathname in the generic format includes root-directory, otherwise path().
path root_path() const;
Returns: root_­name() / root_­directory().
path relative_path() const;
Returns: A path composed from the pathname in the generic format, if !empty(), beginning with the first filename after root-path.
Otherwise, path().
path parent_path() const;
Returns: *this if !has_­relative_­path(), otherwise a path whose generic format pathname is the longest prefix of the generic format pathname of *this that produces one fewer element in its iteration.
path filename() const;
Returns: relative_­path().empty() ? path() : *--end().
[Example
:
path("/foo/bar.txt").filename();   // yields "bar.txt"
path("/foo/bar").filename();       // yields "bar"
path("/foo/bar/").filename();      // yields ""
path("/").filename();              // yields ""
path("//host").filename();         // yields ""
path(".").filename();              // yields "."
path("..").filename();             // yields ".."
end example
]
path stem() const;
Returns: Let f be the generic format pathname of filename().
Returns a path whose pathname in the generic format is
  • f, if it contains no periods other than a leading period or consists solely of one or two periods;
  • otherwise, the prefix of f ending before its last period.
[Example
:
std::cout << path("/foo/bar.txt").stem(); // outputs "bar"
path p = "foo.bar.baz.tar";
for (; !p.extension().empty(); p = p.stem())
  std::cout << p.extension() << '\n';
  // outputs: .tar
  //          .baz
  //          .bar
end example
]
path extension() const;
Returns: a path whose pathname in the generic format is the suffix of filename() not included in stem().
[Example
:
path("/foo/bar.txt").extension();  // yields ".txt" and stem() is "bar"
path("/foo/bar").extension();      // yields "" and stem() is "bar"
path("/foo/.profile").extension(); // yields "" and stem() is ".profile"
path(".bar").extension();          // yields "" and stem() is ".bar"
path("..bar").extension();         // yields ".bar" and stem() is "."
end example
]
[Note
:
The period is included in the return value so that it is possible to distinguish between no extension and an empty extension.
end note
]
[Note
:
On non-POSIX operating systems, for a path p, it may not be the case that p.stem() + p.extension() == p.filename(), even though the generic format pathnames are the same.
end note
]

30.10.8.4.10 path query [fs.path.query]

bool empty() const noexcept;
Returns: true if the pathname in the generic format is empty, else false.
bool has_root_path() const;
Returns: !root_­path().empty().
bool has_root_name() const;
Returns: !root_­name().empty().
bool has_root_directory() const;
Returns: !root_­directory().empty().
bool has_relative_path() const;
Returns: !relative_­path().empty().
bool has_parent_path() const;
Returns: !parent_­path().empty().
bool has_filename() const;
Returns: !filename().empty().
bool has_stem() const;
Returns: !stem().empty().
bool has_extension() const;
Returns: !extension().empty().
bool is_absolute() const;
Returns: true if the pathname in the native format contains an absolute path ([fs.def.absolute.path]), else false.
[Example
:
path("/").is_­absolute() is true for POSIX-based operating systems, and false for Windows-based operating systems.
end example
]
bool is_relative() const;
Returns: !is_­absolute().

30.10.8.4.11 path generation [fs.path.gen]

path lexically_normal() const;
Returns: A path whose pathname in the generic format is the normal form ([fs.def.normal.form]) of the pathname in the generic format of *this.
[Example
:
assert(path("foo/./bar/..").lexically_normal() == "foo/");
assert(path("foo/.///bar/../").lexically_normal() == "foo/");
The above assertions will succeed.
On Windows, the returned path's directory-separator characters will be backslashes rather than slashes, but that does not affect path equality.
end example
]
path lexically_relative(const path& base) const;
Returns: *this made relative to base.
Does not resolve ([fs.def.pathres]) symlinks.
Does not first normalize ([fs.def.normal.form]) *this or base.
Effects: If root_­name() != base.root_­name() is true or is_­absolute() != base.is_­absolute() is true or !has_­root_­directory() && base.has_­root_­directory() is true, returns path().
Determines the first mismatched element of *this and base as if by:
auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());
Then,
  • if a == end() and b == base.end(), returns path("."); otherwise
  • let n be the number of filename elements in [b, base.end()) that are not dot or dot-dot minus the number that are dot-dot.
    If n<0, returns path(); otherwise
  • returns an object of class path that is default-constructed, followed by
    • application of operator/=(path("..")) n times, and then
    • application of operator/= for each element in [a, end()).
[Example
:
assert(path("/a/d").lexically_relative("/a/b/c") == "../../d");
assert(path("/a/b/c").lexically_relative("/a/d") == "../b/c");
assert(path("a/b/c").lexically_relative("a") == "b/c");
assert(path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
assert(path("a/b/c").lexically_relative("a/b/c") == ".");
assert(path("a/b").lexically_relative("c/d") == "../../a/b");
The above assertions will succeed.
On Windows, the returned path's directory-separator characters will be backslashes rather than slashes, but that does not affect path equality.
end example
]
[Note
:
If symlink following semantics are desired, use the operational function relative().
end note
]
[Note
:
If normalization ([fs.def.normal.form]) is needed to ensure consistent matching of elements, apply lexically_­normal() to *this, base, or both.
end note
]
path lexically_proximate(const path& base) const;
Returns: If the value of lexically_­relative(base) is not an empty path, return it.
Otherwise return *this.
[Note
:
If symlink following semantics are desired, use the operational function proximate().
end note
]
[Note
:
If normalization ([fs.def.normal.form]) is needed to ensure consistent matching of elements, apply lexically_­normal() to *this, base, or both.
end note
]

30.10.8.5 path iterators [fs.path.itr]

Path iterators iterate over the elements of the pathname in the generic format ([fs.path.generic]).
A path​::​iterator is a constant iterator satisfying all the requirements of a bidirectional iterator ([bidirectional.iterators]) except that, for dereferenceable iterators a and b of type path​::​iterator with a == b, there is no requirement that *a and *b are bound to the same object.
Its value_­type is path.
Calling any non-const member function of a path object invalidates all iterators referring to elements of that object.
For the elements of the pathname in the generic format, the forward traversal order is as follows:
The backward traversal order is the reverse of forward traversal.
iterator begin() const;
Returns: An iterator for the first present element in the traversal list above.
If no elements are present, the end iterator.
iterator end() const;
Returns: The end iterator.

30.10.8.6 path non-member functions [fs.path.nonmember]

void swap(path& lhs, path& rhs) noexcept;
Effects: Equivalent to: lhs.swap(rhs);
size_t hash_value (const path& p) noexcept;
Returns: A hash value for the path p.
If for two paths, p1 == p2 then hash_­value(p1) == hash_­value(p2).
bool operator< (const path& lhs, const path& rhs) noexcept;
Returns: lhs.compare(rhs) < 0.
bool operator<=(const path& lhs, const path& rhs) noexcept;
Returns: !(rhs < lhs).
bool operator> (const path& lhs, const path& rhs) noexcept;
Returns: rhs < lhs.
bool operator>=(const path& lhs, const path& rhs) noexcept;
Returns: !(lhs < rhs).
bool operator==(const path& lhs, const path& rhs) noexcept;
Returns: !(lhs < rhs) && !(rhs < lhs).
[Note
:
Path equality and path equivalence have different semantics.
  • Equality is determined by the path non-member operator==, which considers the two path's lexical representations only.
    [Example
    :
    path("foo") == "bar" is never true.
    end example
    ]
  • Equivalence is determined by the equivalent() non-member function, which determines if two paths resolve ([fs.def.pathres]) to the same file system entity.
    [Example
    :
    equivalent("foo", "bar") will be true when both paths resolve to the same file.
    end example
    ]
Programmers wishing to determine if two paths are “the same” must decide if “the same” means “the same representation” or “resolve to the same actual file”, and choose the appropriate function accordingly.
end note
]
bool operator!=(const path& lhs, const path& rhs) noexcept;
Returns: !(lhs == rhs).
path operator/ (const path& lhs, const path& rhs);
Effects: Equivalent to: return path(lhs) /= rhs;

30.10.8.6.1 path inserter and extractor [fs.path.io]

template <class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const path& p);
Effects: Equivalent to: os << quoted(p.string<charT, traits>());
[Note
:
The quoted function is described in [quoted.manip].
end note
]
Returns: os.
template <class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, path& p);
Effects: Equivalent to:
basic_string<charT, traits> tmp;
is >> quoted(tmp);
p = tmp;
Returns: is.

30.10.8.6.2 path factory functions [fs.path.factory]

template <class Source> path u8path(const Source& source); template <class InputIterator> path u8path(InputIterator first, InputIterator last);
Requires: The source and [first, last) sequences are UTF-8 encoded.
The value type of Source and InputIterator is char.
Returns:
  • If value_­type is char and the current native narrow encoding ([fs.def.native.encode]) is UTF-8, return path(source) or path(first, last); otherwise,
  • if value_­type is wchar_­t and the native wide encoding is UTF-16, or if value_­type is char16_­t or char32_­t, convert source or [first, last) to a temporary, tmp, of type string_­type and return path(tmp); otherwise,
  • convert source or [first, last) to a temporary, tmp, of type u32string and return path(tmp).
Remarks: Argument format conversion ([fs.path.fmt.cvt]) applies to the arguments for these functions.
How Unicode encoding conversions are performed is unspecified.
[Example
:
A string is to be read from a database that is encoded in UTF-8, and used to create a directory using the native encoding for filenames:
namespace fs = std::filesystem;
std::string utf8_string = read_utf8_data();
fs::create_directory(fs::u8path(utf8_string));
For POSIX-based operating systems with the native narrow encoding set to UTF-8, no encoding or type conversion occurs.
For POSIX-based operating systems with the native narrow encoding not set to UTF-8, a conversion to UTF-32 occurs, followed by a conversion to the current native narrow encoding.
Some Unicode characters may have no native character set representation.
For Windows-based operating systems a conversion from UTF-8 to UTF-16 occurs.
end example
]

30.10.9 Class filesystem_­error [fs.class.filesystem_error]

namespace std::filesystem {
  class filesystem_error : public system_error {
  public:
    filesystem_error(const string& what_arg, error_code ec);
    filesystem_error(const string& what_arg,
                     const path& p1, error_code ec);
    filesystem_error(const string& what_arg,
                     const path& p1, const path& p2, error_code ec);

    const path& path1() const noexcept;
    const path& path2() const noexcept;
    const char* what() const noexcept override;
  };
}
The class filesystem_­error defines the type of objects thrown as exceptions to report file system errors from functions described in this subclause.

30.10.9.1 filesystem_­error members [filesystem_error.members]

Constructors are provided that store zero, one, or two paths associated with an error.
filesystem_error(const string& what_arg, error_code ec);
Postconditions: The postconditions of this function are indicated in Table 114.
Table 114filesystem_­error(const string&, error_­code) effects
Expression
Value
runtime_­error​::​what()
what_­arg.c_­str()
code()
ec
path1().empty()
true
path2().empty()
true
filesystem_error(const string& what_arg, const path& p1, error_code ec);
Postconditions: The postconditions of this function are indicated in Table 115.
Table 115filesystem_­error(const string&, const path&, error_­code) effects
Expression
Value
runtime_­error​::​what()
what_­arg.c_­str()
code()
ec
path1()
Reference to stored copy of p1
path2().empty()
true
filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec);
Postconditions: The postconditions of this function are indicated in Table 116.
Table 116filesystem_­error(const string&, const path&, const path&, error_­code) effects
Expression
Value
runtime_­error​::​what()
what_­arg.c_­str()
code()
ec
path1()
Reference to stored copy of p1
path2()
Reference to stored copy of p2
const path& path1() const noexcept;
Returns: A reference to the copy of p1 stored by the constructor, or, if none, an empty path.
const path& path2() const noexcept;
Returns: A reference to the copy of p2 stored by the constructor, or, if none, an empty path.
const char* what() const noexcept override;
Returns: A string containing runtime_­error​::​what().
The exact format is unspecified.
Implementations are encouraged but not required to include path1.native_­string() if not empty, path2.native_­string() if not empty, and system_­error​::​what() strings in the returned string.

30.10.10 Enumerations [fs.enum]

30.10.10.1 Enum path​::​format [fs.enum.path.format]

This enum specifies constants used to identify the format of the character sequence, with the meanings listed in Table 117.
Table 117 — Enum path​::​format
Name
Meaning
native_­format
The native pathname format.
generic_­format
The generic pathname format.
auto_­format
The interpretation of the format of the character sequence is implementation-defined.
The implementation may inspect the content of the character sequence to determine the format.
[Note
:
For POSIX-based systems, native and generic formats are equivalent and the character sequence should always be interpreted in the same way.
end note
]

30.10.10.2 Enum class file_­type [fs.enum.file_type]

This enum class specifies constants used to identify file types, with the meanings listed in Table 118.
Table 118 — Enum class file_­type
Constant
Meaning
none
The type of the file has not been determined or an error occurred while trying to determine the type.
not_­found
Pseudo-type indicating the file was not found.
[Note
:
The file not being found is not considered an error while determining the type of a file.
end note
]
regular
Regular file
directory
Directory file
symlink
Symbolic link file
block
Block special file
character
Character special file
fifo
FIFO or pipe file
socket
Socket file
implementation-defined
Implementations that support file systems having file types in addition to the above file_­type types shall supply implementation-defined file_­type constants to separately identify each of those additional file types
unknown
The file exists but the type could not be determined

30.10.10.3 Enum class copy_­options [fs.enum.copy.opts]

The enum class type copy_­options is a bitmask type ([bitmask.types]) that specifies bitmask constants used to control the semantics of copy operations.
The constants are specified in option groups with the meanings listed in Table 119.
Constant none is shown in each option group for purposes of exposition; implementations shall provide only a single definition.
Table 119 — Enum class copy_­options
Option group controlling copy_­file function effects for existing target files
Constant
Meaning
none
(Default) Error; file already exists.
skip_­existing
Do not overwrite existing file, do not report an error.
overwrite_­existing
Overwrite the existing file.
update_­existing
Overwrite the existing file if it is older than the replacement file.
Option group controlling copy function effects for sub-directories
Constant
Meaning
none
(Default) Do not copy sub-directories.
recursive
Recursively copy sub-directories and their contents.
Option group controlling copy function effects for symbolic links
Constant
Meaning
none
(Default) Follow symbolic links.
copy_­symlinks
Copy symbolic links as symbolic links rather than copying the files that they point to.
skip_­symlinks
Ignore symbolic links.
Option group controlling copy function effects for choosing the form of copying
Constant
Meaning
none
(Default) Copy content.
directories_­only
Copy directory structure only, do not copy non-directory files.
create_­symlinks
Make symbolic links instead of copies of files.
The source path shall be an absolute path unless the destination path is in the current directory.
create_­hard_­links
Make hard links instead of copies of files.

30.10.10.4 Enum class perms [fs.enum.perms]

The enum class type perms is a bitmask type ([bitmask.types]) that specifies bitmask constants used to identify file permissions, with the meanings listed in Table 120.
Table 120 — Enum class perms
Name
Value
POSIX
Definition or notes
(octal)
macro
none
0
There are no permissions set for the file.
owner_­read
0400
S_­IRUSR
Read permission, owner
owner_­write
0200
S_­IWUSR
Write permission, owner
owner_­exec
0100
S_­IXUSR
Execute/search permission, owner
owner_­all
0700
S_­IRWXU
Read, write, execute/search by owner;
owner_­read | owner_­write | owner_­exec
group_­read
040
S_­IRGRP
Read permission, group
group_­write
020
S_­IWGRP
Write permission, group
group_­exec
010
S_­IXGRP
Execute/search permission, group
group_­all
070
S_­IRWXG
Read, write, execute/search by group;
group_­read | group_­write | group_­exec
others_­read
04
S_­IROTH
Read permission, others
others_­write
02
S_­IWOTH
Write permission, others
others_­exec
01
S_­IXOTH
Execute/search permission, others
others_­all
07
S_­IRWXO
Read, write, execute/search by others;
others_­read | others_­write | others_­exec
all
0777
owner_­all | group_­all | others_­all
set_­uid
04000
S_­ISUID
Set-user-ID on execution
set_­gid
02000
S_­ISGID
Set-group-ID on execution
sticky_­bit
01000
S_­ISVTX
Operating system dependent.
mask
07777
all | set_­uid | set_­gid | sticky_­bit
unknown
0xFFFF
The permissions are not known, such as when a file_­status object is created without specifying the permissions

30.10.10.5 Enum class perm_­options [fs.enum.perm.opts]

The enum class type perm_­options is a bitmask type ([bitmask.types]) that specifies bitmask constants used to control the semantics of permissions operations, with the meanings listed in Table 121.
The bitmask constants are bitmask elements.
In Table 121 perm denotes a value of type perms passed to permissions.
Table 121 — Enum class perm_­options
Name
Meaning
replace
permissions shall replace the file's permission bits with perm
add
permissions shall replace the file's permission bits with the bitwise OR of perm and the file's current permission bits.
remove
permissions shall replace the file's permission bits with the bitwise AND of the complement of perm and the file's current permission bits.
nofollow
permissions shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to.

30.10.10.6 Enum class directory_­options [fs.enum.dir.opts]

The enum class type directory_­options is a bitmask type ([bitmask.types]) that specifies bitmask constants used to identify directory traversal options, with the meanings listed in Table 122.
Table 122 — Enum class directory_­options
Name
Meaning
none
(Default) Skip directory symlinks, permission denied is an error.
follow_­directory_­symlink
Follow rather than skip directory symlinks.
skip_­permission_­denied
Skip directories that would otherwise result in permission denied.

30.10.11 Class file_­status [fs.class.file_status]

namespace std::filesystem {
  class file_status {
  public:
    // [fs.file_status.cons], constructors and destructor
    file_status() noexcept : file_status(file_type::none) {}
    explicit file_status(file_type ft,
                         perms prms = perms::unknown) noexcept;
    file_status(const file_status&) noexcept = default;
    file_status(file_status&&) noexcept = default;
    ~file_status();

    // assignments:
    file_status& operator=(const file_status&) noexcept = default;
    file_status& operator=(file_status&&) noexcept = default;

    // [fs.file_status.mods], modifiers
    void       type(file_type ft) noexcept;
    void       permissions(perms prms) noexcept;

    // [fs.file_status.obs], observers
    file_type  type() const noexcept;
    perms      permissions() const noexcept;
  };
}
An object of type file_­status stores information about the type and permissions of a file.

30.10.11.1 file_­status constructors [fs.file_status.cons]

explicit file_status(file_type ft, perms prms = perms::unknown) noexcept;
Postconditions: type() == ft and permissions() == prms.

30.10.11.2 file_­status observers [fs.file_status.obs]

file_type type() const noexcept;
Returns: The value of type() specified by the postconditions of the most recent call to a constructor, operator=, or type(file_­type) function.
perms permissions() const noexcept;
Returns: The value of permissions() specified by the postconditions of the most recent call to a constructor, operator=, or permissions(perms) function.

30.10.11.3 file_­status modifiers [fs.file_status.mods]

void type(file_type ft) noexcept;
Postconditions: type() == ft.
void permissions(perms prms) noexcept;
Postconditions: permissions() == prms.

30.10.12 Class directory_­entry [fs.class.directory_entry]

namespace std::filesystem {
  class directory_entry {
  public:
    // [fs.dir.entry.cons], constructors and destructor
    directory_entry() noexcept = default;
    directory_entry(const directory_entry&) = default;
    directory_entry(directory_entry&&) noexcept = default;
    explicit directory_entry(const path& p);
    directory_entry(const path& p, error_code& ec);
    ~directory_entry();

    // assignments:
    directory_entry& operator=(const directory_entry&) = default;
    directory_entry& operator=(directory_entry&&) noexcept = default;

    // [fs.dir.entry.mods], modifiers
    void assign(const path& p);
    void assign(const path& p, error_code& ec);
    void replace_filename(const path& p);
    void replace_filename(const path& p, error_code& ec);
    void refresh();
    void refresh(error_code& ec) noexcept;

    // [fs.dir.entry.obs], observers
    const path& path() const noexcept;
    operator const path&() const noexcept;
    bool exists() const;
    bool exists(error_code& ec) const noexcept;
    bool is_block_file() const;
    bool is_block_file(error_code& ec) const noexcept;
    bool is_character_file() const;
    bool is_character_file(error_code& ec) const noexcept;
    bool is_directory() const;
    bool is_directory(error_code& ec) const noexcept;
    bool is_fifo() const;
    bool is_fifo(error_code& ec) const noexcept;
    bool is_other() const;
    bool is_other(error_code& ec) const noexcept;
    bool is_regular_file() const;
    bool is_regular_file(error_code& ec) const noexcept;
    bool is_socket() const;
    bool is_socket(error_code& ec) const noexcept;
    bool is_symlink() const;
    bool is_symlink(error_code& ec) const noexcept;
    uintmax_t file_size() const;
    uintmax_t file_size(error_code& ec) const noexcept;
    uintmax_t hard_link_count() const;
    uintmax_t hard_link_count(error_code& ec) const noexcept;
    file_time_type last_write_time() const;
    file_time_type last_write_time(error_code& ec) const noexcept;
    file_status status() const;
    file_status status(error_code& ec) const noexcept;
    file_status symlink_status() const;
    file_status symlink_status(error_code& ec) const noexcept;

    bool operator< (const directory_entry& rhs) const noexcept;
    bool operator==(const directory_entry& rhs) const noexcept;
    bool operator!=(const directory_entry& rhs) const noexcept;
    bool operator<=(const directory_entry& rhs) const noexcept;
    bool operator> (const directory_entry& rhs) const noexcept;
    bool operator>=(const directory_entry& rhs) const noexcept;

  private:
    path pathobject;                 // exposition only
    friend class directory_iterator; // exposition only
  };
}
A directory_­entry object stores a path object and may store additional objects for file attributes such as hard link count, status, symlink status, file size, and last write time.
Implementations are encouraged to store such additional file attributes during directory iteration if their values are available and storing the values would allow the implementation to eliminate file system accesses by directory_­entry observer functions ([fs.op.funcs]).
Such stored file attribute values are said to be cached.
[Note
:
For purposes of exposition, class directory_­iterator ([fs.class.directory_iterator]) is shown above as a friend of class directory_­entry.
Friendship allows the directory_­iterator implementation to cache already available attribute values directly into a directory_­entry object without the cost of an unneeded call to refresh().
end note
]
[Example
:
using namespace std::filesystem;

// use possibly cached last write time to minimize disk accesses
for (auto&& x : directory_iterator("."))
{
  std::cout << x.path() << " " << x.last_write_time() << std::endl;
}

// call refresh() to refresh a stale cache
for (auto&& x : directory_iterator("."))
{
  lengthy_function(x.path());  // cache becomes stale
  x.refresh();
  std::cout << x.path() << " " << x.last_write_time() << std::endl;
}
On implementations that do not cache the last write time, both loops will result in a potentially expensive call to the std​::​filesystem​::​last_­write_­time function.
On implementations that do cache the last write time, the first loop will use the cached value and so will not result in a potentially expensive call to the std​::​filesystem​::​last_­write_­time function.
The code is portable to any implementation, regardless of whether or not it employs caching.
end example
]

30.10.12.1 directory_­entry constructors [fs.dir.entry.cons]

explicit directory_entry(const path& p); directory_entry(const path& p, error_code& ec);
Effects: Constructs an object of type directory_­entry, then refresh() or refresh(ec), respectively.
Postconditions: path() == p if no error occurs, otherwise path() == std​::​filesystem​::​path().
Throws: As specified in [fs.err.report].

30.10.12.2 directory_­entry modifiers [fs.dir.entry.mods]

void assign(const path& p); void assign(const path& p, error_code& ec);
Effects: Equivalent to pathobject = p, then refresh() or refresh(ec), respectively.
If an error occurs, the values of any cached attributes are unspecified.
Throws: As specified in [fs.err.report].
void replace_filename(const path& p); void replace_filename(const path& p, error_code& ec);
Effects: Equivalent to pathobject.replace_­filename(p), then refresh() or refresh(ec), respectively.
If an error occurs, the values of any cached attributes are unspecified.
Throws: As specified in [fs.err.report].
void refresh(); void refresh(error_code& ec) noexcept;
Effects: Stores the current values of any cached attributes of the file p resolves to.
If an error occurs, an error is reported ([fs.err.report]) and the values of any cached attributes are unspecified.
Throws: As specified in [fs.err.report].
[Note
:
Implementations of directory_­iterator ([fs.class.directory_iterator]) are prohibited from directly or indirectly calling the refresh function since it must access the external file system, and the objective of caching is to avoid unnecessary file system accesses.
end note
]

30.10.12.3 directory_­entry observers [fs.dir.entry.obs]

Unqualified function names in the Returns: elements of the directory_­entry observers described below refer to members of the std​::​filesystem namespace.
const path& path() const noexcept; operator const path&() const noexcept;
Returns: pathobject.
bool exists() const; bool exists(error_code& ec) const noexcept;
Returns: exists(this->status()) or exists(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_block_file() const; bool is_block_file(error_code& ec) const noexcept;
Returns: is_­block_­file(this->status()) or is_­block_­file(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_character_file() const; bool is_character_file(error_code& ec) const noexcept;
Returns: is_­character_­file(this->status()) or is_­character_­file(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_directory() const; bool is_directory(error_code& ec) const noexcept;
Returns: is_­directory(this->status()) or is_­directory(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_fifo() const; bool is_fifo(error_code& ec) const noexcept;
Returns: is_­fifo(this->status()) or is_­fifo(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_other() const; bool is_other(error_code& ec) const noexcept;
Returns: is_­other(this->status()) or is_­other(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_regular_file() const; bool is_regular_file(error_code& ec) const noexcept;
Returns: is_­regular_­file(this->status()) or is_­regular_­file(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_socket() const; bool is_socket(error_code& ec) const noexcept;
Returns: is_­socket(this->status()) or is_­socket(this->status(), ec), respectively.
Throws: As specified in [fs.err.report].
bool is_symlink() const; bool is_symlink(error_code& ec) const noexcept;
Returns: is_­symlink(this->symlink_­status()) or is_­symlink(this->symlink_­status(), ec), respectively.
Throws: As specified in [fs.err.report].
uintmax_t file_size() const; uintmax_t file_size(error_code& ec) const noexcept;
Returns: If cached, the file size attribute value.
Otherwise, file_­size(path()) or file_­size(path(), ec), respectively.
Throws: As specified in [fs.err.report].
uintmax_t hard_link_count() const; uintmax_t hard_link_count(error_code& ec) const noexcept;
Returns: If cached, the hard link count attribute value.
Otherwise, hard_­link_­count(path()) or hard_­link_­count(path(), ec), respectively.
Throws: As specified in [fs.err.report].
file_time_type last_write_time() const; file_time_type last_write_time(error_code& ec) const noexcept;
Returns: If cached, the last write time attribute value.
Otherwise, last_­write_­time(path()) or last_­write_­time(path(), ec), respectively.
Throws: As specified in [fs.err.report].
file_status status() const; file_status status(error_code& ec) const noexcept;
Returns: If cached, the status attribute value.
Otherwise, status(path()) or status(path(), ec), respectively.
Throws: As specified in [fs.err.report].
file_status symlink_status() const; file_status symlink_status(error_code& ec) const noexcept;
Returns: If cached, the symlink status attribute value.
Otherwise, symlink_­status(path()) or symlink_­status(path(), ec), respectively.
Throws: As specified in [fs.err.report].
bool operator==(const directory_entry& rhs) const noexcept;
Returns: pathobject == rhs.pathobject.
bool operator!=(const directory_entry& rhs) const noexcept;
Returns: pathobject != rhs.pathobject.
bool operator< (const directory_entry& rhs) const noexcept;
Returns: pathobject < rhs.pathobject.
bool operator<=(const directory_entry& rhs) const noexcept;
Returns: pathobject <= rhs.pathobject.
bool operator> (const directory_entry& rhs) const noexcept;
Returns: pathobject > rhs.pathobject.
bool operator>=(const directory_entry& rhs) const noexcept;
Returns: pathobject >= rhs.pathobject.

30.10.13 Class directory_­iterator [fs.class.directory_iterator]

An object of type directory_­iterator provides an iterator for a sequence of directory_­entry elements representing the path and any cached attribute values ([fs.class.directory_entry]) for each file in a directory or in an implementation-defined directory-like file type.
[Note
:
For iteration into sub-directories, see class recursive_­directory_­iterator ([fs.class.rec.dir.itr]).
end note
]
namespace std::filesystem {
  class directory_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = directory_entry;
    using difference_type   = ptrdiff_t;
    using pointer           = const directory_entry*;
    using reference         = const directory_entry&;

    // [fs.dir.itr.members], member functions
    directory_iterator() noexcept;
    explicit directory_iterator(const path& p);
    directory_iterator(const path& p, directory_options options);
    directory_iterator(const path& p, error_code& ec) noexcept;
    directory_iterator(const path& p, directory_options options,
                       error_code& ec) noexcept;
    directory_iterator(const directory_iterator& rhs);
    directory_iterator(directory_iterator&& rhs) noexcept;
    ~directory_iterator();

    directory_iterator& operator=(const directory_iterator& rhs);
    directory_iterator& operator=(directory_iterator&& rhs) noexcept;

    const directory_entry& operator*() const;
    const directory_entry* operator->() const;
    directory_iterator&    operator++();
    directory_iterator&    increment(error_code& ec) noexcept;

    // other members as required by [input.iterators], input iterators
  };
}
directory_­iterator satisfies the requirements of an input iterator ([input.iterators]).
If an iterator of type directory_­iterator reports an error or is advanced past the last directory element, that iterator shall become equal to the end iterator value.
The directory_­iterator default constructor shall create an iterator equal to the end iterator value, and this shall be the only valid iterator for the end condition.
The end iterator is not dereferenceable.
Two end iterators are always equal.
An end iterator shall not be equal to a non-end iterator.
The result of calling the path() member of the directory_­entry object obtained by dereferencing a directory_­iterator is a reference to a path object composed of the directory argument from which the iterator was constructed with filename of the directory entry appended as if by operator/=.
Directory iteration shall not yield directory entries for the current (dot) and parent (dot-dot) directories.
The order of directory entries obtained by dereferencing successive increments of a directory_­iterator is unspecified.
Constructors and non-const directory_­iterator member functions store the values of any cached attributes ([fs.class.directory_entry]) in the directory_­entry element returned by operator*().
directory_­iterator member functions shall not directly or indirectly call any directory_­entry refresh function.
[Note
:
The exact mechanism for storing cached attribute values is not exposed to users.
For exposition, class directory_­iterator is shown in [fs.class.directory_entry] as a friend of class directory_­entry.
end note
]
[Note
:
Programs performing directory iteration may wish to test if the path obtained by dereferencing a directory iterator actually exists.
It could be a symbolic link to a non-existent file.
Programs recursively walking directory trees for purposes of removing and renaming entries may wish to avoid following symbolic links.
end note
]
[Note
:
If a file is removed from or added to a directory after the construction of a directory_­iterator for the directory, it is unspecified whether or not subsequently incrementing the iterator will ever result in an iterator referencing the removed or added directory entry.
See POSIX readdir_­r.
end note
]

30.10.13.1 directory_­iterator members [fs.dir.itr.members]

directory_iterator() noexcept;
Effects: Constructs the end iterator.
explicit directory_iterator(const path& p); directory_iterator(const path& p, directory_options options); directory_iterator(const path& p, error_code& ec) noexcept; directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
Effects: For the directory that p resolves to, constructs an iterator for the first element in a sequence of directory_­entry elements representing the files in the directory, if any; otherwise the end iterator.
However, if
(options & directory_options::skip_permission_denied) != directory_options::none
and construction encounters an error indicating that permission to access p is denied, constructs the end iterator and does not report an error.
Throws: As specified in [fs.err.report].
[Note
:
To iterate over the current directory, use directory_­iterator(".") rather than directory_­iterator("").
end note
]
directory_iterator(const directory_iterator& rhs); directory_iterator(directory_iterator&& rhs) noexcept;
Effects: Constructs an object of class directory_­iterator.
Postconditions: *this has the original value of rhs.
directory_iterator& operator=(const directory_iterator& rhs); directory_iterator& operator=(directory_iterator&& rhs) noexcept;
Effects: If *this and rhs are the same object, the member has no effect.
Postconditions: *this has the original value of rhs.
Returns: *this.
directory_iterator& operator++(); directory_iterator& increment(error_code& ec) noexcept;
Effects: As specified for the prefix increment operation of Input iterators ([input.iterators]).
Returns: *this.
Throws: As specified in [fs.err.report].

30.10.13.2 directory_­iterator non-member functions [fs.dir.itr.nonmembers]

These functions enable range access for directory_­iterator.
directory_iterator begin(directory_iterator iter) noexcept;
Returns: iter.
directory_iterator end(const directory_iterator&) noexcept;
Returns: directory_­iterator().

30.10.14 Class recursive_­directory_­iterator [fs.class.rec.dir.itr]

An object of type recursive_­directory_­iterator provides an iterator for a sequence of directory_­entry elements representing the files in a directory or in an implementation-defined directory-like file type, and its sub-directories.
namespace std::filesystem {
  class recursive_directory_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = directory_entry;
    using difference_type   = ptrdiff_t;
    using pointer           = const directory_entry*;
    using reference         = const directory_entry&;

    // [fs.rec.dir.itr.members], constructors and destructor
    recursive_directory_iterator() noexcept;
    explicit recursive_directory_iterator(const path& p);
    recursive_directory_iterator(const path& p, directory_options options);
    recursive_directory_iterator(const path& p, directory_options options,
                                 error_code& ec) noexcept;
    recursive_directory_iterator(const path& p, error_code& ec) noexcept;
    recursive_directory_iterator(const recursive_directory_iterator& rhs);
    recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
    ~recursive_directory_iterator();

    // [fs.rec.dir.itr.members], observers
    directory_options  options() const;
    int                depth() const;
    bool               recursion_pending() const;

    const directory_entry& operator*() const;
    const directory_entry* operator->() const;

    // [fs.rec.dir.itr.members], modifiers
    recursive_directory_iterator&
      operator=(const recursive_directory_iterator& rhs);
    recursive_directory_iterator&
      operator=(recursive_directory_iterator&& rhs) noexcept;

    recursive_directory_iterator& operator++();
    recursive_directory_iterator& increment(error_code& ec) noexcept;

    void pop();
    void pop(error_code& ec);
    void disable_recursion_pending();

    // other members as required by [input.iterators], input iterators
  };
}
Calling options, depth, recursion_­pending, pop or disable_­recursion_­pending on an iterator that is not dereferenceable results in undefined behavior.
The behavior of a recursive_­directory_­iterator is the same as a directory_­iterator unless otherwise specified.
[Note
:
If the directory structure being iterated over contains cycles then the end iterator may be unreachable.
end note
]

30.10.14.1 recursive_­directory_­iterator members [fs.rec.dir.itr.members]

recursive_directory_iterator() noexcept;
Effects: Constructs the end iterator.
explicit recursive_directory_iterator(const path& p); recursive_directory_iterator(const path& p, directory_options options); recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept; recursive_directory_iterator(const path& p, error_code& ec) noexcept;
Effects: Constructs a iterator representing the first entry in the directory p resolves to, if any; otherwise, the end iterator.
However, if
(options & directory_options::skip_permission_denied) != directory_options::none
and construction encounters an error indicating that permission to access p is denied, constructs the end iterator and does not report an error.
Postconditions: options() == options for the signatures with a directory_­options argument, otherwise options() == directory_­options​::​none.
Throws: As specified in [fs.err.report].
[Note
:
To iterate over the current directory, use recursive_­directory_­iterator(".") rather than recursive_­directory_­iterator("").
end note
]
[Note
:
By default, recursive_­directory_­iterator does not follow directory symlinks.
To follow directory symlinks, specify options as directory_­options​::​follow_­directory_­symlink
end note
]
recursive_directory_iterator(const recursive_directory_iterator& rhs);
Effects: Constructs an object of class recursive_­directory_­iterator.
Postconditions:
  • options() == rhs.options()
  • depth() == rhs.depth()
  • recursion_­pending() == rhs.recursion_­pending()
recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept;
Effects: Constructs an object of class recursive_­directory_­iterator.
Postconditions: options(), depth(), and recursion_­pending() have the values that rhs.options(), rhs.depth(), and rhs.recursion_­pending(), respectively, had before the function call.
recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs);
Effects: If *this and rhs are the same object, the member has no effect.
Postconditions:
  • options() == rhs.options()
  • depth() == rhs.depth()
  • recursion_­pending() == rhs.recursion_­pending()
Returns: *this.
recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept;
Effects: If *this and rhs are the same object, the member has no effect.
Postconditions: options(), depth(), and recursion_­pending() have the values that rhs.options(), rhs.depth(), and rhs.recursion_­pending(), respectively, had before the function call.
Returns: *this.
directory_options options() const;
Returns: The value of the argument passed to the constructor for the options parameter, if present, otherwise directory_­options​::​none.
Throws: Nothing.
int depth() const;
Returns: The current depth of the directory tree being traversed.
[Note
:
The initial directory is depth 0, its immediate subdirectories are depth 1, and so forth.
end note
]
Throws: Nothing.
bool recursion_pending() const;
Returns: true if disable_­recursion_­pending() has not been called subsequent to the prior construction or increment operation, otherwise false.
Throws: Nothing.
recursive_directory_iterator& operator++(); recursive_directory_iterator& increment(error_code& ec) noexcept;
Effects: As specified for the prefix increment operation of Input iterators ([input.iterators]), except that:
  • If there are no more entries at the current depth, then if depth() != 0 iteration over the parent directory resumes; otherwise *this = recursive_­directory_­iterator().
  • Otherwise if
    recursion_pending() && is_directory((*this)->status()) &&
    (!is_symlink((*this)->symlink_status()) ||
     (options() & directory_options::follow_directory_symlink) != directory_options::none)
    then either directory (*this)->path() is recursively iterated into or, if
    (options() & directory_options::skip_permission_denied) != directory_options::none
    and an error occurs indicating that permission to access directory (*this)->path() is denied, then directory (*this)->path() is treated as an empty directory and no error is reported.
Returns: *this.
Throws: As specified in [fs.err.report].
void pop(); void pop(error_code& ec);
Effects: If depth() == 0, set *this to recursive_­directory_­iterator().
Otherwise, cease iteration of the directory currently being iterated over, and continue iteration over the parent directory.
Throws: As specified in [fs.err.report].
void disable_recursion_pending();
Postconditions: recursion_­pending() == false.
[Note
:
disable_­recursion_­pending() is used to prevent unwanted recursion into a directory.
end note
]

30.10.14.2 recursive_­directory_­iterator non-member functions [fs.rec.dir.itr.nonmembers]

These functions enable use of recursive_­directory_­iterator with range-based for statements.
recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
Returns: iter.
recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
Returns: recursive_­directory_­iterator().

30.10.15 Filesystem operation functions [fs.op.funcs]

Filesystem operation functions query or modify files, including directories, in external storage.
[Note
:
Because hardware failures, network failures, file system races ([fs.def.race]), and many other kinds of errors occur frequently in file system operations, users should be aware that any filesystem operation function, no matter how apparently innocuous, may encounter an error; see [fs.err.report].
end note
]

30.10.15.1 Absolute [fs.op.absolute]

path absolute(const path& p); path absolute(const path& p, error_code& ec);
Effects: Composes an absolute path referencing the same file system location as p according to the operating system ([fs.conform.os]).
Returns: The composed path.
The signature with argument ec returns path() if an error occurs.
[Note
:
For the returned path, rp, rp.is_­absolute() is true unless an error occurs.
end note
]
Throws: As specified in [fs.err.report].
[Note
:
To resolve symlinks, or perform other sanitization which might require queries to secondary storage, such as hard disks, consider canonical ([fs.op.canonical]).
end note
]
[Note
:
Implementations are strongly encouraged to not query secondary storage, and not consider !exists(p) an error.
end note
]
[Example
:
For POSIX-based operating systems, absolute(p) is simply current_­path()/p.
For Windows-based operating systems, absolute might have the same semantics as GetFullPathNameW.
end example
]

30.10.15.2 Canonical [fs.op.canonical]

path canonical(const path& p, const path& base = current_path()); path canonical(const path& p, error_code& ec); path canonical(const path& p, const path& base, error_code& ec);
Effects: Converts p, which must exist, to an absolute path that has no symbolic link, dot, or dot-dot elements in its pathname in the generic format.
Returns: A path that refers to the same file system object as absolute(p, base).
For the overload without a base argument, base is current_­path().
Signatures with argument ec return path() if an error occurs.
Throws: As specified in [fs.err.report].
Remarks: !exists(p) is an error.

30.10.15.3 Copy [fs.op.copy]

void copy(const path& from, const path& to);
Effects: Equivalent to copy(from, to, copy_­options​::​none).
void copy(const path& from, const path& to, error_code& ec) noexcept;
Effects: Equivalent to copy(from, to, copy_­options​::​none, ec).
void copy(const path& from, const path& to, copy_options options); void copy(const path& from, const path& to, copy_options options, error_code& ec) noexcept;
Requires: At most one element from each option group ([fs.enum.copy.opts]) is set in options.
Effects: Before the first use of f and t:
  • If
    (options & copy_options::create_symlinks) != copy_options::none ||
    (options & copy_options::skip_symlinks) != copy_options::none
    then auto f = symlink_­status(from) and if needed auto t = symlink_­status(to).
  • Otherwise, if
    (options & copy_options::copy_symlinks) != copy_options::none
    then auto f = symlink_­status(from) and if needed auto t = status(to).
  • Otherwise, auto f = status(from) and if needed auto t = status(to).
Effects are then as follows:
  • If f.type() or t.type() is an implementation-defined file type ([fs.enum.file_type]), then the effects are implementation-defined.
  • Otherwise, an error is reported as specified in [fs.err.report] if:
  • Otherwise, if is_­symlink(f), then:
    • If (options & copy_­options​::​skip_­symlinks) != copy_­options​::​none then return.
    • Otherwise if
      !exists(t) && (options & copy_options::copy_symlinks) != copy_options::none
      then copy_­symlink(from, to).
    • Otherwise report an error as specified in [fs.err.report].
  • Otherwise, if is_­regular_­file(f), then:
    • If (options & copy_­options​::​directories_­only) != copy_­options​::​none, then return.
    • Otherwise, if (options & copy_­options​::​create_­symlinks) != copy_­options​::​none, then create a symbolic link to the source file.
    • Otherwise, if (options & copy_­options​::​create_­hard_­links) != copy_­options​::​none, then create a hard link to the source file.
    • Otherwise, if is_­directory(t), then copy_­file(from, to/from.filename(), options).
    • Otherwise, copy_­file(from, to, options).
  • Otherwise, if
    is_directory(f) &&
    ((options & copy_options::recursive) != copy_options::none ||
     options == copy_options::none)
    then:
    • If !exists(t), then create_­directory(to, from).
    • Then, iterate over the files in from, as if by
      for (const directory_entry& x : directory_iterator(from))
        copy(x.path(), to/x.path().filename(), options | copy_options::unspecified)
  • Otherwise, for the signature with argument ec, ec.clear().
  • Otherwise, no effects.
Throws: As specified in [fs.err.report].
Remarks: For the signature with argument ec, any library functions called by the implementation shall have an error_­code argument if applicable.
[Example
:
Given this directory structure:
/dir1
  file1
  file2
  dir2
    file3
Calling copy("/dir1", "/dir3") would result in:
/dir1
  file1
  file2
  dir2
    file3
/dir3
  file1
  file2
Alternatively, calling copy("/dir1", "/dir3", copy_­options​::​recursive) would result in:
/dir1
  file1
  file2
  dir2
    file3
/dir3
  file1
  file2
  dir2
    file3
end example
]

30.10.15.4 Copy file [fs.op.copy_file]

bool copy_file(const path& from, const path& to); bool copy_file(const path& from, const path& to, error_code& ec) noexcept;
Returns: copy_­file(from, to, copy_­options​::​none) or
copy_­file(from, to, copy_­options​::​none, ec), respectively.
Throws: As specified in [fs.err.report].
bool copy_file(const path& from, const path& to, copy_options options); bool copy_file(const path& from, const path& to, copy_options options, error_code& ec) noexcept;
Requires: At most one element from each option group ([fs.enum.copy.opts]) is set in options.
Effects: As follows:
  • Report a file already exists error as specified in [fs.err.report] if:
    • !is_­regular_­file(from), or
    • exists(to) and !is_­regular_­file(to), or
    • exists(to) and equivalent(from, to), or
    • exists(to) and
      (options & (copy_options::skip_existing |
                  copy_options::overwrite_existing |
                  copy_options::update_existing)) == copy_options::none
  • Otherwise, copy the contents and attributes of the file from resolves to, to the file to resolves to, if:
    • !exists(to), or
    • (options & copy_­options​::​overwrite_­existing) != copy_­options​::​none, or
    • (options & copy_­options​::​update_­existing) != copy_­options​::​none and from is more recent than to, determined as if by use of the last_­write_­time function ([fs.op.last_write_time]).
  • Otherwise, no effects.
Returns: true if the from file was copied, otherwise false.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].
Complexity: At most one direct or indirect invocation of status(to).

30.10.15.6 Create directories [fs.op.create_directories]

bool create_directories(const path& p); bool create_directories(const path& p, error_code& ec) noexcept;
Effects: Establishes the postcondition by calling create_­directory() for any element of p that does not exist.
Postconditions: is_­directory(p).
Returns: true if a new directory was created, otherwise false.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].
Complexity: where n is the number of elements of p that do not exist.

30.10.15.7 Create directory [fs.op.create_directory]

bool create_directory(const path& p); bool create_directory(const path& p, error_code& ec) noexcept;
Effects: Establishes the postcondition by attempting to create the directory p resolves to, as if by POSIX mkdir() with a second argument of static_­cast<int>(perms​::​all).
Creation failure because p resolves to an existing directory shall not be treated as an error.
Postconditions: is_­directory(p).
Returns: true if a new directory was created, otherwise false.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].
bool create_directory(const path& p, const path& existing_p); bool create_directory(const path& p, const path& existing_p, error_code& ec) noexcept;
Effects: Establishes the postcondition by attempting to create the directory p resolves to, with attributes copied from directory existing_­p.
The set of attributes copied is operating system dependent.
Creation failure because p resolves to an existing directory shall not be treated as an error.
[Note
:
For POSIX-based operating systems, the attributes are those copied by native API stat(existing_­p.c_­str(), &attributes_­stat) followed by mkdir(p.c_­str(), attributes_­stat.st_­mode).
For Windows-based operating systems, the attributes are those copied by native API CreateDirectoryExW(existing_­p.c_­str(), p.c_­str(), 0).
end note
]
Postconditions: is_­directory(p).
Returns: true if a new directory was created, otherwise false.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.8 Create directory symlink [fs.op.create_dir_symlk]

void create_directory_symlink(const path& to, const path& new_symlink); void create_directory_symlink(const path& to, const path& new_symlink, error_code& ec) noexcept;
Effects: Establishes the postcondition, as if by POSIX symlink().
Postconditions: new_­symlink resolves to a symbolic link file that contains an unspecified representation of to.
Throws: As specified in [fs.err.report].
[Note
:
Some operating systems require symlink creation to identify that the link is to a directory.
Portable code should use create_­directory_­symlink() to create directory symlinks rather than create_­symlink()
end note
]
[Note
:
Some operating systems do not support symbolic links at all or support them only for regular files.
Some file systems (such as the FAT file system) do not support symbolic links regardless of the operating system.
end note
]

30.10.15.9 Create hard link [fs.op.create_hard_lk]

void create_hard_link(const path& to, const path& new_hard_link); void create_hard_link(const path& to, const path& new_hard_link, error_code& ec) noexcept;
Effects: Establishes the postcondition, as if by POSIX link().
Postconditions:
  • exists(to) && exists(new_­hard_­link) && equivalent(to, new_­hard_­link)
  • The contents of the file or directory to resolves to are unchanged.
Throws: As specified in [fs.err.report].
[Note
:
Some operating systems do not support hard links at all or support them only for regular files.
Some file systems (such as the FAT file system) do not support hard links regardless of the operating system.
Some file systems limit the number of links per file.
end note
]

30.10.15.11 Current path [fs.op.current_path]

path current_path(); path current_path(error_code& ec);
Returns: The absolute path of the current working directory, whose pathname in the native format is obtained as if by POSIX getcwd().
The signature with argument ec returns path() if an error occurs.
Throws: As specified in [fs.err.report].
Remarks: The current working directory is the directory, associated with the process, that is used as the starting location in pathname resolution for relative paths.
[Note
:
The current_­path() name was chosen to emphasize that the returned value is a path, not just a single directory name.
end note
]
[Note
:
The current path as returned by many operating systems is a dangerous global variable.
It may be changed unexpectedly by a third-party or system library functions, or by another thread.
end note
]
void current_path(const path& p); void current_path(const path& p, error_code& ec) noexcept;
Effects: Establishes the postcondition, as if by POSIX chdir().
Postconditions: equivalent(p, current_­path()).
Throws: As specified in [fs.err.report].
[Note
:
The current path for many operating systems is a dangerous global state.
It may be changed unexpectedly by a third-party or system library functions, or by another thread.
end note
]

30.10.15.12 Equivalent [fs.op.equivalent]

bool equivalent(const path& p1, const path& p2); bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept;
Let s1 and s2 be file_­statuss, determined as if by status(p1) and status(p2), respectively.
Effects: Determines s1 and s2.
If (!exists(s1) && !exists(s2)) || (is_­other(s1) && is_­other(s2)) an error is reported ([fs.err.report]).
Returns: true, if s1 == s2 and p1 and p2 resolve to the same file system entity, else false.
The signature with argument ec returns false if an error occurs.
Two paths are considered to resolve to the same file system entity if two candidate entities reside on the same device at the same location.
This is determined as if by the values of the POSIX stat structure, obtained as if by stat() for the two paths, having equal st_­dev values and equal st_­ino values.
Throws: As specified in [fs.err.report].

30.10.15.13 Exists [fs.op.exists]

bool exists(file_status s) noexcept;
Returns: status_­known(s) && s.type() != file_­type​::​not_­found.
bool exists(const path& p); bool exists(const path& p, error_code& ec) noexcept;
Let s be a file_­status, determined as if by status(p) or status(p, ec), respectively.
Effects: The signature with argument ec calls ec.clear() if status_­known(s).
Returns: exists(s).
Throws: As specified in [fs.err.report].

30.10.15.14 File size [fs.op.file_size]

uintmax_t file_size(const path& p); uintmax_t file_size(const path& p, error_code& ec) noexcept;
Returns:
  • If !exists(p) an error is reported ([fs.err.report]).
  • Otherwise, if is_­regular_­file(p), the size in bytes of the file p resolves to, determined as if by the value of the POSIX stat structure member st_­size obtained as if by POSIX stat().
  • Otherwise, the result is implementation-defined.
The signature with argument ec returns static_­cast<uintmax_­t>(-1) if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.15 Hard link count [fs.op.hard_lk_ct]

uintmax_t hard_link_count(const path& p); uintmax_t hard_link_count(const path& p, error_code& ec) noexcept;
Returns: The number of hard links for p.
The signature with argument ec returns static_­cast<uintmax_­t>(-1) if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.16 Is block file [fs.op.is_block_file]

bool is_block_file(file_status s) noexcept;
Returns: s.type() == file_­type​::​block.
bool is_block_file(const path& p); bool is_block_file(const path& p, error_code& ec) noexcept;
Returns: is_­block_­file(status(p)) or is_­block_­file(status(p, ec)), respectively.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.17 Is character file [fs.op.is_char_file]

bool is_character_file(file_status s) noexcept;
Returns: s.type() == file_­type​::​character.
bool is_character_file(const path& p); bool is_character_file(const path& p, error_code& ec) noexcept;
Returns: is_­character_­file(status(p)) or is_­character_­file(status(p, ec)), respectively.

The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.18 Is directory [fs.op.is_directory]

bool is_directory(file_status s) noexcept;
Returns: s.type() == file_­type​::​directory.
bool is_directory(const path& p); bool is_directory(const path& p, error_code& ec) noexcept;
Returns: is_­directory(status(p)) or is_­directory(status(p, ec)), respectively.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.19 Is empty [fs.op.is_empty]

bool is_empty(const path& p); bool is_empty(const path& p, error_code& ec) noexcept;
Effects:
  • Determine file_­status s, as if by status(p) or status(p, ec), respectively.
  • For the signature with argument ec, return false if an error occurred.
  • Otherwise, if is_­directory(s):
    • Create a variable itr, as if by directory_­iterator itr(p) or directory_­iterator itr(p, ec), respectively.
    • For the signature with argument ec, return false if an error occurred.
    • Otherwise, return itr == directory_­iterator().
  • Otherwise:
    • Determine uintmax_­t sz, as if by file_­size(p) or file_­size(p, ec), respectively.
    • For the signature with argument ec, return false if an error occurred.
    • Otherwise, return sz == 0.
Throws: As specified in [fs.err.report].

30.10.15.20 Is fifo [fs.op.is_fifo]

bool is_fifo(file_status s) noexcept;
Returns: s.type() == file_­type​::​fifo.
bool is_fifo(const path& p); bool is_fifo(const path& p, error_code& ec) noexcept;
Returns: is_­fifo(status(p)) or is_­fifo(status(p, ec)), respectively.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.21 Is other [fs.op.is_other]

bool is_other(file_status s) noexcept;
Returns: exists(s) && !is_­regular_­file(s) && !is_­directory(s) && !is_­symlink(s).
bool is_other(const path& p); bool is_other(const path& p, error_code& ec) noexcept;
Returns: is_­other(status(p)) or is_­other(status(p, ec)), respectively.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.22 Is regular file [fs.op.is_regular_file]

bool is_regular_file(file_status s) noexcept;
Returns: s.type() == file_­type​::​regular.
bool is_regular_file(const path& p);
Returns: is_­regular_­file(status(p)).
Throws: filesystem_­error if status(p) would throw filesystem_­error.
bool is_regular_file(const path& p, error_code& ec) noexcept;
Effects: Sets ec as if by status(p, ec).
[Note
:
file_­type​::​none, file_­type​::​not_­found and file_­type​::​unknown cases set ec to error values.
To distinguish between cases, call the status function directly.
end note
]
Returns: is_­regular_­file(status(p, ec)).
Returns false if an error occurs.

30.10.15.23 Is socket [fs.op.is_socket]

bool is_socket(file_status s) noexcept;
Returns: s.type() == file_­type​::​socket.
bool is_socket(const path& p); bool is_socket(const path& p, error_code& ec) noexcept;
Returns: is_­socket(status(p)) or is_­socket(status(p, ec)), respectively.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.25 Last write time [fs.op.last_write_time]

file_time_type last_write_time(const path& p); file_time_type last_write_time(const path& p, error_code& ec) noexcept;
Returns: The time of last data modification of p, determined as if by the value of the POSIX stat structure member st_­mtime obtained as if by POSIX stat().
The signature with argument ec returns file_­time_­type​::​min() if an error occurs.
Throws: As specified in [fs.err.report].
void last_write_time(const path& p, file_time_type new_time); void last_write_time(const path& p, file_time_type new_time, error_code& ec) noexcept;
Effects: Sets the time of last data modification of the file resolved to by p to new_­time, as if by POSIX futimens().
Throws: As specified in [fs.err.report].
[Note
:
A postcondition of last_­write_­time(p) == new_­time is not specified since it might not hold for file systems with coarse time granularity.
end note
]

30.10.15.26 Permissions [fs.op.permissions]

void permissions(const path& p, perms prms, perm_options opts=perm_options::replace); void permissions(const path& p, perms prms, error_code& ec) noexcept; void permissions(const path& p, perms prms, perm_options opts, error_code& ec);
Requires: Exactly one of the perm_­options constants replace, add, or remove is present in opts.
Remarks: The second signature behaves as if it had an additional parameter perm_­options opts with an argument of perm_­options​::​replace.
Effects: Applies the action specified by opts to the file p resolves to, or to file p itself if p is a symbolic link and perm_­options​::​nofollow is set in opts.
The action is applied as if by POSIX fchmodat().
[Note
:
Conceptually permissions are viewed as bits, but the actual implementation may use some other mechanism.
end note
]
Throws: As specified in [fs.err.report].

30.10.15.27 Proximate [fs.op.proximate]

path proximate(const path& p, error_code& ec);
Returns: proximate(p, current_­path(), ec).
Throws: As specified in [fs.err.report].
path proximate(const path& p, const path& base = current_path()); path proximate(const path& p, const path& base, error_code& ec);
Returns: For the first form:
weakly_canonical(p).lexically_proximate(weakly_canonical(base));
For the second form:
weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec));
or path() at the first error occurrence, if any.
Throws: As specified in [fs.err.report].

30.10.15.29 Relative [fs.op.relative]

path relative(const path& p, error_code& ec);
Returns: relative(p, current_­path(), ec).
Throws: As specified in [fs.err.report].
path relative(const path& p, const path& base = current_path()); path relative(const path& p, const path& base, error_code& ec);
Returns: For the first form:
weakly_canonical(p).lexically_relative(weakly_canonical(base));
For the second form:
weakly_canonical(p, ec).lexically_relative(weakly_canonical(base, ec));
or path() at the first error occurrence, if any.
Throws: As specified in [fs.err.report].

30.10.15.30 Remove [fs.op.remove]

bool remove(const path& p); bool remove(const path& p, error_code& ec) noexcept;
Effects: If exists(symlink_­status(p, ec)), the file p is removed as if by POSIX remove().
[Note
:
A symbolic link is itself removed, rather than the file it resolves to.
end note
]
Postconditions: !exists(symlink_­status(p)).
Returns: false if p did not exist, otherwise true.
The signature with argument ec returns false if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.31 Remove all [fs.op.remove_all]

uintmax_t remove_all(const path& p); uintmax_t remove_all(const path& p, error_code& ec) noexcept;
Effects: Recursively deletes the contents of p if it exists, then deletes file p itself, as if by POSIX remove().
[Note
:
A symbolic link is itself removed, rather than the file it resolves to.
end note
]
Postconditions: !exists(symlink_­status(p)).
Returns: The number of files removed.
The signature with argument ec returns static_­cast< uintmax_­t>(-1) if an error occurs.
Throws: As specified in [fs.err.report].

30.10.15.32 Rename [fs.op.rename]

void rename(const path& old_p, const path& new_p); void rename(const path& old_p, const path& new_p, error_code& ec) noexcept;
Effects: Renames old_­p to new_­p, as if by POSIX rename().
[Note
:
  • If old_­p and new_­p resolve to the same existing file, no action is taken.
  • Otherwise, the rename may include the following effects:
    • if new_­p resolves to an existing non-directory file, new_­p is removed; otherwise,
    • if new_­p resolves to an existing directory, new_­p is removed if empty on POSIX compliant operating systems but may be an error on other operating systems.
A symbolic link is itself renamed, rather than the file it resolves to.
end note
]
Throws: As specified in [fs.err.report].

30.10.15.33 Resize file [fs.op.resize_file]

void resize_file(const path& p, uintmax_t new_size); void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
Postconditions: file_­size(p) == new_­size.
Throws: As specified in [fs.err.report].
Remarks: Achieves its postconditions as if by POSIX truncate().

30.10.15.34 Space [fs.op.space]

space_info space(const path& p); space_info space(const path& p, error_code& ec) noexcept;
Returns: An object of type space_­info.
The value of the space_­info object is determined as if by using POSIX statvfs to obtain a POSIX struct statvfs, and then multiplying its f_­blocks, f_­bfree, and f_­bavail members by its f_­frsize member, and assigning the results to the capacity, free, and available members respectively.
Any members for which the value cannot be determined shall be set to static_­cast<uintmax_­t>(-1).
For the signature with argument ec, all members are set to static_­cast<uintmax_­t>(-1) if an error occurs.
Throws: As specified in [fs.err.report].
Remarks: The value of member space_­info​::​available is operating system dependent.
[Note
:
available may be less than free.
end note
]

30.10.15.35 Status [fs.op.status]

file_status status(const path& p);
Effects: As if:
error_code ec;
file_status result = status(p, ec);
if (result.type() == file_type::none)
  throw filesystem_error(implementation-supplied-message, p, ec);
return result;
Returns: See above.
Throws: filesystem_­error.
[Note
:
result values of file_­status(file_­type​::​not_­found) and file_­status(file_­type​::​unknown) are not considered failures and do not cause an exception to be thrown.
end note
]
file_status status(const path& p, error_code& ec) noexcept;
Effects: If possible, determines the attributes of the file p resolves to, as if by using POSIX stat() to obtain a POSIX struct stat.
If, during attribute determination, the underlying file system API reports an error, sets ec to indicate the specific error reported.
Otherwise, ec.clear().
[Note
:
This allows users to inspect the specifics of underlying API errors even when the value returned by status() is not file_­status(file_­type​::​none).
end note
]
Let prms denote the result of (m & perms​::​mask), where m is determined as if by converting the st_­mode member of the obtained struct stat to the type perms.
Returns:
  • If ec != error_­code():
    • If the specific error indicates that p cannot be resolved because some element of the path does not exist, returns file_­status(file_­type​::​not_­found).
    • Otherwise, if the specific error indicates that p can be resolved but the attributes cannot be determined, returns file_­status(file_­type​::​unknown).
    • Otherwise, returns file_­status(file_­type​::​none).
    [Note
    :
    These semantics distinguish between p being known not to exist, p existing but not being able to determine its attributes, and there being an error that prevents even knowing if p exists.
    These distinctions are important to some use cases.
    end note
    ]
  • Otherwise,
    • If the attributes indicate a regular file, as if by POSIX S_­ISREG, returns file_­status(file_­type​::​regular, prms).
      [Note
      :
      file_­type​::​regular implies appropriate <fstream> operations would succeed, assuming no hardware, permission, access, or file system race errors.
      Lack of file_­type​::​regular does not necessarily imply <fstream> operations would fail on a directory.
      end note
      ]
    • Otherwise, if the attributes indicate a directory, as if by POSIX S_­ISDIR, returns file_­status(file_­type​::​directory, prms).
      [Note
      :
      file_­type​::​directory implies that calling directory_­iterator(p) would succeed.
      end note
      ]
    • Otherwise, if the attributes indicate a block special file, as if by POSIX S_­ISBLK, returns file_­status(file_­type​::​block, prms).
    • Otherwise, if the attributes indicate a character special file, as if by POSIX S_­ISCHR, returns file_­status(file_­type​::​character, prms).
    • Otherwise, if the attributes indicate a fifo or pipe file, as if by POSIX S_­ISFIFO, returns file_­status(file_­type​::​fifo, prms).
    • Otherwise, if the attributes indicate a socket, as if by POSIX S_­ISSOCK, returns file_­status(file_­type​::​socket, prms).
    • Otherwise, if the attributes indicate an implementation-defined file type ([fs.enum.file_type]), returns file_­status(file_­type​::​A, prms), where A is the constant for the implementation-defined file type.
    • Otherwise, returns file_­status(file_­type​::​unknown, prms).
Remarks: If a symbolic link is encountered during pathname resolution, pathname resolution continues using the contents of the symbolic link.

30.10.15.36 Status known [fs.op.status_known]

bool status_known(file_status s) noexcept;
Returns: s.type() != file_­type​::​none.

30.10.15.38 Temporary directory path [fs.op.temp_dir_path]

path temp_directory_path(); path temp_directory_path(error_code& ec);
Returns: An unspecifed directory path suitable for temporary files.
An error shall be reported if !exists(p) || !is_­directory(p), where p is the path to be returned.
The signature with argument ec returns path() if an error occurs.
Throws: As specified in [fs.err.report].
[Example
:
For POSIX-based operating systems, an implementation might return the path supplied by the first environment variable found in the list TMPDIR, TMP, TEMP, TEMPDIR, or if none of these are found, "/tmp".
For Windows-based operating systems, an implementation might return the path reported by the Windows GetTempPath API function.
end example
]

30.10.15.39 Weakly canonical [fs.op.weakly_canonical]

path weakly_canonical(const path& p); path weakly_canonical(const path& p, error_code& ec);
Returns: p with symlinks resolved and the result normalized ([fs.def.normal.form]).
Effects: Using status(p) or status(p, ec), respectively, to determine existence, return a path composed by operator/= from the result of calling canonical() without a base argument and with a path argument composed of the leading elements of p that exist, if any, followed by the elements of p that do not exist, if any.
For the first form, canonical() is called without an error_­code argument.
For the second form, canonical() is called with ec as an error_­code argument, and path() is returned at the first error occurrence, if any.
Postconditions: The returned path is in normal form ([fs.def.normal.form]).
Remarks: Implementations are encouraged to avoid unnecessary normalization such as when canonical has already been called on the entirety of p.
Throws: As specified in [fs.err.report].

30.11 C library files [c.files]

30.11.1 Header <cstdio> synopsis [cstdio.syn]

namespace std {
  using size_t = see [support.types.layout];
  using FILE = see below;
  using fpos_t = see below;
}

#define NULL see [support.types.nullptr]
#define _IOFBF see below
#define _IOLBF see below
#define _IONBF see below
#define BUFSIZ see below
#define EOF see below
#define FOPEN_MAX see below
#define FILENAME_MAX see below
#define L_tmpnam see below
#define SEEK_CUR see below
#define SEEK_END see below
#define SEEK_SET see below
#define TMP_MAX see below
#define stderr see below
#define stdin see below
#define stdout see below

namespace std {
  int remove(const char* filename);
  int rename(const char* old, const char* new);
  FILE* tmpfile();
  char* tmpnam(char* s);
  int fclose(FILE* stream);
  int fflush(FILE* stream);
  FILE* fopen(const char* filename, const char* mode);
  FILE* freopen(const char* filename, const char* mode, FILE* stream);
  void setbuf(FILE* stream, char* buf);
  int setvbuf(FILE* stream, char* buf, int mode, size_t size);
  int fprintf(FILE* stream, const char* format, ...);
  int fscanf(FILE* stream, const char* format, ...);
  int printf(const char* format, ...);
  int scanf(const char* format, ...);
  int snprintf(char* s, size_t n, const char* format, ...);
  int sprintf(char* s, const char* format, ...);
  int sscanf(const char* s, const char* format, ...);
  int vfprintf(FILE* stream, const char* format, va_list arg);
  int vfscanf(FILE* stream, const char* format, va_list arg);
  int vprintf(const char* format, va_list arg);
  int vscanf(const char* format, va_list arg);
  int vsnprintf(char* s, size_t n, const char* format, va_list arg);
  int vsprintf(char* s, const char* format, va_list arg);
  int vsscanf(const char* s, const char* format, va_list arg);
  int fgetc(FILE* stream);
  char* fgets(char* s, int n, FILE* stream);
  int fputc(int c, FILE* stream);
  int fputs(const char* s, FILE* stream);
  int getc(FILE* stream);
  int getchar();
  int putc(int c, FILE* stream);
  int putchar(int c);
  int puts(const char* s);
  int ungetc(int c, FILE* stream);
  size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
  size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
  int fgetpos(FILE* stream, fpos_t* pos);
  int fseek(FILE* stream, long int offset, int whence);
  int fsetpos(FILE* stream, const fpos_t* pos);
  long int ftell(FILE* stream);
  void rewind(FILE* stream);
  void clearerr(FILE* stream);
  int feof(FILE* stream);
  int ferror(FILE* stream);
  void perror(const char* s);
}
The contents and meaning of the header <cstdio> are the same as the C standard library header <stdio.h>.
Calls to the function tmpnam with an argument that is a null pointer value may introduce a data race ([res.on.data.races]) with other calls to tmpnam with an argument that is a null pointer value.
See also: ISO C 7.
21.

30.11.2 Header <cinttypes> synopsis [cinttypes.syn]

#include <cstdint>  // see [cstdint.syn]

namespace std {
  using imaxdiv_t = see below;

  intmax_t imaxabs(intmax_t j);
  imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);
  intmax_t strtoimax(const char* nptr, char** endptr, int base);
  uintmax_t strtoumax(const char* nptr, char** endptr, int base);
  intmax_t wcstoimax(const wchar_t* nptr, wchar_t** endptr, int base);
  uintmax_t wcstoumax(const wchar_t* nptr, wchar_t** endptr, int base);

  intmax_t abs(intmax_t);  // optional, see below
  imaxdiv_t div(intmax_t, intmax_t);  // optional, see below
}

#define PRIdN see below
#define PRIiN see below
#define PRIoN see below
#define PRIuN see below
#define PRIxN see below
#define PRIXN see below
#define SCNdN see below
#define SCNiN see below
#define SCNoN see below
#define SCNuN see below
#define SCNxN see below
#define PRIdLEASTN see below
#define PRIiLEASTN see below
#define PRIoLEASTN see below
#define PRIuLEASTN see below
#define PRIxLEASTN see below
#define PRIXLEASTN see below
#define SCNdLEASTN see below
#define SCNiLEASTN see below
#define SCNoLEASTN see below
#define SCNuLEASTN see below
#define SCNxLEASTN see below
#define PRIdFASTN see below
#define PRIiFASTN see below
#define PRIoFASTN see below
#define PRIuFASTN see below
#define PRIxFASTN see below
#define PRIXFASTN see below
#define SCNdFASTN see below
#define SCNiFASTN see below
#define SCNoFASTN see below
#define SCNuFASTN see below
#define SCNxFASTN see below
#define PRIdMAX see below
#define PRIiMAX see below
#define PRIoMAX see below
#define PRIuMAX see below
#define PRIxMAX see below
#define PRIXMAX see below
#define SCNdMAX see below
#define SCNiMAX see below
#define SCNoMAX see below
#define SCNuMAX see below
#define SCNxMAX see below
#define PRIdPTR see below
#define PRIiPTR see below
#define PRIoPTR see below
#define PRIuPTR see below
#define PRIxPTR see below
#define PRIXPTR see below
#define SCNdPTR see below
#define SCNiPTR see below
#define SCNoPTR see below
#define SCNuPTR see below
#define SCNxPTR see below
The contents and meaning of the header <cinttypes> are the same as the C standard library header <inttypes.h>, with the following changes:
  • The header <cinttypes> includes the header <cstdint> instead of <stdint.h>, and
  • if and only if the type intmax_­t designates an extended integer type ([basic.fundamental]), the following function signatures are added:
    intmax_t abs(intmax_t);
    imaxdiv_t div(intmax_t, intmax_t);
    which shall have the same semantics as the function signatures intmax_­t imaxabs(intmax_­t) and imaxdiv_­t imaxdiv(intmax_­t, intmax_­t), respectively.
See also: ISO C 7.
8.

31 Regular expressions library [re]

31.1 General [re.general]

This Clause describes components that C++ programs may use to perform operations involving regular expression matching and searching.
The following subclauses describe a basic regular expression class template and its traits that can handle char-like ([strings.general]) template arguments, two specializations of this class template that handle sequences of char and wchar_­t, a class template that holds the result of a regular expression match, a series of algorithms that allow a character sequence to be operated upon by a regular expression, and two iterator types for enumerating regular expression matches, as described in Table 123.
Table 123 — Regular expressions library summary
Subclause
Header(s)
Definitions
Requirements
Constants
Exception type
Traits
Regular expression template
<regex>
Submatches
Match results
Algorithms
Iterators
Grammar

31.2 Definitions [re.def]

The following definitions shall apply to this Clause:

31.2.1 collating element [defns.regex.collating.element]

a sequence of one or more characters within the current locale that collate as if they were a single character.

31.2.2 finite state machine [defns.regex.finite.state.machine]

an unspecified data structure that is used to represent a regular expression, and which permits efficient matches against the regular expression to be obtained.

31.2.3 format specifier [defns.regex.format.specifier]

a sequence of one or more characters that is to be replaced with some part of a regular expression match.

31.2.4 matched [defns.regex.matched]

a sequence of zero or more characters is matched by a regular expression when the characters in the sequence correspond to a sequence of characters defined by the pattern.

31.2.5 primary equivalence class [defns.regex.primary.equivalence.class]

a set of one or more characters which share the same primary sort key: that is the sort key weighting that depends only upon character shape, and not accents, case, or locale specific tailorings.

31.2.6 regular expression [defns.regex.regular.expression]

a pattern that selects specific strings from a set of character strings.

31.2.7 sub-expression [defns.regex.subexpression]

a subset of a regular expression that has been marked by parenthesis.

31.3 Requirements [re.req]

This subclause defines requirements on classes representing regular expression traits.
[Note
:
The class template regex_­traits, defined in Clause [re.traits], satisfies these requirements.
end note
]
The class template basic_­regex, defined in Clause [re.regex], needs a set of related types and functions to complete the definition of its semantics.
These types and functions are provided as a set of member typedef-names and functions in the template parameter traits used by the basic_­regex class template.
This subclause defines the semantics of these members.
To specialize class template basic_­regex for a character container CharT and its related regular expression traits class Traits, use basic_­regex<CharT, Traits>.
In Table 124 X denotes a traits class defining types and functions for the character container type charT; u is an object of type X; v is an object of type const X; p is a value of type const charT*; I1 and I2 are input iterators ([input.iterators]); F1 and F2 are forward iterators ([forward.iterators]); c is a value of type const charT; s is an object of type X​::​string_­type; cs is an object of type const X​::​string_­type; b is a value of type bool; I is a value of type int; cl is an object of type X​::​char_­class_­type, and loc is an object of type X​::​locale_­type.
Table 124 — Regular expression traits class requirements
Expression
Return type
Assertion/note pre-/post-condition
X​::​char_­type
charT
The character container type used in the implementation of class template basic_­regex.
X​::​string_­type
basic_­string<charT>
X​::​locale_­type
A copy constructible type
A type that represents the locale used by the traits class.
X​::​char_­class_­type
A bitmask type ([bitmask.types]).
A bitmask type representing a particular character classification.
X​::​length(p)
size_­t
Yields the smallest i such that p[i] == 0.
Complexity is linear in i .
v.translate(c)
X​::​char_­type
Returns a character such that for any character d that is to be considered equivalent to c then v.translate(c) == v.translate(d).
v.translate_­nocase(c)
X​::​char_­type
For all characters C that are to be considered equivalent to c when comparisons are to be performed without regard to case, then v.translate_­nocase(c) == v.translate_­nocase(C).
v.transform(F1, F2)
X​::​string_­type
Returns a sort key for the character sequence designated by the iterator range [F1, F2) such that if the character sequence [G1, G2) sorts before the character sequence [H1, H2) then v.transform(G1, G2) < v.transform(H1, H2).
v.transform_­primary(F1, F2)
X​::​string_­type
Returns a sort key for the character sequence designated by the iterator range [F1, F2) such that if the character sequence [G1, G2) sorts before the character sequence [H1, H2) when character case is not considered then v.transform_­primary(G1, G2) < v.transform_­primary(H1, H2).
v.lookup_­collatename(F1, F2)
X​::​string_­type
Returns a sequence of characters that represents the collating element consisting of the character sequence designated by the iterator range [F1, F2).
Returns an empty string if the character sequence is not a valid collating element.
v.lookup_­classname(F1, F2, b)
X​::​char_­class_­type
Converts the character sequence designated by the iterator range [F1, F2) into a value of a bitmask type that can subsequently be passed to isctype.
Values returned from lookup_­classname can be bitwise or'ed together; the resulting value represents membership in either of the corresponding character classes.
If b is true, the returned bitmask is suitable for matching characters without regard to their case.
Returns 0 if the character sequence is not the name of a character class recognized by X.
The value returned shall be independent of the case of the characters in the sequence.
v.isctype(c, cl)
bool
Returns true if character c is a member of one of the character classes designated by cl, false otherwise.
v.value(c, I)
int
Returns the value represented by the digit c in base I if the character c is a valid digit in base I; otherwise returns -1.
[Note
:
The value of I will only be 8, 10, or 16.
end note
]
u.imbue(loc)
X​::​locale_­type
Imbues u with the locale loc and returns the previous locale used by u if any.
v.getloc()
X​::​locale_­type
Returns the current locale used by v, if any.
[Note
:
Class template regex_­traits satisfies the requirements for a regular expression traits class when it is specialized for char or wchar_­t.
This class template is described in the header <regex>, and is described in Clause [re.traits].
end note
]

31.4 Header <regex> synopsis [re.syn]

#include <initializer_list>

namespace std {
  // [re.const], regex constants
  namespace regex_constants {
    using syntax_option_type = T1;
    using match_flag_type = T2;
    using error_type = T3;
  }

  // [re.badexp], class regex_­error
  class regex_error;

  // [re.traits], class template regex_­traits
  template <class charT> struct regex_traits;

  // [re.regex], class template basic_­regex
  template <class charT, class traits = regex_traits<charT>> class basic_regex;

  using regex  = basic_regex<char>;
  using wregex = basic_regex<wchar_t>;

  // [re.regex.swap], basic_­regex swap
  template <class charT, class traits>
    void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2);

  // [re.submatch], class template sub_­match
  template <class BidirectionalIterator>
    class sub_match;

  using csub_match  = sub_match<const char*>;
  using wcsub_match = sub_match<const wchar_t*>;
  using ssub_match  = sub_match<string::const_iterator>;
  using wssub_match = sub_match<wstring::const_iterator>;

  // [re.submatch.op], sub_­match non-member operators
  template <class BiIter>
    bool operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);

  template <class BiIter, class ST, class SA>
    bool operator==(
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
      const sub_match<BiIter>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator!=(
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
      const sub_match<BiIter>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator<(
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
      const sub_match<BiIter>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator>(
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
      const sub_match<BiIter>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator>=(
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
      const sub_match<BiIter>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator<=(
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
      const sub_match<BiIter>& rhs);

  template <class BiIter, class ST, class SA>
    bool operator==(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator!=(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator<(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator>(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator>=(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
  template <class BiIter, class ST, class SA>
    bool operator<=(
      const sub_match<BiIter>& lhs,
      const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);

  template <class BiIter>
    bool operator==(const typename iterator_traits<BiIter>::value_type* lhs,
                    const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator!=(const typename iterator_traits<BiIter>::value_type* lhs,
                    const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator<(const typename iterator_traits<BiIter>::value_type* lhs,
                   const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator>(const typename iterator_traits<BiIter>::value_type* lhs,
                   const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator>=(const typename iterator_traits<BiIter>::value_type* lhs,
                    const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator<=(const typename iterator_traits<BiIter>::value_type* lhs,
                    const sub_match<BiIter>& rhs);

  template <class BiIter>
    bool operator==(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type* rhs);
  template <class BiIter>
    bool operator!=(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type* rhs);
  template <class BiIter>
    bool operator<(const sub_match<BiIter>& lhs,
                   const typename iterator_traits<BiIter>::value_type* rhs);
  template <class BiIter>
    bool operator>(const sub_match<BiIter>& lhs,
                   const typename iterator_traits<BiIter>::value_type* rhs);
  template <class BiIter>
    bool operator>=(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type* rhs);
  template <class BiIter>
    bool operator<=(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type* rhs);

  template <class BiIter>
    bool operator==(const typename iterator_traits<BiIter>::value_type& lhs,
                    const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator!=(const typename iterator_traits<BiIter>::value_type& lhs,
                    const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator<(const typename iterator_traits<BiIter>::value_type& lhs,
                   const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator>(const typename iterator_traits<BiIter>::value_type& lhs,
                   const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator>=(const typename iterator_traits<BiIter>::value_type& lhs,
                    const sub_match<BiIter>& rhs);
  template <class BiIter>
    bool operator<=(const typename iterator_traits<BiIter>::value_type& lhs,
                    const sub_match<BiIter>& rhs);

  template <class BiIter>
    bool operator==(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type& rhs);
  template <class BiIter>
    bool operator!=(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type& rhs);
  template <class BiIter>
    bool operator<(const sub_match<BiIter>& lhs,
                   const typename iterator_traits<BiIter>::value_type& rhs);
  template <class BiIter>
    bool operator>(const sub_match<BiIter>& lhs,
                   const typename iterator_traits<BiIter>::value_type& rhs);
  template <class BiIter>
    bool operator>=(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type& rhs);
  template <class BiIter>
    bool operator<=(const sub_match<BiIter>& lhs,
                    const typename iterator_traits<BiIter>::value_type& rhs);

  template <class charT, class ST, class BiIter>
    basic_ostream<charT, ST>&
      operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);

  // [re.results], class template match_­results
  template <class BidirectionalIterator,
            class Allocator = allocator<sub_match<BidirectionalIterator>>>
    class match_results;

  using cmatch  = match_results<const char*>;
  using wcmatch = match_results<const wchar_t*>;
  using smatch  = match_results<string::const_iterator>;
  using wsmatch = match_results<wstring::const_iterator>;

  // match_­results comparisons
  template <class BidirectionalIterator, class Allocator>
    bool operator==(const match_results<BidirectionalIterator, Allocator>& m1,
                    const match_results<BidirectionalIterator, Allocator>& m2);
  template <class BidirectionalIterator, class Allocator>
    bool operator!=(const match_results<BidirectionalIterator, Allocator>& m1,
                    const match_results<BidirectionalIterator, Allocator>& m2);

  // [re.results.swap], match_­results swap
  template <class BidirectionalIterator, class Allocator>
    void swap(match_results<BidirectionalIterator, Allocator>& m1,
              match_results<BidirectionalIterator, Allocator>& m2);

  // [re.alg.match], function template regex_­match
  template <class BidirectionalIterator, class Allocator, class charT, class traits>
    bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                     match_results<BidirectionalIterator, Allocator>& m,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class BidirectionalIterator, class charT, class traits>
    bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class charT, class Allocator, class traits>
    bool regex_match(const charT* str, match_results<const charT*, Allocator>& m,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class ST, class SA, class Allocator, class charT, class traits>
    bool regex_match(const basic_string<charT, ST, SA>& s,
                     match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                   Allocator>& m,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class ST, class SA, class Allocator, class charT, class traits>
    bool regex_match(const basic_string<charT, ST, SA>&&,
                     match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                   Allocator>&,
                     const basic_regex<charT, traits>&,
                     regex_constants::match_flag_type = regex_constants::match_default) = delete;
  template <class charT, class traits>
    bool regex_match(const charT* str,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class ST, class SA, class charT, class traits>
    bool regex_match(const basic_string<charT, ST, SA>& s,
                     const basic_regex<charT, traits>& e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);

  // [re.alg.search], function template regex_­search
  template <class BidirectionalIterator, class Allocator, class charT, class traits>
    bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                      match_results<BidirectionalIterator, Allocator>& m,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class BidirectionalIterator, class charT, class traits>
    bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class charT, class Allocator, class traits>
    bool regex_search(const charT* str,
                      match_results<const charT*, Allocator>& m,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class charT, class traits>
    bool regex_search(const charT* str,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class ST, class SA, class charT, class traits>
    bool regex_search(const basic_string<charT, ST, SA>& s,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class ST, class SA, class Allocator, class charT, class traits>
    bool regex_search(const basic_string<charT, ST, SA>& s,
                      match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                    Allocator>& m,
                      const basic_regex<charT, traits>& e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class ST, class SA, class Allocator, class charT, class traits>
    bool regex_search(const basic_string<charT, ST, SA>&&,
                      match_results<typename basic_string<charT, ST, SA>::const_iterator,
                                    Allocator>&,
                      const basic_regex<charT, traits>&,
                      regex_constants::match_flag_type
                        = regex_constants::match_default) = delete;

  // [re.alg.replace], function template regex_­replace
  template <class OutputIterator, class BidirectionalIterator,
            class traits, class charT, class ST, class SA>
    OutputIterator
      regex_replace(OutputIterator out,
                    BidirectionalIterator first, BidirectionalIterator last,
                    const basic_regex<charT, traits>& e,
                    const basic_string<charT, ST, SA>& fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class OutputIterator, class BidirectionalIterator, class traits, class charT>
    OutputIterator
      regex_replace(OutputIterator out,
                    BidirectionalIterator first, BidirectionalIterator last,
                    const basic_regex<charT, traits>& e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class traits, class charT, class ST, class SA, class FST, class FSA>
    basic_string<charT, ST, SA>
      regex_replace(const basic_string<charT, ST, SA>& s,
                    const basic_regex<charT, traits>& e,
                    const basic_string<charT, FST, FSA>& fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class traits, class charT, class ST, class SA>
    basic_string<charT, ST, SA>
      regex_replace(const basic_string<charT, ST, SA>& s,
                    const basic_regex<charT, traits>& e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class traits, class charT, class ST, class SA>
    basic_string<charT>
      regex_replace(const charT* s,
                    const basic_regex<charT, traits>& e,
                    const basic_string<charT, ST, SA>& fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template <class traits, class charT>
    basic_string<charT>
      regex_replace(const charT* s,
                    const basic_regex<charT, traits>& e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);

  // [re.regiter], class template regex_­iterator
  template <class BidirectionalIterator,
            class charT = typename iterator_traits<BidirectionalIterator>::value_type,
            class traits = regex_traits<charT>>
    class regex_iterator;

  using cregex_iterator  = regex_iterator<const char*>;
  using wcregex_iterator = regex_iterator<const wchar_t*>;
  using sregex_iterator  = regex_iterator<string::const_iterator>;
  using wsregex_iterator = regex_iterator<wstring::const_iterator>;

  // [re.tokiter], class template regex_­token_­iterator
  template <class BidirectionalIterator,
            class charT = typename iterator_traits<BidirectionalIterator>::value_type,
            class traits = regex_traits<charT>>
    class regex_token_iterator;

  using cregex_token_iterator  = regex_token_iterator<const char*>;
  using wcregex_token_iterator = regex_token_iterator<const wchar_t*>;
  using sregex_token_iterator  = regex_token_iterator<string::const_iterator>;
  using wsregex_token_iterator = regex_token_iterator<wstring::const_iterator>;

  namespace pmr {
    template <class BidirectionalIterator>
      using match_results =
        std::match_results<BidirectionalIterator,
                           polymorphic_allocator<sub_match<BidirectionalIterator>>>;

    using cmatch  = match_results<const char*>;
    using wcmatch = match_results<const wchar_t*>;
    using smatch  = match_results<string::const_iterator>;
    using wsmatch = match_results<wstring::const_iterator>;
  }
}

31.5 Namespace std​::​regex_­constants [re.const]

The namespace std​::​regex_­constants holds symbolic constants used by the regular expression library.
This namespace provides three types, syntax_­option_­type, match_­flag_­type, and error_­type, along with several constants of these types.

31.5.1 Bitmask type syntax_­option_­type [re.synopt]

namespace std::regex_constants {
  using syntax_option_type = T1;
  inline constexpr syntax_option_type icase = unspecified;
  inline constexpr syntax_option_type nosubs = unspecified;
  inline constexpr syntax_option_type optimize = unspecified;
  inline constexpr syntax_option_type collate = unspecified;
  inline constexpr syntax_option_type ECMAScript = unspecified;
  inline constexpr syntax_option_type basic = unspecified;
  inline constexpr syntax_option_type extended = unspecified;
  inline constexpr syntax_option_type awk = unspecified;
  inline constexpr syntax_option_type grep = unspecified;
  inline constexpr syntax_option_type egrep = unspecified;
  inline constexpr syntax_option_type multiline = unspecified;
}
The type syntax_­option_­type is an implementation-defined bitmask type ([bitmask.types]).
Setting its elements has the effects listed in Table 125.
A valid value of type syntax_­option_­type shall have at most one of the grammar elements ECMAScript, basic, extended, awk, grep, egrep, set.
If no grammar element is set, the default grammar is ECMAScript.
Table 125syntax_­option_­type effects
Element
Effect(s) if set
icase
Specifies that matching of regular expressions against a character container sequence shall be performed without regard to case.
nosubs
Specifies that no sub-expressions shall be considered to be marked, so that when a regular expression is matched against a character container sequence, no sub-expression matches shall be stored in the supplied match_­results structure.
optimize
Specifies that the regular expression engine should pay more attention to the speed with which regular expressions are matched, and less to the speed with which regular expression objects are constructed.
Otherwise it has no detectable effect on the program output.
collate
Specifies that character ranges of the form "[a-b]" shall be locale sensitive.
ECMAScript
Specifies that the grammar recognized by the regular expression engine shall be that used by ECMAScript in ECMA-262, as modified in [re.grammar].
basic
Specifies that the grammar recognized by the regular expression engine shall be that used by basic regular expressions in POSIX, Base Definitions and Headers, Section 9, Regular Expressions.
extended
Specifies that the grammar recognized by the regular expression engine shall be that used by extended regular expressions in POSIX, Base Definitions and Headers, Section 9, Regular Expressions.
awk
Specifies that the grammar recognized by the regular expression engine shall be that used by the utility awk in POSIX.
grep
Specifies that the grammar recognized by the regular expression engine shall be that used by the utility grep in POSIX.
egrep
Specifies that the grammar recognized by the regular expression engine shall be that used by the utility grep when given the -E option in POSIX.
multiline
Specifies that ^ shall match the beginning of a line and $ shall match the end of a line, if the ECMAScript engine is selected.

31.5.2 Bitmask type match_­flag_­type [re.matchflag]

namespace std::regex_constants {
  using match_flag_type = T2;
  inline constexpr match_flag_type match_default = {};
  inline constexpr match_flag_type match_not_bol = unspecified;
  inline constexpr match_flag_type match_not_eol = unspecified;
  inline constexpr match_flag_type match_not_bow = unspecified;
  inline constexpr match_flag_type match_not_eow = unspecified;
  inline constexpr match_flag_type match_any = unspecified;
  inline constexpr match_flag_type match_not_null = unspecified;
  inline constexpr match_flag_type match_continuous = unspecified;
  inline constexpr match_flag_type match_prev_avail = unspecified;
  inline constexpr match_flag_type format_default = {};
  inline constexpr match_flag_type format_sed = unspecified;
  inline constexpr match_flag_type format_no_copy = unspecified;
  inline constexpr match_flag_type format_first_only = unspecified;
}
The type match_­flag_­type is an implementation-defined bitmask type ([bitmask.types]).
The constants of that type, except for match_­default and format_­default, are bitmask elements.
The match_­default and format_­default constants are empty bitmasks.
Matching a regular expression against a sequence of characters [first, last) proceeds according to the rules of the grammar specified for the regular expression object, modified according to the effects listed in Table 126 for any bitmask elements set.
Table 126regex_­constants​::​match_­flag_­type effects when obtaining a match against a character container sequence [first, last).
Element
Effect(s) if set
match_­not_­bol
The first character in the sequence [first, last) shall be treated as though it is not at the beginning of a line, so the character ^ in the regular expression shall not match [first, first).
match_­not_­eol
The last character in the sequence [first, last) shall be treated as though it is not at the end of a line, so the character "$" in the regular expression shall not match [last, last).
match_­not_­bow
The expression "\\b" shall not match the sub-sequence [first, first).
match_­not_­eow
The expression "\\b" shall not match the sub-sequence [last, last).
match_­any
If more than one match is possible then any match is an acceptable result.
match_­not_­null
The expression shall not match an empty sequence.
match_­continuous
The expression shall only match a sub-sequence that begins at first.
match_­prev_­avail
--first is a valid iterator position.
When this flag is set the flags match_­not_­bol and match_­not_­bow shall be ignored by the regular expression algorithms ([re.alg]) and iterators ([re.iter]).
format_­default
When a regular expression match is to be replaced by a new string, the new string shall be constructed using the rules used by the ECMAScript replace function in ECMA-262, part 15.
5.
4.
11 String.
prototype.
replace.
In addition, during search and replace operations all non-overlapping occurrences of the regular expression shall be located and replaced, and sections of the input that did not match the expression shall be copied unchanged to the output string.
format_­sed
When a regular expression match is to be replaced by a new string, the new string shall be constructed using the rules used by the sed utility in POSIX.
format_­no_­copy
During a search and replace operation, sections of the character container sequence being searched that do not match the regular expression shall not be copied to the output string.
format_­first_­only
When specified during a search and replace operation, only the first occurrence of the regular expression shall be replaced.

31.5.3 Implementation-defined error_­type [re.err]

namespace std::regex_constants {
  using error_type = T3;
  inline constexpr error_type error_collate = unspecified;
  inline constexpr error_type error_ctype = unspecified;
  inline constexpr error_type error_escape = unspecified;
  inline constexpr error_type error_backref = unspecified;
  inline constexpr error_type error_brack = unspecified;
  inline constexpr error_type error_paren = unspecified;
  inline constexpr error_type error_brace = unspecified;
  inline constexpr error_type error_badbrace = unspecified;
  inline constexpr error_type error_range = unspecified;
  inline constexpr error_type error_space = unspecified;
  inline constexpr error_type error_badrepeat = unspecified;
  inline constexpr error_type error_complexity = unspecified;
  inline constexpr error_type error_stack = unspecified;
}
The type error_­type is an implementation-defined enumerated type ([enumerated.types]).
Values of type error_­type represent the error conditions described in Table 127:
Table 127error_­type values in the C locale
Value
Error condition
error_­collate
The expression contained an invalid collating element name.
error_­ctype
The expression contained an invalid character class name.
error_­escape
The expression contained an invalid escaped character, or a trailing escape.
error_­backref
The expression contained an invalid back reference.
error_­brack
The expression contained mismatched [ and ].
error_­paren
The expression contained mismatched ( and ).
error_­brace
The expression contained mismatched { and }
error_­badbrace
The expression contained an invalid range in a {} expression.
error_­range
The expression contained an invalid character range, such as [b-a] in most encodings.
error_­space
There was insufficient memory to convert the expression into a finite state machine.
error_­badrepeat
One of *?+{ was not preceded by a valid regular expression.
error_­complexity
The complexity of an attempted match against a regular expression exceeded a pre-set level.
error_­stack
There was insufficient memory to determine whether the regular expression could match the specified character sequence.

31.6 Class regex_­error [re.badexp]

class regex_error : public runtime_error {
public:
  explicit regex_error(regex_constants::error_type ecode);
  regex_constants::error_type code() const;
};
The class regex_­error defines the type of objects thrown as exceptions to report errors from the regular expression library.
regex_error(regex_constants::error_type ecode);
Effects: Constructs an object of class regex_­error.
Postconditions: ecode == code().
regex_constants::error_type code() const;
Returns: The error code that was passed to the constructor.

31.7 Class template regex_­traits [re.traits]

namespace std {
  template <class charT>
    struct regex_traits {
      using char_type       = charT;
      using string_type     = basic_string<char_type>;
      using locale_type     = locale;
      using char_class_type = bitmask_type;

      regex_traits();
      static size_t length(const char_type* p);
      charT translate(charT c) const;
      charT translate_nocase(charT c) const;
      template <class ForwardIterator>
        string_type transform(ForwardIterator first, ForwardIterator last) const;
      template <class ForwardIterator>
        string_type transform_primary(
          ForwardIterator first, ForwardIterator last) const;
      template <class ForwardIterator>
        string_type lookup_collatename(
          ForwardIterator first, ForwardIterator last) const;
      template <class ForwardIterator>
        char_class_type lookup_classname(
          ForwardIterator first, ForwardIterator last, bool icase = false) const;
      bool isctype(charT c, char_class_type f) const;
      int value(charT ch, int radix) const;
      locale_type imbue(locale_type l);
      locale_type getloc() const;
    };
}
The specializations regex_­traits<char> and regex_­traits<wchar_­t> shall be valid and shall satisfy the requirements for a regular expression traits class ([re.req]).
using char_class_type = bitmask_type;
The type char_­class_­type is used to represent a character classification and is capable of holding an implementation specific set returned by lookup_­classname.
static size_t length(const char_type* p);
Returns: char_­traits<charT>​::​length(p).
charT translate(charT c) const;
Returns: c.
charT translate_nocase(charT c) const;
Returns: use_­facet<ctype<charT>>(getloc()).tolower(c).
template <class ForwardIterator> string_type transform(ForwardIterator first, ForwardIterator last) const;
Effects: As if by:
string_type str(first, last);
return use_facet<collate<charT>>(
  getloc()).transform(&*str.begin(), &*str.begin() + str.length());
template <class ForwardIterator> string_type transform_primary(ForwardIterator first, ForwardIterator last) const;
Effects: If
typeid(use_facet<collate<charT>>) == typeid(collate_byname<charT>)
and the form of the sort key returned by collate_­byname<charT>​::​transform(first, last) is known and can be converted into a primary sort key then returns that key, otherwise returns an empty string.
template <class ForwardIterator> string_type lookup_collatename(ForwardIterator first, ForwardIterator last) const;
Returns: a sequence of one or more characters that represents the collating element consisting of the character sequence designated by the iterator range [first, last).
Returns an empty string if the character sequence is not a valid collating element.
template <class ForwardIterator> char_class_type lookup_classname( ForwardIterator first, ForwardIterator last, bool icase = false) const;
Returns: an unspecified value that represents the character classification named by the character sequence designated by the iterator range [first, last).
If the parameter icase is true then the returned mask identifies the character classification without regard to the case of the characters being matched, otherwise it does honor the case of the characters being matched.329
The value returned shall be independent of the case of the characters in the character sequence.
If the name is not recognized then returns char_­class_­type().
Remarks: For regex_­traits<char>, at least the narrow character names in Table 128 shall be recognized.
For regex_­traits<wchar_­t>, at least the wide character names in Table 128 shall be recognized.
bool isctype(charT c, char_class_type f) const;
Effects: Determines if the character c is a member of the character classification represented by f.
Returns: Given the following function declaration:
// for exposition only
template<class C>
  ctype_base::mask convert(typename regex_traits<C>::char_class_type f);
that returns a value in which each ctype_­base​::​mask value corresponding to a value in f named in Table 128 is set, then the result is determined as if by:
ctype_base::mask m = convert<charT>(f);
const ctype<charT>& ct = use_facet<ctype<charT>>(getloc());
if (ct.is(m, c)) {
  return true;
} else if (c == ct.widen('_')) {
  charT w[1] = { ct.widen('w') };
  char_class_type x = lookup_classname(w, w+1);
  return (f&x) == x;
} else {
  return false;
}
[Example
:
regex_traits<char> t;
string d("d");
string u("upper");
regex_traits<char>::char_class_type f;
f = t.lookup_classname(d.begin(), d.end());
f |= t.lookup_classname(u.begin(), u.end());
ctype_base::mask m = convert<char>(f); // m == ctype_­base​::​digit|ctype_­base​::​upper
end example
]
[Example
:
regex_traits<char> t;
string w("w");
regex_traits<char>::char_class_type f;
f = t.lookup_classname(w.begin(), w.end());
t.isctype('A', f); // returns true
t.isctype('_', f); // returns true
t.isctype(' ', f); // returns false
end example
]
int value(charT ch, int radix) const;
Requires: The value of radix shall be 8, 10, or 16.
Returns: the value represented by the digit ch in base radix if the character ch is a valid digit in base radix; otherwise returns -1.
locale_type imbue(locale_type loc);
Effects: Imbues this with a copy of the locale loc.
[Note
:
Calling imbue with a different locale than the one currently in use invalidates all cached data held by *this.
end note
]
Returns: if no locale has been previously imbued then a copy of the global locale in effect at the time of construction of *this, otherwise a copy of the last argument passed to imbue.
Postconditions: getloc() == loc.
locale_type getloc() const;
Returns: if no locale has been imbued then a copy of the global locale in effect at the time of construction of *this, otherwise a copy of the last argument passed to imbue.
Table 128 — Character class names and corresponding ctype masks
Narrow character name
Wide character name
Corresponding ctype_­base​::​mask value
"alnum"
L"alnum"
ctype_­base​::​alnum
"alpha"
L"alpha"
ctype_­base​::​alpha
"blank"
L"blank"
ctype_­base​::​blank
"cntrl"
L"cntrl"
ctype_­base​::​cntrl
"digit"
L"digit"
ctype_­base​::​digit
"d"
L"d"
ctype_­base​::​digit
"graph"
L"graph"
ctype_­base​::​graph
"lower"
L"lower"
ctype_­base​::​lower
"print"
L"print"
ctype_­base​::​print
"punct"
L"punct"
ctype_­base​::​punct
"space"
L"space"
ctype_­base​::​space
"s"
L"s"
ctype_­base​::​space
"upper"
L"upper"
ctype_­base​::​upper
"w"
L"w"
ctype_­base​::​alnum
"xdigit"
L"xdigit"
ctype_­base​::​xdigit
For example, if the parameter icase is true then [[:lower:]] is the same as [[:alpha:]].

31.8 Class template basic_­regex [re.regex]

For a char-like type charT, specializations of class template basic_­regex represent regular expressions constructed from character sequences of charT characters.
In the rest of [re.regex], charT denotes a given char-like type.
Storage for a regular expression is allocated and freed as necessary by the member functions of class basic_­regex.
Objects of type specialization of basic_­regex are responsible for converting the sequence of charT objects to an internal representation.
It is not specified what form this representation takes, nor how it is accessed by algorithms that operate on regular expressions.
[Note
:
Implementations will typically declare some function templates as friends of basic_­regex to achieve this
end note
]
The functions described in this Clause report errors by throwing exceptions of type regex_­error.
namespace std {
  template <class charT, class traits = regex_traits<charT>>
    class basic_regex {
    public:
      // types:
      using value_type  =          charT;
      using traits_type =          traits;
      using string_type = typename traits::string_type;
      using flag_type   =          regex_constants::syntax_option_type;
      using locale_type = typename traits::locale_type;

      // [re.regex.const], constants
      static constexpr regex_constants::syntax_option_type
        icase = regex_constants::icase;
      static constexpr regex_constants::syntax_option_type
        nosubs = regex_constants::nosubs;
      static constexpr regex_constants::syntax_option_type
        optimize = regex_constants::optimize;
      static constexpr regex_constants::syntax_option_type
        collate = regex_constants::collate;
      static constexpr regex_constants::syntax_option_type
        ECMAScript = regex_constants::ECMAScript;
      static constexpr regex_constants::syntax_option_type
        basic = regex_constants::basic;
      static constexpr regex_constants::syntax_option_type
        extended = regex_constants::extended;
      static constexpr regex_constants::syntax_option_type
        awk = regex_constants::awk;
      static constexpr regex_constants::syntax_option_type
        grep = regex_constants::grep;
      static constexpr regex_constants::syntax_option_type
        egrep = regex_constants::egrep;
      static constexpr regex_constants::syntax_option_type
        multiline = regex_constants::multiline;

      // [re.regex.construct], construct/copy/destroy
      basic_regex();
      explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
      basic_regex(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript);
      basic_regex(const basic_regex&);
      basic_regex(basic_regex&&) noexcept;
      template <class ST, class SA>
        explicit basic_regex(const basic_string<charT, ST, SA>& p,
                             flag_type f = regex_constants::ECMAScript);
      template <class ForwardIterator>
        basic_regex(ForwardIterator first, ForwardIterator last,
                    flag_type f = regex_constants::ECMAScript);
      basic_regex(initializer_list<charT>, flag_type = regex_constants::ECMAScript);

      ~basic_regex();

      basic_regex& operator=(const basic_regex&);
      basic_regex& operator=(basic_regex&&) noexcept;
      basic_regex& operator=(const charT* ptr);
      basic_regex& operator=(initializer_list<charT> il);
      template <class ST, class SA>
        basic_regex& operator=(const basic_string<charT, ST, SA>& p);

      // [re.regex.assign], assign
      basic_regex& assign(const basic_regex& that);
      basic_regex& assign(basic_regex&& that) noexcept;
      basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript);
      basic_regex& assign(const charT* p, size_t len, flag_type f);
      template <class string_traits, class A>
        basic_regex& assign(const basic_string<charT, string_traits, A>& s,
                            flag_type f = regex_constants::ECMAScript);
      template <class InputIterator>
        basic_regex& assign(InputIterator first, InputIterator last,
                            flag_type f = regex_constants::ECMAScript);
      basic_regex& assign(initializer_list<charT>,
                          flag_type = regex_constants::ECMAScript);

      // [re.regex.operations], const operations
      unsigned mark_count() const;
      flag_type flags() const;

      // [re.regex.locale], locale
      locale_type imbue(locale_type loc);
      locale_type getloc() const;

      // [re.regex.swap], swap
      void swap(basic_regex&);
    };

  template<class ForwardIterator>
    basic_regex(ForwardIterator, ForwardIterator,
                regex_constants::syntax_option_type = regex_constants::ECMAScript)
      -> basic_regex<typename iterator_traits<ForwardIterator>::value_type>;
}

31.8.1 basic_­regex constants [re.regex.const]

static constexpr regex_constants::syntax_option_type icase = regex_constants::icase;
static constexpr regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
static constexpr regex_constants::syntax_option_type optimize = regex_constants::optimize;
static constexpr regex_constants::syntax_option_type collate = regex_constants::collate;
static constexpr regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
static constexpr regex_constants::syntax_option_type basic = regex_constants::basic;
static constexpr regex_constants::syntax_option_type extended = regex_constants::extended;
static constexpr regex_constants::syntax_option_type awk = regex_constants::awk;
static constexpr regex_constants::syntax_option_type grep = regex_constants::grep;
static constexpr regex_constants::syntax_option_type egrep = regex_constants::egrep;
static constexpr regex_constants::syntax_option_type multiline = regex_constants::multiline;
The static constant members are provided as synonyms for the constants declared in namespace regex_­constants.

31.8.2 basic_­regex constructors [re.regex.construct]

basic_regex();
Effects: Constructs an object of class basic_­regex that does not match any character sequence.
explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
Requires: p shall not be a null pointer.
Throws: regex_­error if p is not a valid regular expression.
Effects: Constructs an object of class basic_­regex; the object's internal finite state machine is constructed from the regular expression contained in the array of charT of length char_­traits<charT>​::​​length(p) whose first element is designated by p, and interpreted according to the flags f.
Postconditions: flags() returns f.
mark_­count() returns the number of marked sub-expressions within the expression.
basic_regex(const charT* p, size_t len, flag_type f);
Requires: p shall not be a null pointer.
Throws: regex_­error if p is not a valid regular expression.
Effects: Constructs an object of class basic_­regex; the object's internal finite state machine is constructed from the regular expression contained in the sequence of characters [p, p+len), and interpreted according the flags specified in f.
Postconditions: flags() returns f.
mark_­count() returns the number of marked sub-expressions within the expression.
basic_regex(const basic_regex& e);
Effects: Constructs an object of class basic_­regex as a copy of the object e.
Postconditions: flags() and mark_­count() return e.flags() and e.mark_­count(), respectively.
basic_regex(basic_regex&& e) noexcept;
Effects: Move constructs an object of class basic_­regex from e.
Postconditions: flags() and mark_­count() return the values that e.flags() and e.mark_­count(), respectively, had before construction.
e is in a valid state with unspecified value.
template <class ST, class SA> explicit basic_regex(const basic_string<charT, ST, SA>& s, flag_type f = regex_constants::ECMAScript);
Throws: regex_­error if s is not a valid regular expression.
Effects: Constructs an object of class basic_­regex; the object's internal finite state machine is constructed from the regular expression contained in the string s, and interpreted according to the flags specified in f.
Postconditions: flags() returns f.
mark_­count() returns the number of marked sub-expressions within the expression.
template <class ForwardIterator> basic_regex(ForwardIterator first, ForwardIterator last, flag_type f = regex_constants::ECMAScript);
Throws: regex_­error if the sequence [first, last) is not a valid regular expression.
Effects: Constructs an object of class basic_­regex; the object's internal finite state machine is constructed from the regular expression contained in the sequence of characters [first, last), and interpreted according to the flags specified in f.
Postconditions: flags() returns f.
mark_­count() returns the number of marked sub-expressions within the expression.
basic_regex(initializer_list<charT> il, flag_type f = regex_constants::ECMAScript);
Effects: Same as basic_­regex(il.begin(), il.end(), f).

31.8.3 basic_­regex assign [re.regex.assign]

basic_regex& operator=(const basic_regex& e);
Effects: Copies e into *this and returns *this.
Postconditions: flags() and mark_­count() return e.flags() and e.mark_­count(), respectively.
basic_regex& operator=(basic_regex&& e) noexcept;
Effects: Move assigns from e into *this and returns *this.
Postconditions: flags() and mark_­count() return the values that e.flags() and e.mark_­count(), respectively, had before assignment.
e is in a valid state with unspecified value.
basic_regex& operator=(const charT* ptr);
Requires: ptr shall not be a null pointer.
Effects: Returns assign(ptr).
basic_regex& operator=(initializer_list<charT> il);
Effects: Returns assign(il.begin(), il.end()).
template <class ST, class SA> basic_regex& operator=(const basic_string<charT, ST, SA>& p);
Effects: Returns assign(p).
basic_regex& assign(const basic_regex& that);
Effects: Equivalent to *this = that.
Returns: *this.
basic_regex& assign(basic_regex&& that) noexcept;
Effects: Equivalent to *this = std​::​move(that).
Returns: *this.
basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript);
Returns: assign(string_­type(ptr), f).
basic_regex& assign(const charT* ptr, size_t len, flag_type f = regex_constants::ECMAScript);
Returns: assign(string_­type(ptr, len), f).
template <class string_traits, class A> basic_regex& assign(const basic_string<charT, string_traits, A>& s, flag_type f = regex_constants::ECMAScript);
Throws: regex_­error if s is not a valid regular expression.
Returns: *this.
Effects: Assigns the regular expression contained in the string s, interpreted according the flags specified in f.
If an exception is thrown, *this is unchanged.
Postconditions: If no exception is thrown, flags() returns f and mark_­count() returns the number of marked sub-expressions within the expression.
template <class InputIterator> basic_regex& assign(InputIterator first, InputIterator last, flag_type f = regex_constants::ECMAScript);
Requires: The type InputIterator shall satisfy the requirements for an Input Iterator ([input.iterators]).
Returns: assign(string_­type(first, last), f).
basic_regex& assign(initializer_list<charT> il, flag_type f = regex_constants::ECMAScript);
Effects: Same as assign(il.begin(), il.end(), f).
Returns: *this.

31.8.4 basic_­regex constant operations [re.regex.operations]

unsigned mark_count() const;
Effects: Returns the number of marked sub-expressions within the regular expression.
flag_type flags() const;
Effects: Returns a copy of the regular expression syntax flags that were passed to the object's constructor or to the last call to assign.

31.8.5 basic_­regex locale [re.regex.locale]

locale_type imbue(locale_type loc);
Effects: Returns the result of traits_­inst.imbue(loc) where traits_­inst is a (default-initialized) instance of the template type argument traits stored within the object.
After a call to imbue the basic_­regex object does not match any character sequence.
locale_type getloc() const;
Effects: Returns the result of traits_­inst.getloc() where traits_­inst is a (default-initialized) instance of the template parameter traits stored within the object.

31.8.6 basic_­regex swap [re.regex.swap]

void swap(basic_regex& e);
Effects: Swaps the contents of the two regular expressions.
Postconditions: *this contains the regular expression that was in e, e contains the regular expression that was in *this.
Complexity: Constant time.

31.8.7 basic_­regex non-member functions [re.regex.nonmemb]

31.8.7.1 basic_­regex non-member swap [re.regex.nmswap]

template <class charT, class traits> void swap(basic_regex<charT, traits>& lhs, basic_regex<charT, traits>& rhs);
Effects: Calls lhs.swap(rhs).

31.9 Class template sub_­match [re.submatch]

Class template sub_­match denotes the sequence of characters matched by a particular marked sub-expression.
namespace std {
  template <class BidirectionalIterator>
    class sub_match : public pair<BidirectionalIterator, BidirectionalIterator> {
    public:
      using value_type      =
              typename iterator_traits<BidirectionalIterator>::value_type;
      using difference_type =
              typename iterator_traits<BidirectionalIterator>::difference_type;
      using iterator        = BidirectionalIterator;
      using string_type     = basic_string<value_type>;

      bool matched;

      constexpr sub_match();

      difference_type length() const;
      operator string_type() const;
      string_type str() const;

      int compare(const sub_match& s) const;
      int compare(const string_type& s) const;
      int compare(const value_type* s) const;
    };
}

31.9.1 sub_­match members [re.submatch.members]

constexpr sub_match();
Effects: Value-initializes the pair base class subobject and the member matched.
difference_type length() const;
Returns: matched ? distance(first, second) : 0.
operator string_type() const;
Returns: matched ? string_­type(first, second) : string_­type().
string_type str() const;
Returns: matched ? string_­type(first, second) : string_­type().
int compare(const sub_match& s) const;
Returns: str().compare(s.str()).
int compare(const string_type& s) const;
Returns: str().compare(s).
int compare(const value_type* s) const;
Returns: str().compare(s).

31.9.2 sub_­match non-member operators [re.submatch.op]

template <class BiIter> bool operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
Returns: lhs.compare(rhs) == 0.
template <class BiIter> bool operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
Returns: lhs.compare(rhs) != 0.
template <class BiIter> bool operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
Returns: lhs.compare(rhs) < 0.
template <class BiIter> bool operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
Returns: lhs.compare(rhs) <= 0.
template <class BiIter> bool operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
Returns: lhs.compare(rhs) >= 0.
template <class BiIter> bool operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
Returns: lhs.compare(rhs) > 0.
template <class BiIter, class ST, class SA> bool operator==( const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, const sub_match<BiIter>& rhs);
Returns:
rhs.compare(typename sub_match<BiIter>::string_type(lhs.data(), lhs.size())) == 0
template <class BiIter, class ST, class SA> bool operator!=( const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, const sub_match<BiIter>& rhs);
Returns: !(lhs == rhs).
template <class BiIter, class ST, class SA> bool operator<( const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, const sub_match<BiIter>& rhs);
Returns:
rhs.compare(typename sub_match<BiIter>::string_type(lhs.data(), lhs.size())) > 0
template <class BiIter, class ST, class SA> bool operator>( const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, const sub_match<BiIter>& rhs);
Returns: rhs < lhs.
template <class BiIter, class ST, class SA> bool operator>=( const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, const sub_match<BiIter>& rhs);
Returns: !(lhs < rhs).
template <class BiIter, class ST, class SA> bool operator<=( const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, const sub_match<BiIter>& rhs);
Returns: !(rhs < lhs).
template <class BiIter, class ST, class SA> bool operator==( const sub_match<BiIter>& lhs, const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
Returns:
lhs.compare(typename sub_match<BiIter>::string_type(rhs.data(), rhs.size())) == 0
template <class BiIter, class ST, class SA> bool operator!=( const sub_match<BiIter>& lhs, const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
Returns: !(lhs == rhs).
template <class BiIter, class ST, class SA> bool operator<( const sub_match<BiIter>& lhs, const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
Returns:
lhs.compare(typename sub_match<BiIter>::string_type(rhs.data(), rhs.size())) < 0
template <class BiIter, class ST, class SA> bool operator>( const sub_match<BiIter>& lhs, const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
Returns: rhs < lhs.
template <class BiIter, class ST, class SA> bool operator>=( const sub_match<BiIter>& lhs, const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
Returns: !(lhs < rhs).
template <class BiIter, class ST, class SA> bool operator<=( const sub_match<BiIter>& lhs, const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
Returns: !(rhs < lhs).
template <class BiIter> bool operator==(const typename iterator_traits<BiIter>::value_type* lhs, const sub_match<BiIter>& rhs);
Returns: rhs.compare(lhs) == 0.
template <class BiIter> bool operator!=(const typename iterator_traits<BiIter>::value_type* lhs, const sub_match<BiIter>& rhs);
Returns: !(lhs == rhs).
template <class BiIter> bool operator<(const typename iterator_traits<BiIter>::value_type* lhs, const sub_match<BiIter>& rhs);
Returns: rhs.compare(lhs) > 0.
template <class BiIter> bool operator>(const typename iterator_traits<BiIter>::value_type* lhs, const sub_match<BiIter>& rhs);
Returns: rhs < lhs.
template <class BiIter> bool operator>=(const typename iterator_traits<BiIter>::value_type* lhs, const sub_match<BiIter>& rhs);
Returns: !(lhs < rhs).
template <class BiIter> bool operator<=(const typename iterator_traits<BiIter>::value_type* lhs, const sub_match<BiIter>& rhs);
Returns: !(rhs < lhs).
template <class BiIter> bool operator==(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type* rhs);
Returns: lhs.compare(rhs) == 0.
template <class BiIter> bool operator!=(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type* rhs);
Returns: !(lhs == rhs).
template <class BiIter> bool operator<(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type* rhs);
Returns: lhs.compare(rhs) < 0.
template <class BiIter> bool operator>(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type* rhs);
Returns: rhs < lhs.
template <class BiIter> bool operator>=(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type* rhs);
Returns: !(lhs < rhs).
template <class BiIter> bool operator<=(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type* rhs);
Returns: !(rhs < lhs).
template <class BiIter> bool operator==(const typename iterator_traits<BiIter>::value_type& lhs, const sub_match<BiIter>& rhs);
Returns: rhs.compare(typename sub_­match<BiIter>​::​string_­type(1, lhs)) == 0.
template <class BiIter> bool operator!=(const typename iterator_traits<BiIter>::value_type& lhs, const sub_match<BiIter>& rhs);
Returns: !(lhs == rhs).
template <class BiIter> bool operator<(const typename iterator_traits<BiIter>::value_type& lhs, const sub_match<BiIter>& rhs);
Returns: rhs.compare(typename sub_­match<BiIter>​::​string_­type(1, lhs)) > 0.
template <class BiIter> bool operator>(const typename iterator_traits<BiIter>::value_type& lhs, const sub_match<BiIter>& rhs);
Returns: rhs < lhs.
template <class BiIter> bool operator>=(const typename iterator_traits<BiIter>::value_type& lhs, const sub_match<BiIter>& rhs);
Returns: !(lhs < rhs).
template <class BiIter> bool operator<=(const typename iterator_traits<BiIter>::value_type& lhs, const sub_match<BiIter>& rhs);
Returns: !(rhs < lhs).
template <class BiIter> bool operator==(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type& rhs);
Returns: lhs.compare(typename sub_­match<BiIter>​::​string_­type(1, rhs)) == 0.
template <class BiIter> bool operator!=(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type& rhs);
Returns: !(lhs == rhs).
template <class BiIter> bool operator<(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type& rhs);
Returns: lhs.compare(typename sub_­match<BiIter>​::​string_­type(1, rhs)) < 0.
template <class BiIter> bool operator>(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type& rhs);
Returns: rhs < lhs.
template <class BiIter> bool operator>=(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type& rhs);
Returns: !(lhs < rhs).
template <class BiIter> bool operator<=(const sub_match<BiIter>& lhs, const typename iterator_traits<BiIter>::value_type& rhs);
Returns: !(rhs < lhs).
template <class charT, class ST, class BiIter> basic_ostream<charT, ST>& operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);
Returns: os << m.str().

31.10 Class template match_­results [re.results]

Class template match_­results denotes a collection of character sequences representing the result of a regular expression match.
Storage for the collection is allocated and freed as necessary by the member functions of class template match_­results.
The class template match_­results satisfies the requirements of an allocator-aware container and of a sequence container ([container.requirements.general], [sequence.reqmts]) except that only operations defined for const-qualified sequence containers are supported and that the semantics of comparison functions are different from those required for a container.
A default-constructed match_­results object has no fully established result state.
A match result is ready when, as a consequence of a completed regular expression match modifying such an object, its result state becomes fully established.
The effects of calling most member functions from a match_­results object that is not ready are undefined.
The sub_­match object stored at index 0 represents sub-expression 0, i.e., the whole match. In this case the sub_­match member matched is always true.
The sub_­match object stored at index n denotes what matched the marked sub-expression n within the matched expression.
If the sub-expression n participated in a regular expression match then the sub_­match member matched evaluates to true, and members first and second denote the range of characters [first, second) which formed that match.
Otherwise matched is false, and members first and second point to the end of the sequence that was searched.
[Note
:
The sub_­match objects representing different sub-expressions that did not participate in a regular expression match need not be distinct.
end note
]
namespace std {
  template <class BidirectionalIterator,
            class Allocator = allocator<sub_match<BidirectionalIterator>>>
    class match_results {
    public:
      using value_type      = sub_match<BidirectionalIterator>;
      using const_reference = const value_type&;
      using reference       = value_type&;
      using const_iterator  = implementation-defined;
      using iterator        = const_iterator;
      using difference_type =
              typename iterator_traits<BidirectionalIterator>::difference_type;
      using size_type       = typename allocator_traits<Allocator>::size_type;
      using allocator_type  = Allocator;
      using char_type       =
              typename iterator_traits<BidirectionalIterator>::value_type;
      using string_type     = basic_string<char_type>;

      // [re.results.const], construct/copy/destroy
      explicit match_results(const Allocator& a = Allocator());
      match_results(const match_results& m);
      match_results(match_results&& m) noexcept;
      match_results& operator=(const match_results& m);
      match_results& operator=(match_results&& m);
      ~match_results();

      // [re.results.state], state
      bool ready() const;

      // [re.results.size], size
      size_type size() const;
      size_type max_size() const;
      bool empty() const;

      // [re.results.acc], element access
      difference_type length(size_type sub = 0) const;
      difference_type position(size_type sub = 0) const;
      string_type str(size_type sub = 0) const;
      const_reference operator[](size_type n) const;

      const_reference prefix() const;
      const_reference suffix() const;
      const_iterator begin() const;
      const_iterator end() const;
      const_iterator cbegin() const;
      const_iterator cend() const;

      // [re.results.form], format
      template <class OutputIter>
        OutputIter
          format(OutputIter out,
                 const char_type* fmt_first, const char_type* fmt_last,
                 regex_constants::match_flag_type flags = regex_constants::format_default) const;
      template <class OutputIter, class ST, class SA>
        OutputIter
          format(OutputIter out,
                 const basic_string<char_type, ST, SA>& fmt,
                 regex_constants::match_flag_type flags = regex_constants::format_default) const;
      template <class ST, class SA>
        basic_string<char_type, ST, SA>
          format(const basic_string<char_type, ST, SA>& fmt,
                 regex_constants::match_flag_type flags = regex_constants::format_default) const;
      string_type
        format(const char_type* fmt,
               regex_constants::match_flag_type flags = regex_constants::format_default) const;

      // [re.results.all], allocator
      allocator_type get_allocator() const;

      // [re.results.swap], swap
      void swap(match_results& that);
    };
}

31.10.1 match_­results constructors [re.results.const]

In all match_­results constructors, a copy of the Allocator argument shall be used for any memory allocation performed by the constructor or member functions during the lifetime of the object.
match_results(const Allocator& a = Allocator());
Effects: Constructs an object of class match_­results.
Postconditions: ready() returns false.
size() returns 0.
match_results(const match_results& m);
Effects: Constructs an object of class match_­results, as a copy of m.
match_results(match_results&& m) noexcept;
Effects: Move constructs an object of class match_­results from m satisfying the same postconditions as Table 129.
Additionally, the stored Allocator value is move constructed from m.get_­allocator().
Throws: Nothing.
match_results& operator=(const match_results& m);
Effects: Assigns m to *this.
The postconditions of this function are indicated in Table 129.
match_results& operator=(match_results&& m);
Effects: Move-assigns m to *this.
The postconditions of this function are indicated in Table 129.
Table 129match_­results assignment operator effects
Element
Value
ready()
m.ready()
size()
m.size()
str(n)
m.str(n) for all integers n < m.size()
prefix()
m.prefix()
suffix()
m.suffix()
(*this)[n]
m[n] for all integers n < m.size()
length(n)
m.length(n) for all integers n < m.size()
position(n)
m.position(n) for all integers n < m.size()

31.10.2 match_­results state [re.results.state]

bool ready() const;
Returns: true if *this has a fully established result state, otherwise false.

31.10.3 match_­results size [re.results.size]

size_type size() const;
Returns: One plus the number of marked sub-expressions in the regular expression that was matched if *this represents the result of a successful match.
Otherwise returns 0.
[Note
:
The state of a match_­results object can be modified only by passing that object to regex_­match or regex_­search.
Sections [re.alg.match] and [re.alg.search] specify the effects of those algorithms on their match_­results arguments.
end note
]
size_type max_size() const;
Returns: The maximum number of sub_­match elements that can be stored in *this.
bool empty() const;
Returns: size() == 0.

31.10.4 match_­results element access [re.results.acc]

difference_type length(size_type sub = 0) const;
Requires: ready() == true.
Returns: (*this)[sub].length().
difference_type position(size_type sub = 0) const;
Requires: ready() == true.
Returns: The distance from the start of the target sequence to (*this)[sub].first.
string_type str(size_type sub = 0) const;
Requires: ready() == true.
Returns: string_­type((*this)[sub]).
const_reference operator[](size_type n) const;
Requires: ready() == true.
Returns: A reference to the sub_­match object representing the character sequence that matched marked sub-expression n.
If n == 0 then returns a reference to a sub_­match object representing the character sequence that matched the whole regular expression.
If n >= size() then returns a sub_­match object representing an unmatched sub-expression.
const_reference prefix() const;
Requires: ready() == true.
Returns: A reference to the sub_­match object representing the character sequence from the start of the string being matched/searched to the start of the match found.
const_reference suffix() const;
Requires: ready() == true.
Returns: A reference to the sub_­match object representing the character sequence from the end of the match found to the end of the string being matched/searched.
const_iterator begin() const; const_iterator cbegin() const;
Returns: A starting iterator that enumerates over all the sub-expressions stored in *this.
const_iterator end() const; const_iterator cend() const;
Returns: A terminating iterator that enumerates over all the sub-expressions stored in *this.

31.10.5 match_­results formatting [re.results.form]

template <class OutputIter> OutputIter format( OutputIter out, const char_type* fmt_first, const char_type* fmt_last, regex_constants::match_flag_type flags = regex_constants::format_default) const;
Requires: ready() == true and OutputIter shall satisfy the requirements for an Output Iterator ([output.iterators]).
Effects: Copies the character sequence [fmt_­first, fmt_­last) to OutputIter out.
Replaces each format specifier or escape sequence in the copied range with either the character(s) it represents or the sequence of characters within *this to which it refers.
The bitmasks specified in flags determine which format specifiers and escape sequences are recognized.
Returns: out.
template <class OutputIter, class ST, class SA> OutputIter format( OutputIter out, const basic_string<char_type, ST, SA>& fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const;
Effects: Equivalent to:
return format(out, fmt.data(), fmt.data() + fmt.size(), flags);
template <class ST, class SA> basic_string<char_type, ST, SA> format( const basic_string<char_type, ST, SA>& fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const;
Requires: ready() == true.
Effects: Constructs an empty string result of type basic_­string<char_­type, ST, SA> and calls:
format(back_inserter(result), fmt, flags);
Returns: result.
string_type format( const char_type* fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const;
Requires: ready() == true.
Effects: Constructs an empty string result of type string_­type and calls:
format(back_inserter(result), fmt, fmt + char_traits<char_type>::length(fmt), flags);
Returns: result.

31.10.6 match_­results allocator [re.results.all]

allocator_type get_allocator() const;
Returns: A copy of the Allocator that was passed to the object's constructor or, if that allocator has been replaced, a copy of the most recent replacement.

31.10.7 match_­results swap [re.results.swap]

void swap(match_results& that);
Effects: Swaps the contents of the two sequences.
Postconditions: *this contains the sequence of matched sub-expressions that were in that, that contains the sequence of matched sub-expressions that were in *this.
Complexity: Constant time.
template <class BidirectionalIterator, class Allocator> void swap(match_results<BidirectionalIterator, Allocator>& m1, match_results<BidirectionalIterator, Allocator>& m2);
Effects: As if by m1.swap(m2).

31.10.8 match_­results non-member functions [re.results.nonmember]

template <class BidirectionalIterator, class Allocator> bool operator==(const match_results<BidirectionalIterator, Allocator>& m1, const match_results<BidirectionalIterator, Allocator>& m2);
Returns: true if neither match result is ready, false if one match result is ready and the other is not.
If both match results are ready, returns true only if:
  • m1.empty() && m2.empty(), or
  • !m1.empty() && !m2.empty(), and the following conditions are satisfied:
    • m1.prefix() == m2.prefix(),
    • m1.size() == m2.size() && equal(m1.begin(), m1.end(), m2.begin()), and
    • m1.suffix() == m2.suffix().
[Note
:
The algorithm equal is defined in Clause [algorithms].
end note
]
template <class BidirectionalIterator, class Allocator> bool operator!=(const match_results<BidirectionalIterator, Allocator>& m1, const match_results<BidirectionalIterator, Allocator>& m2);
Returns: !(m1 == m2).

31.11 Regular expression algorithms [re.alg]

31.11.1 Exceptions [re.except]

The algorithms described in this subclause may throw an exception of type regex_­error.
If such an exception e is thrown, e.code() shall return either regex_­constants​::​error_­complexity or regex_­constants​::​error_­stack.

31.11.2 regex_­match [re.alg.match]

template <class BidirectionalIterator, class Allocator, class charT, class traits> bool regex_match(BidirectionalIterator first, BidirectionalIterator last, match_results<BidirectionalIterator, Allocator>& m, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Requires: The type BidirectionalIterator shall satisfy the requirements of a Bidirectional Iterator ([bidirectional.iterators]).
Effects: Determines whether there is a match between the regular expression e, and all of the character sequence [first, last).
The parameter flags is used to control how the expression is matched against the character sequence.
When determining if there is a match, only potential matches that match the entire character sequence are considered.
Returns true if such a match exists, false otherwise.
[Example
:
std::regex re("Get|GetValue");
std::cmatch m;
regex_search("GetValue", m, re);	// returns true, and m[0] contains "Get"
regex_match ("GetValue", m, re);	// returns true, and m[0] contains "GetValue"
regex_search("GetValues", m, re);	// returns true, and m[0] contains "Get"
regex_match ("GetValues", m, re);	// returns false
end example
]
Postconditions: m.ready() == true in all cases.
If the function returns false, then the effect on parameter m is unspecified except that m.size() returns 0 and m.empty() returns true.
Otherwise the effects on parameter m are given in Table 130.
Table 130 — Effects of regex_­match algorithm
Element
Value
m.size()
1 + e.mark_­count()
m.empty()
false
m.prefix().first
first
m.prefix().second
first
m.prefix().matched
false
m.suffix().first
last
m.suffix().second
last
m.suffix().matched
false
m[0].first
first
m[0].second
last
m[0].matched
true
m[n].first
For all integers 0 < n < m.size(), the start of the sequence that matched sub-expression n.
Alternatively, if sub-expression n did not participate in the match, then last.
m[n].second
For all integers 0 < n < m.size(), the end of the sequence that matched sub-expression n.
Alternatively, if sub-expression n did not participate in the match, then last.
m[n].matched
For all integers 0 < n < m.size(), true if sub-expression n participated in the match, false otherwise.
template <class BidirectionalIterator, class charT, class traits> bool regex_match(BidirectionalIterator first, BidirectionalIterator last, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Effects: Behaves “as if” by constructing an instance of match_­results<BidirectionalIterator> what, and then returning the result of regex_­match(first, last, what, e, flags).
template <class charT, class Allocator, class traits> bool regex_match(const charT* str, match_results<const charT*, Allocator>& m, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­match(str, str + char_­traits<charT>​::​length(str), m, e, flags).
template <class ST, class SA, class Allocator, class charT, class traits> bool regex_match(const basic_string<charT, ST, SA>& s, match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­match(s.begin(), s.end(), m, e, flags).
template <class charT, class traits> bool regex_match(const charT* str, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­match(str, str + char_­traits<charT>​::​length(str), e, flags)
template <class ST, class SA, class charT, class traits> bool regex_match(const basic_string<charT, ST, SA>& s, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­match(s.begin(), s.end(), e, flags).

31.11.3 regex_­search [re.alg.search]

template <class BidirectionalIterator, class Allocator, class charT, class traits> bool regex_search(BidirectionalIterator first, BidirectionalIterator last, match_results<BidirectionalIterator, Allocator>& m, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Requires: Type BidirectionalIterator shall satisfy the requirements of a Bidirectional Iterator ([bidirectional.iterators]).
Effects: Determines whether there is some sub-sequence within [first, last) that matches the regular expression e.
The parameter flags is used to control how the expression is matched against the character sequence.
Returns true if such a sequence exists, false otherwise.
Postconditions: m.ready() == true in all cases.
If the function returns false, then the effect on parameter m is unspecified except that m.size() returns 0 and m.empty() returns true.
Otherwise the effects on parameter m are given in Table 131.
Table 131 — Effects of regex_­search algorithm
Element
Value
m.size()
1 + e.mark_­count()
m.empty()
false
m.prefix().first
first
m.prefix().second
m[0].first
m.prefix().matched
m.prefix().first != m.prefix().second
m.suffix().first
m[0].second
m.suffix().second
last
m.suffix().matched
m.suffix().first != m.suffix().second
m[0].first
The start of the sequence of characters that matched the regular expression
m[0].second
The end of the sequence of characters that matched the regular expression
m[0].matched
true
m[n].first
For all integers 0 < n < m.size(), the start of the sequence that matched sub-expression n.
Alternatively, if sub-expression n did not participate in the match, then last.
m[n].second
For all integers 0 < n < m.size(), the end of the sequence that matched sub-expression n.
Alternatively, if sub-expression n did not participate in the match, then last .
m[n].matched
For all integers 0 < n < m.size(), true if sub-expression n participated in the match, false otherwise.
template <class charT, class Allocator, class traits> bool regex_search(const charT* str, match_results<const charT*, Allocator>& m, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­search(str, str + char_­traits<charT>​::​length(str), m, e, flags).
template <class ST, class SA, class Allocator, class charT, class traits> bool regex_search(const basic_string<charT, ST, SA>& s, match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­search(s.begin(), s.end(), m, e, flags).
template <class BidirectionalIterator, class charT, class traits> bool regex_search(BidirectionalIterator first, BidirectionalIterator last, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Effects: Behaves “as if” by constructing an object what of type match_­results<BidirectionalIterator> and returning regex_­search(first, last, what, e, flags).
template <class charT, class traits> bool regex_search(const charT* str, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­search(str, str + char_­traits<charT>​::​length(str), e, flags).
template <class ST, class SA, class charT, class traits> bool regex_search(const basic_string<charT, ST, SA>& s, const basic_regex<charT, traits>& e, regex_constants::match_flag_type flags = regex_constants::match_default);
Returns: regex_­search(s.begin(), s.end(), e, flags).

31.11.4 regex_­replace [re.alg.replace]

template <class OutputIterator, class BidirectionalIterator, class traits, class charT, class ST, class SA> OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex<charT, traits>& e, const basic_string<charT, ST, SA>& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template <class OutputIterator, class BidirectionalIterator, class traits, class charT> OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex<charT, traits>& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default);
Effects: Constructs a regex_­iterator object i as if by
regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags)
and uses i to enumerate through all of the matches m of type match_­results<BidirectionalIterator> that occur within the sequence [first, last).
If no such matches are found and !(flags & regex_­constants​::​format_­no_­copy), then calls
out = copy(first, last, out)
If any matches are found then, for each such match:
  • If !(flags & regex_­constants​::​format_­no_­copy), calls
    out = copy(m.prefix().first, m.prefix().second, out)
  • Then calls
    out = m.format(out, fmt, flags)
    for the first form of the function and
    out = m.format(out, fmt, fmt + char_traits<charT>::length(fmt), flags)
    for the second.
Finally, if such a match is found and !(flags & regex_­constants​::​format_­no_­copy), calls
out = copy(last_m.suffix().first, last_m.suffix().second, out)
where last_­m is a copy of the last match found.
If flags & regex_­constants​::​format_­first_­only is nonzero, then only the first match found is replaced.
Returns: out.
template <class traits, class charT, class ST, class SA, class FST, class FSA> basic_string<charT, ST, SA> regex_replace(const basic_string<charT, ST, SA>& s, const basic_regex<charT, traits>& e, const basic_string<charT, FST, FSA>& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template <class traits, class charT, class ST, class SA> basic_string<charT, ST, SA> regex_replace(const basic_string<charT, ST, SA>& s, const basic_regex<charT, traits>& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default);
Effects: Constructs an empty string result of type basic_­string<charT, ST, SA> and calls:
regex_replace(back_inserter(result), s.begin(), s.end(), e, fmt, flags);
Returns: result.
template <class traits, class charT, class ST, class SA> basic_string<charT> regex_replace(const charT* s, const basic_regex<charT, traits>& e, const basic_string<charT, ST, SA>& fmt, regex_constants::match_flag_type flags = regex_constants::match_default); template <class traits, class charT> basic_string<charT> regex_replace(const charT* s, const basic_regex<charT, traits>& e, const charT* fmt, regex_constants::match_flag_type flags = regex_constants::match_default);
Effects: Constructs an empty string result of type basic_­string<charT> and calls:
regex_replace(back_inserter(result), s, s + char_traits<charT>::length(s), e, fmt, flags);
Returns: result.

31.12 Regular expression iterators [re.iter]

31.12.1 Class template regex_­iterator [re.regiter]

The class template regex_­iterator is an iterator adaptor.
It represents a new view of an existing iterator sequence, by enumerating all the occurrences of a regular expression within that sequence.
A regex_­iterator uses regex_­search to find successive regular expression matches within the sequence from which it was constructed.
After the iterator is constructed, and every time operator++ is used, the iterator finds and stores a value of match_­results<BidirectionalIterator>.
If the end of the sequence is reached (regex_­search returns false), the iterator becomes equal to the end-of-sequence iterator value.
The default constructor constructs an end-of-sequence iterator object, which is the only legitimate iterator to be used for the end condition.
The result of operator* on an end-of-sequence iterator is not defined.
For any other iterator value a const match_­results<BidirectionalIterator>& is returned.
The result of operator-> on an end-of-sequence iterator is not defined.
For any other iterator value a const match_­results<BidirectionalIterator>* is returned.
It is impossible to store things into regex_­iterators.
Two end-of-sequence iterators are always equal.
An end-of-sequence iterator is not equal to a non-end-of-sequence iterator.
Two non-end-of-sequence iterators are equal when they are constructed from the same arguments.
namespace std {
  template <class BidirectionalIterator,
            class charT = typename iterator_traits<BidirectionalIterator>::value_type,
            class traits = regex_traits<charT>>
    class regex_iterator {
    public:
      using regex_type        = basic_regex<charT, traits>;
      using iterator_category = forward_iterator_tag;
      using value_type        = match_results<BidirectionalIterator>;
      using difference_type   = ptrdiff_t;
      using pointer           = const value_type*;
      using reference         = const value_type&;

      regex_iterator();
      regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
                     const regex_type& re,
                     regex_constants::match_flag_type m = regex_constants::match_default);
      regex_iterator(BidirectionalIterator, BidirectionalIterator,
                     const regex_type&&,
                     regex_constants::match_flag_type = regex_constants::match_default) = delete;
      regex_iterator(const regex_iterator&);
      regex_iterator& operator=(const regex_iterator&);
      bool operator==(const regex_iterator&) const;
      bool operator!=(const regex_iterator&) const;
      const value_type& operator*() const;
      const value_type* operator->() const;
      regex_iterator& operator++();
      regex_iterator operator++(int);

    private:
      BidirectionalIterator                begin;  // exposition only
      BidirectionalIterator                end;    // exposition only
      const regex_type*                    pregex; // exposition only
      regex_constants::match_flag_type     flags;  // exposition only
      match_results<BidirectionalIterator> match;  // exposition only
    };
}
An object of type regex_­iterator that is not an end-of-sequence iterator holds a zero-length match if match[0].matched == true and match[0].first == match[0].second.
[Note
:
For example, this can occur when the part of the regular expression that matched consists only of an assertion (such as '^', '$', '\b', '\B').
end note
]

31.12.1.1 regex_­iterator constructors [re.regiter.cnstr]

regex_iterator();
Effects: Constructs an end-of-sequence iterator.
regex_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, regex_constants::match_flag_type m = regex_constants::match_default);
Effects: Initializes begin and end to a and b, respectively, sets pregex to &re, sets flags to m, then calls regex_­search(begin, end, match, *pregex, flags).
If this call returns false the constructor sets *this to the end-of-sequence iterator.

31.12.1.2 regex_­iterator comparisons [re.regiter.comp]

bool operator==(const regex_iterator& right) const;
Returns: true if *this and right are both end-of-sequence iterators or if the following conditions all hold:
  • begin == right.begin,
  • end == right.end,
  • pregex == right.pregex,
  • flags == right.flags, and
  • match[0] == right.match[0];
otherwise false.
bool operator!=(const regex_iterator& right) const;
Returns: !(*this == right).

31.12.1.3 regex_­iterator indirection [re.regiter.deref]

const value_type& operator*() const;
Returns: match.
const value_type* operator->() const;
Returns:&match.

31.12.1.4 regex_­iterator increment [re.regiter.incr]

regex_iterator& operator++();
Effects: Constructs a local variable start of type BidirectionalIterator and initializes it with the value of match[0].second.
If the iterator holds a zero-length match and start == end the operator sets *this to the end-of-sequence iterator and returns *this.
Otherwise, if the iterator holds a zero-length match, the operator calls:
regex_search(start, end, match, *pregex,
             flags | regex_constants::match_not_null | regex_constants::match_continuous)
If the call returns true the operator returns *this.
Otherwise the operator increments start and continues as if the most recent match was not a zero-length match.
If the most recent match was not a zero-length match, the operator sets flags to flags | regex_­constants​::​match_­prev_­avail and calls regex_­search(start, end, match, *pregex, flags).
If the call returns false the iterator sets *this to the end-of-sequence iterator.
The iterator then returns *this.
In all cases in which the call to regex_­search returns true, match.prefix().first shall be equal to the previous value of match[0].second, and for each index i in the half-open range [0, match.size()) for which match[i].matched is true, match.position(i) shall return distance(begin, match[i].​first).
[Note
:
This means that match.position(i) gives the offset from the beginning of the target sequence, which is often not the same as the offset from the sequence passed in the call to regex_­search.
end note
]
It is unspecified how the implementation makes these adjustments.
[Note
:
This means that a compiler may call an implementation-specific search function, in which case a user-defined specialization of regex_­search will not be called.
end note
]
regex_iterator operator++(int);
Effects: As if by:
regex_iterator tmp = *this;
++(*this);
return tmp;

31.12.2 Class template regex_­token_­iterator [re.tokiter]

The class template regex_­token_­iterator is an iterator adaptor; that is to say it represents a new view of an existing iterator sequence, by enumerating all the occurrences of a regular expression within that sequence, and presenting one or more sub-expressions for each match found.
Each position enumerated by the iterator is a sub_­match class template instance that represents what matched a particular sub-expression within the regular expression.
When class regex_­token_­iterator is used to enumerate a single sub-expression with index -1 the iterator performs field splitting: that is to say it enumerates one sub-expression for each section of the character container sequence that does not match the regular expression specified.
After it is constructed, the iterator finds and stores a value regex_­iterator<BidirectionalIterator> position and sets the internal count N to zero.
It also maintains a sequence subs which contains a list of the sub-expressions which will be enumerated.
Every time operator++ is used the count N is incremented; if N exceeds or equals subs.size(), then the iterator increments member position and sets count N to zero.
If the end of sequence is reached (position is equal to the end of sequence iterator), the iterator becomes equal to the end-of-sequence iterator value, unless the sub-expression being enumerated has index -1, in which case the iterator enumerates one last sub-expression that contains all the characters from the end of the last regular expression match to the end of the input sequence being enumerated, provided that this would not be an empty sub-expression.
The default constructor constructs an end-of-sequence iterator object, which is the only legitimate iterator to be used for the end condition.
The result of operator* on an end-of-sequence iterator is not defined.
For any other iterator value a const sub_­match<BidirectionalIterator>& is returned.
The result of operator-> on an end-of-sequence iterator is not defined.
For any other iterator value a const sub_­match<BidirectionalIterator>* is returned.
It is impossible to store things into regex_­token_­iterators.
Two end-of-sequence iterators are always equal.
An end-of-sequence iterator is not equal to a non-end-of-sequence iterator.
Two non-end-of-sequence iterators are equal when they are constructed from the same arguments.
namespace std {
  template <class BidirectionalIterator,
            class charT = typename iterator_traits<BidirectionalIterator>::value_type,
            class traits = regex_traits<charT>>
    class regex_token_iterator {
    public:
      using regex_type        = basic_regex<charT, traits>;
      using iterator_category = forward_iterator_tag;
      using value_type        = sub_match<BidirectionalIterator>;
      using difference_type   = ptrdiff_t;
      using pointer           = const value_type*;
      using reference         = const value_type&;

      regex_token_iterator();
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type& re,
                           int submatch = 0,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default);
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type& re,
                           const vector<int>& submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default);
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type& re,
                           initializer_list<int> submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default);
      template <size_t N>
        regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                             const regex_type& re,
                             const int (&submatches)[N],
                             regex_constants::match_flag_type m =
                               regex_constants::match_default);
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           int submatch = 0,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           const vector<int>& submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           initializer_list<int> submatches,
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      template <size_t N>
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type&& re,
                           const int (&submatches)[N],
                           regex_constants::match_flag_type m =
                             regex_constants::match_default) = delete;
      regex_token_iterator(const regex_token_iterator&);
      regex_token_iterator& operator=(const regex_token_iterator&);
      bool operator==(const regex_token_iterator&) const;
      bool operator!=(const regex_token_iterator&) const;
      const value_type& operator*() const;
      const value_type* operator->() const;
      regex_token_iterator& operator++();
      regex_token_iterator operator++(int);

    private:
      using position_iterator =
            regex_iterator<BidirectionalIterator, charT, traits>; // exposition only
      position_iterator position;                                 // exposition only
      const value_type* result;                                   // exposition only
      value_type suffix;                                          // exposition only
      size_t N;                                                   // exposition only
      vector<int> subs;                                           // exposition only
    };
}
A suffix iterator is a regex_­token_­iterator object that points to a final sequence of characters at the end of the target sequence.
In a suffix iterator the member result holds a pointer to the data member suffix, the value of the member suffix.match is true, suffix.first points to the beginning of the final sequence, and suffix.second points to the end of the final sequence.
[Note
:
For a suffix iterator, data member suffix.first is the same as the end of the last match found, and suffix​.second is the same as the end of the target sequence
end note
]
The current match is (*position).prefix() if subs[N] == -1, or (*position)[subs[N]] for any other value of subs[N].

31.12.2.1 regex_­token_­iterator constructors [re.tokiter.cnstr]

regex_token_iterator();
Effects: Constructs the end-of-sequence iterator.
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default); regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, const vector<int>& submatches, regex_constants::match_flag_type m = regex_constants::match_default); regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, initializer_list<int> submatches, regex_constants::match_flag_type m = regex_constants::match_default); template <size_t N> regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, const int (&submatches)[N], regex_constants::match_flag_type m = regex_constants::match_default);
Requires: Each of the initialization values of submatches shall be >= -1.
Effects: The first constructor initializes the member subs to hold the single value submatch.
The second constructor initializes the member subs to hold a copy of the argument submatches.
The third and fourth constructors initialize the member subs to hold a copy of the sequence of integer values pointed to by the iterator range [submatches.begin(), submatches.end()) and [&submatches, &submatches + N), respectively.
Each constructor then sets N to 0, and position to position_­iterator(a, b, re, m).
If position is not an end-of-sequence iterator the constructor sets result to the address of the current match.
Otherwise if any of the values stored in subs is equal to -1 the constructor sets *this to a suffix iterator that points to the range [a, b), otherwise the constructor sets *this to an end-of-sequence iterator.

31.12.2.2 regex_­token_­iterator comparisons [re.tokiter.comp]

bool operator==(const regex_token_iterator& right) const;
Returns: true if *this and right are both end-of-sequence iterators, or if *this and right are both suffix iterators and suffix == right.suffix; otherwise returns false if *this or right is an end-of-sequence iterator or a suffix iterator.
Otherwise returns true if position == right.position, N == right.N, and subs == right.subs.
Otherwise returns false.
bool operator!=(const regex_token_iterator& right) const;
Returns: !(*this == right).

31.12.2.3 regex_­token_­iterator indirection [re.tokiter.deref]

const value_type& operator*() const;
Returns: *result.
const value_type* operator->() const;
Returns: result.

31.12.2.4 regex_­token_­iterator increment [re.tokiter.incr]

regex_token_iterator& operator++();
Effects: Constructs a local variable prev of type position_­iterator, initialized with the value of position.
If *this is a suffix iterator, sets *this to an end-of-sequence iterator.
Otherwise, if N + 1 < subs.size(), increments N and sets result to the address of the current match.
Otherwise, sets N to 0 and increments position.
If position is not an end-of-sequence iterator the operator sets result to the address of the current match.
Otherwise, if any of the values stored in subs is equal to -1 and prev->suffix().length() is not 0 the operator sets *this to a suffix iterator that points to the range [prev->suffix().first, prev->suffix().second).
Otherwise, sets *this to an end-of-sequence iterator.
Returns: *this
regex_token_iterator& operator++(int);
Effects: Constructs a copy tmp of *this, then calls ++(*this).
Returns: tmp.

31.13 Modified ECMAScript regular expression grammar [re.grammar]

The regular expression grammar recognized by basic_­regex objects constructed with the ECMAScript flag is that specified by ECMA-262, except as specified below.
Objects of type specialization of basic_­regex store within themselves a default-constructed instance of their traits template parameter, henceforth referred to as traits_­inst.
This traits_­inst object is used to support localization of the regular expression; basic_­regex member functions shall not call any locale dependent C or C++ API, including the formatted string input functions.
Instead they shall call the appropriate traits member function to achieve the required effect.
The following productions within the ECMAScript grammar are modified as follows:
ClassAtom ::
  -
  ClassAtomNoDash
  ClassAtomExClass
  ClassAtomCollatingElement
  ClassAtomEquivalence

IdentityEscape ::
  SourceCharacter but not c
The following new productions are then added:
ClassAtomExClass ::
  [: ClassName :]

ClassAtomCollatingElement ::
  [. ClassName .]

ClassAtomEquivalence ::
  [= ClassName =]

ClassName ::
  ClassNameCharacter
  ClassNameCharacter ClassName

ClassNameCharacter ::
  SourceCharacter but not one of "." "=" ":"
The productions ClassAtomExClass, ClassAtomCollatingElement and ClassAtomEquivalence provide functionality equivalent to that of the same features in regular expressions in POSIX.
The regular expression grammar may be modified by any regex_­constants​::​syntax_­option_­type flags specified when constructing an object of type specialization of basic_­regex according to the rules in Table 125.
A ClassName production, when used in ClassAtomExClass, is not valid if traits_­inst.lookup_­classname returns zero for that name.
The names recognized as valid ClassNames are determined by the type of the traits class, but at least the following names shall be recognized: alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit, d, s, w.
In addition the following expressions shall be equivalent:
\d and [[:digit:]]

\D and [^[:digit:]]

\s and [[:space:]]

\S and [^[:space:]]

\w and [_[:alnum:]]

\W and [^_[:alnum:]]
A ClassName production when used in a ClassAtomCollatingElement production is not valid if the value returned by traits_­inst.lookup_­collatename for that name is an empty string.
The results from multiple calls to traits_­inst.lookup_­classname can be bitwise OR'ed together and subsequently passed to traits_­inst.isctype.
A ClassName production when used in a ClassAtomEquivalence production is not valid if the value returned by traits_­inst.lookup_­collatename for that name is an empty string or if the value returned by traits_­inst​.transform_­primary for the result of the call to traits_­inst.lookup_­collatename is an empty string.
When the sequence of characters being transformed to a finite state machine contains an invalid class name the translator shall throw an exception object of type regex_­error.
If the CV of a UnicodeEscapeSequence is greater than the largest value that can be held in an object of type charT the translator shall throw an exception object of type regex_­error.
[Note
:
This means that values of the form "uxxxx" that do not fit in a character are invalid.
end note
]
Where the regular expression grammar requires the conversion of a sequence of characters to an integral value, this is accomplished by calling traits_­inst.value.
The behavior of the internal finite state machine representation when used to match a sequence of characters is as described in ECMA-262.
The behavior is modified according to any match_flag_type flags ([re.matchflag]) specified when using the regular expression object in one of the regular expression algorithms ([re.alg]).
The behavior is also localized by interaction with the traits class template parameter as follows:
  • During matching of a regular expression finite state machine against a sequence of characters, two characters c and d are compared using the following rules:
    • if (flags() & regex_­constants​::​icase) the two characters are equal if traits_­inst.translate_­nocase(c) == traits_­inst.translate_­nocase(d);
    • otherwise, if flags() & regex_­constants​::​collate the two characters are equal if traits_­inst​.translate(c) == traits_­inst​.translate(d);
    • otherwise, the two characters are equal if c == d.
  • During matching of a regular expression finite state machine against a sequence of characters, comparison of a collating element range c1-c2 against a character c is conducted as follows: if flags() & regex_­constants​::​collate is false then the character c is matched if c1 <= c && c <= c2, otherwise c is matched in accordance with the following algorithm:
    string_type str1 = string_type(1,
      flags() & icase ?
        traits_inst.translate_nocase(c1) : traits_inst.translate(c1);
    string_type str2 = string_type(1,
      flags() & icase ?
        traits_inst.translate_nocase(c2) : traits_inst.translate(c2);
    string_type str = string_type(1,
      flags() & icase ?
        traits_inst.translate_nocase(c) : traits_inst.translate(c);
    return traits_inst.transform(str1.begin(), str1.end())
          <= traits_inst.transform(str.begin(), str.end())
      && traits_inst.transform(str.begin(), str.end())
          <= traits_inst.transform(str2.begin(), str2.end());
  • During matching of a regular expression finite state machine against a sequence of characters, testing whether a collating element is a member of a primary equivalence class is conducted by first converting the collating element and the equivalence class to sort keys using traits​::​transform_­primary, and then comparing the sort keys for equality.
  • During matching of a regular expression finite state machine against a sequence of characters, a character c is a member of a character class designated by an iterator range [first, last) if traits_­inst.isctype(c, traits_­inst.lookup_­classname(first, last, flags() & icase)) is true.

32 Atomic operations library [atomics]

32.1 General [atomics.general]

This Clause describes components for fine-grained atomic access.
This access is provided via operations on atomic objects.
The following subclauses describe atomics requirements and components for types and operations, as summarized below.
Table 132 — Atomics library summary
Subclause
Header(s)
Order and Consistency
Lock-free Property
Atomic Types
<atomic>
Operations on Atomic Types
Flag Type and Operations
Fences

32.2 Header <atomic> synopsis [atomics.syn]

namespace std {
  // [atomics.order], order and consistency
  enum memory_order;
  template <class T>
    T kill_dependency(T y) noexcept;

  // [atomics.lockfree], lock-free property
  #define ATOMIC_BOOL_LOCK_FREE unspecified
  #define ATOMIC_CHAR_LOCK_FREE unspecified
  #define ATOMIC_CHAR16_T_LOCK_FREE unspecified
  #define ATOMIC_CHAR32_T_LOCK_FREE unspecified
  #define ATOMIC_WCHAR_T_LOCK_FREE unspecified
  #define ATOMIC_SHORT_LOCK_FREE unspecified
  #define ATOMIC_INT_LOCK_FREE unspecified
  #define ATOMIC_LONG_LOCK_FREE unspecified
  #define ATOMIC_LLONG_LOCK_FREE unspecified
  #define ATOMIC_POINTER_LOCK_FREE unspecified

  // [atomics.types.generic], atomic
  template<class T> struct atomic;
  // [atomics.types.pointer], partial specialization for pointers
  template<class T> struct atomic<T*>;

  // [atomics.nonmembers], non-member functions
  template<class T>
    bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
  template<class T>
    bool atomic_is_lock_free(const atomic<T>*) noexcept;
  template<class T>
    void atomic_init(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_init(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template<class T>
    void atomic_store_explicit(atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template<class T>
    T atomic_load(const volatile atomic<T>*) noexcept;
  template<class T>
    T atomic_load(const atomic<T>*) noexcept;
  template<class T>
    T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
  template<class T>
    T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
  template<class T>
    T atomic_exchange(volatile atomic<T>*, T) noexcept;
  template<class T>
    T atomic_exchange(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    T atomic_exchange_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template<class T>
    T atomic_exchange_explicit(atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template<class T>
    bool atomic_compare_exchange_weak(volatile atomic<T>*,
                                      typename atomic<T>::value_type*,
                                      typename atomic<T>::value_type) noexcept;
  template<class T>
    bool atomic_compare_exchange_weak(atomic<T>*,
                                      typename atomic<T>::value_type*,
                                      typename atomic<T>::value_type) noexcept;
  template<class T>
    bool atomic_compare_exchange_strong(volatile atomic<T>*,
                                        typename atomic<T>::value_type*,
                                        typename atomic<T>::value_type) noexcept;
  template<class T>
    bool atomic_compare_exchange_strong(atomic<T>*,
                                        typename atomic<T>::value_type*,
                                        typename atomic<T>::value_type) noexcept;
  template<class T>
    bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*,
                                               typename atomic<T>::value_type*,
                                               typename atomic<T>::value_type,
                                               memory_order, memory_order) noexcept;
  template<class T>
    bool atomic_compare_exchange_weak_explicit(atomic<T>*,
                                               typename atomic<T>::value_type*,
                                               typename atomic<T>::value_type,
                                               memory_order, memory_order) noexcept;
  template<class T>
    bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*,
                                                 typename atomic<T>::value_type*,
                                                 typename atomic<T>::value_type,
                                                 memory_order, memory_order) noexcept;
  template<class T>
    bool atomic_compare_exchange_strong_explicit(atomic<T>*,
                                                 typename atomic<T>::value_type*,
                                                 typename atomic<T>::value_type,
                                                 memory_order, memory_order) noexcept;

  template <class T>
    T atomic_fetch_add(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template <class T>
    T atomic_fetch_add(atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template <class T>
    T atomic_fetch_add_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
  template <class T>
    T atomic_fetch_add_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
  template <class T>
    T atomic_fetch_sub(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template <class T>
    T atomic_fetch_sub(atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template <class T>
    T atomic_fetch_sub_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
  template <class T>
    T atomic_fetch_sub_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
  template <class T>
    T atomic_fetch_and(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template <class T>
    T atomic_fetch_and(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template <class T>
    T atomic_fetch_and_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
  template <class T>
    T atomic_fetch_and_explicit(atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
  template <class T>
    T atomic_fetch_or(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template <class T>
    T atomic_fetch_or(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template <class T>
    T atomic_fetch_or_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template <class T>
    T atomic_fetch_or_explicit(atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template <class T>
    T atomic_fetch_xor(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template <class T>
    T atomic_fetch_xor(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template <class T>
    T atomic_fetch_xor_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
  template <class T>
    T atomic_fetch_xor_explicit(atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;

  // [atomics.types.operations], initialization
  #define ATOMIC_VAR_INIT(value) see below

  // [atomics.alias], type aliases
  using atomic_bool           = atomic<bool>;
  using atomic_char           = atomic<char>;
  using atomic_schar          = atomic<signed char>;
  using atomic_uchar          = atomic<unsigned char>;
  using atomic_short          = atomic<short>;
  using atomic_ushort         = atomic<unsigned short>;
  using atomic_int            = atomic<int>;
  using atomic_uint           = atomic<unsigned int>;
  using atomic_long           = atomic<long>;
  using atomic_ulong          = atomic<unsigned long>;
  using atomic_llong          = atomic<long long>;
  using atomic_ullong         = atomic<unsigned long long>;
  using atomic_char16_t       = atomic<char16_t>;
  using atomic_char32_t       = atomic<char32_t>;
  using atomic_wchar_t        = atomic<wchar_t>;

  using atomic_int8_t         = atomic<int8_t>;
  using atomic_uint8_t        = atomic<uint8_t>;
  using atomic_int16_t        = atomic<int16_t>;
  using atomic_uint16_t       = atomic<uint16_t>;
  using atomic_int32_t        = atomic<int32_t>;
  using atomic_uint32_t       = atomic<uint32_t>;
  using atomic_int64_t        = atomic<int64_t>;
  using atomic_uint64_t       = atomic<uint64_t>;

  using atomic_int_least8_t   = atomic<int_least8_t>;
  using atomic_uint_least8_t  = atomic<uint_least8_t>;
  using atomic_int_least16_t  = atomic<int_least16_t>;
  using atomic_uint_least16_t = atomic<uint_least16_t>;
  using atomic_int_least32_t  = atomic<int_least32_t>;
  using atomic_uint_least32_t = atomic<uint_least32_t>;
  using atomic_int_least64_t  = atomic<int_least64_t>;
  using atomic_uint_least64_t = atomic<uint_least64_t>;

  using atomic_int_fast8_t    = atomic<int_fast8_t>;
  using atomic_uint_fast8_t   = atomic<uint_fast8_t>;
  using atomic_int_fast16_t   = atomic<int_fast16_t>;
  using atomic_uint_fast16_t  = atomic<uint_fast16_t>;
  using atomic_int_fast32_t   = atomic<int_fast32_t>;
  using atomic_uint_fast32_t  = atomic<uint_fast32_t>;
  using atomic_int_fast64_t   = atomic<int_fast64_t>;
  using atomic_uint_fast64_t  = atomic<uint_fast64_t>;

  using atomic_intptr_t       = atomic<intptr_t>;
  using atomic_uintptr_t      = atomic<uintptr_t>;
  using atomic_size_t         = atomic<size_t>;
  using atomic_ptrdiff_t      = atomic<ptrdiff_t>;
  using atomic_intmax_t       = atomic<intmax_t>;
  using atomic_uintmax_t      = atomic<uintmax_t>;

  // [atomics.flag], flag type and operations
  struct atomic_flag;
  bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;
  bool atomic_flag_test_and_set(atomic_flag*) noexcept;
  bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept;
  bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept;
  void atomic_flag_clear(volatile atomic_flag*) noexcept;
  void atomic_flag_clear(atomic_flag*) noexcept;
  void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept;
  void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept;
  #define ATOMIC_FLAG_INIT see below

  // [atomics.fences], fences
  extern "C" void atomic_thread_fence(memory_order) noexcept;
  extern "C" void atomic_signal_fence(memory_order) noexcept;
}

32.3 Type aliases [atomics.alias]

The type aliases atomic_­intN_­t, atomic_­uintN_­t, atomic_­intptr_­t, and atomic_­uintptr_­t are defined if and only if intN_­t, uintN_­t, intptr_­t, and uintptr_­t are defined, respectively.

32.4 Order and consistency [atomics.order]

namespace std {
  enum memory_order {
    memory_order_relaxed, memory_order_consume, memory_order_acquire,
    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
  };
}
The enumeration memory_­order specifies the detailed regular (non-atomic) memory synchronization order as defined in [intro.multithread] and may provide for operation ordering.
Its enumerated values and their meanings are as follows:
  • memory_­order_­relaxed: no operation orders memory.
  • memory_­order_­release, memory_­order_­acq_­rel, and memory_­order_­seq_­cst: a store operation performs a release operation on the affected memory location.
  • memory_­order_­consume: a load operation performs a consume operation on the affected memory location.
    [Note
    :
    Prefer memory_­order_­acquire, which provides stronger guarantees than memory_­order_­consume.
    Implementations have found it infeasible to provide performance better than that of memory_­order_­acquire.
    Specification revisions are under consideration.
    end note
    ]
  • memory_­order_­acquire, memory_­order_­acq_­rel, and memory_­order_­seq_­cst: a load operation performs an acquire operation on the affected memory location.
[Note
:
Atomic operations specifying memory_­order_­relaxed are relaxed with respect to memory ordering.
Implementations must still guarantee that any given atomic access to a particular atomic object be indivisible with respect to all other atomic accesses to that object.
end note
]
An atomic operation A that performs a release operation on an atomic object M synchronizes with an atomic operation B that performs an acquire operation on M and takes its value from any side effect in the release sequence headed by A.
There shall be a single total order S on all memory_­order_­seq_­cst operations, consistent with the “happens before” order and modification orders for all affected locations, such that each memory_­order_­seq_­cst operation B that loads a value from an atomic object M observes one of the following values:
  • the result of the last modification A of M that precedes B in S, if it exists, or
  • if A exists, the result of some modification of M that is not memory_­order_­seq_­cst and that does not happen before A, or
  • if A does not exist, the result of some modification of M that is not memory_­order_­seq_­cst.
[Note
:
Although it is not explicitly required that S include locks, it can always be extended to an order that does include lock and unlock operations, since the ordering between those is already included in the “happens before” ordering.
end note
]
For an atomic operation B that reads the value of an atomic object M, if there is a memory_­order_­seq_­cst fence X sequenced before B, then B observes either the last memory_­order_­seq_­cst modification of M preceding X in the total order S or a later modification of M in its modification order.
For atomic operations A and B on an atomic object M, where A modifies M and B takes its value, if there is a memory_­order_­seq_­cst fence X such that A is sequenced before X and B follows X in S, then B observes either the effects of A or a later modification of M in its modification order.
For atomic operations A and B on an atomic object M, where A modifies M and B takes its value, if there are memory_­order_­seq_­cst fences X and Y such that A is sequenced before X, Y is sequenced before B, and X precedes Y in S, then B observes either the effects of A or a later modification of M in its modification order.
For atomic modifications A and B of an atomic object M, B occurs later than A in the modification order of M if:
  • there is a memory_­order_­seq_­cst fence X such that A is sequenced before X, and X precedes B in S, or
  • there is a memory_­order_­seq_­cst fence Y such that Y is sequenced before B, and A precedes Y in S, or
  • there are memory_­order_­seq_­cst fences X and Y such that A is sequenced before X, Y is sequenced before B, and X precedes Y in S.
[Note
:
memory_­order_­seq_­cst ensures sequential consistency only for a program that is free of data races and uses exclusively memory_­order_­seq_­cst operations.
Any use of weaker ordering will invalidate this guarantee unless extreme care is used.
In particular, memory_­order_­seq_­cst fences ensure a total order only for the fences themselves.
Fences cannot, in general, be used to restore sequential consistency for atomic operations with weaker ordering specifications.
end note
]
Implementations should ensure that no “out-of-thin-air” values are computed that circularly depend on their own computation.
[Note
:
For example, with x and y initially zero,
// Thread 1:
r1 = y.load(memory_order_relaxed);
x.store(r1, memory_order_relaxed);
// Thread 2:
r2 = x.load(memory_order_relaxed);
y.store(r2, memory_order_relaxed);
should not produce r1 == r2 == 42, since the store of 42 to y is only possible if the store to x stores 42, which circularly depends on the store to y storing 42.
Note that without this restriction, such an execution is possible.
end note
]
[Note
:
The recommendation similarly disallows r1 == r2 == 42 in the following example, with x and y again initially zero:
// Thread 1:
r1 = x.load(memory_order_relaxed);
if (r1 == 42) y.store(42, memory_order_relaxed);
// Thread 2:
r2 = y.load(memory_order_relaxed);
if (r2 == 42) x.store(42, memory_order_relaxed);
end note
]
Atomic read-modify-write operations shall always read the last value (in the modification order) written before the write associated with the read-modify-write operation.
Implementations should make atomic stores visible to atomic loads within a reasonable amount of time.
template <class T> T kill_dependency(T y) noexcept;
Effects: The argument does not carry a dependency to the return value ([intro.multithread]).
Returns: y.

32.5 Lock-free property [atomics.lockfree]

#define ATOMIC_BOOL_LOCK_FREE unspecified
#define ATOMIC_CHAR_LOCK_FREE unspecified
#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
#define ATOMIC_SHORT_LOCK_FREE unspecified
#define ATOMIC_INT_LOCK_FREE unspecified
#define ATOMIC_LONG_LOCK_FREE unspecified
#define ATOMIC_LLONG_LOCK_FREE unspecified
#define ATOMIC_POINTER_LOCK_FREE unspecified
The ATOMIC_­..._­LOCK_­FREE macros indicate the lock-free property of the corresponding atomic types, with the signed and unsigned variants grouped together.
The properties also apply to the corresponding (partial) specializations of the atomic template.
A value of 0 indicates that the types are never lock-free.
A value of 1 indicates that the types are sometimes lock-free.
A value of 2 indicates that the types are always lock-free.
The function atomic_­is_­lock_­free ([atomics.types.operations]) indicates whether the object is lock-free.
In any given program execution, the result of the lock-free query shall be consistent for all pointers of the same type.
Atomic operations that are not lock-free are considered to potentially block ([intro.progress]).
[Note
:
Operations that are lock-free should also be address-free.
That is, atomic operations on the same memory location via two different addresses will communicate atomically.
The implementation should not depend on any per-process state.
This restriction enables communication by memory that is mapped into a process more than once and by memory that is shared between two processes.
end note
]

32.6 Class template atomic [atomics.types.generic]

namespace std {
  template <class T> struct atomic {
    using value_type = T;
    static constexpr bool is_always_lock_free = implementation-defined;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(T, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(T, memory_order = memory_order_seq_cst) noexcept;
    T load(memory_order = memory_order_seq_cst) const volatile noexcept;
    T load(memory_order = memory_order_seq_cst) const noexcept;
    operator T() const volatile noexcept;
    operator T() const noexcept;
    T exchange(T, memory_order = memory_order_seq_cst) volatile noexcept;
    T exchange(T, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept;
    bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept;
    bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst) noexcept;

    atomic() noexcept = default;
    constexpr atomic(T) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    T operator=(T) volatile noexcept;
    T operator=(T) noexcept;
  };
}
The template argument for T shall be trivially copyable ([basic.types]).
[Note
:
Type arguments that are not also statically initializable may be difficult to use.
end note
]
The specialization atomic<bool> is a standard-layout struct.
[Note
:
The representation of an atomic specialization need not have the same size as its corresponding argument type.
Specializations should have the same size whenever possible, as this reduces the effort required to port existing code.
end note
]

32.6.1 Operations on atomic types [atomics.types.operations]

[Note
:
Many operations are volatile-qualified.
The “volatile as device register” semantics have not changed in the standard.
This qualification means that volatility is preserved when applying these operations to volatile objects.
It does not mean that operations on non-volatile objects become volatile.
end note
]
atomic() noexcept = default;
Effects: Leaves the atomic object in an uninitialized state.
[Note
:
These semantics ensure compatibility with C.
end note
]
constexpr atomic(T desired) noexcept;
Effects: Initializes the object with the value desired.
Initialization is not an atomic operation ([intro.multithread]).
[Note
:
It is possible to have an access to an atomic object A race with its construction, for example by communicating the address of the just-constructed object A to another thread via memory_­order_­relaxed operations on a suitable atomic pointer variable, and then immediately accessing A in the receiving thread.
This results in undefined behavior.
end note
]
#define ATOMIC_VAR_INIT(value) see below
The macro expands to a token sequence suitable for constant initialization of an atomic variable of static storage duration of a type that is initialization-compatible with value.
[Note
:
This operation may need to initialize locks.
end note
]
Concurrent access to the variable being initialized, even via an atomic operation, constitutes a data race.
[Example
:
atomic<int> v = ATOMIC_VAR_INIT(5);
end example
]
static constexpr bool is_always_lock_free = implementation-defined;
The static data member is_­always_­lock_­free is true if the atomic type's operations are always lock-free, and false otherwise.
[Note
:
The value of is_­always_­lock_­free is consistent with the value of the corresponding ATOMIC_­..._­LOCK_­FREE macro, if defined.
end note
]
bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept;
Returns: true if the object's operations are lock-free, false otherwise.
[Note
:
The return value of the is_­lock_­free member function is consistent with the value of is_­always_­lock_­free for the same type.
end note
]
void store(T desired, memory_order order = memory_order_seq_cst) volatile noexcept; void store(T desired, memory_order order = memory_order_seq_cst) noexcept;
Requires: The order argument shall not be memory_­order_­consume, memory_­order_­acquire, nor memory_­order_­acq_­rel.
Effects: Atomically replaces the value pointed to by this with the value of desired.
Memory is affected according to the value of order.
T operator=(T desired) volatile noexcept; T operator=(T desired) noexcept;
Effects: Equivalent to: store(desired).
Returns: desired.
T load(memory_order order = memory_order_seq_cst) const volatile noexcept; T load(memory_order order = memory_order_seq_cst) const noexcept;
Requires: The order argument shall not be memory_­order_­release nor memory_­order_­acq_­rel.
Effects: Memory is affected according to the value of order.
Returns: Atomically returns the value pointed to by this.
operator T() const volatile noexcept; operator T() const noexcept;
Effects: Equivalent to: return load();
T exchange(T desired, memory_order order = memory_order_seq_cst) volatile noexcept; T exchange(T desired, memory_order order = memory_order_seq_cst) noexcept;
Effects: Atomically replaces the value pointed to by this with desired.
Memory is affected according to the value of order.
These operations are atomic read-modify-write operations ([intro.multithread]).
Returns: Atomically returns the value pointed to by this immediately before the effects.
bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) volatile noexcept; bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) noexcept; bool compare_exchange_strong(T& expected, T desired, memory_order success, memory_order failure) volatile noexcept; bool compare_exchange_strong(T& expected, T desired, memory_order success, memory_order failure) noexcept; bool compare_exchange_weak(T& expected, T desired, memory_order order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_weak(T& expected, T desired, memory_order order = memory_order_seq_cst) noexcept; bool compare_exchange_strong(T& expected, T desired, memory_order order = memory_order_seq_cst) volatile noexcept; bool compare_exchange_strong(T& expected, T desired, memory_order order = memory_order_seq_cst) noexcept;
Requires: The failure argument shall not be memory_­order_­release nor memory_­order_­acq_­rel.
Effects: Retrieves the value in expected.
It then atomically compares the contents of the memory pointed to by this for equality with that previously retrieved from expected, and if true, replaces the contents of the memory pointed to by this with that in desired.
If and only if the comparison is true, memory is affected according to the value of success, and if the comparison is false, memory is affected according to the value of failure.
When only one memory_­order argument is supplied, the value of success is order, and the value of failure is order except that a value of memory_­order_­acq_­rel shall be replaced by the value memory_­order_­acquire and a value of memory_­order_­release shall be replaced by the value memory_­order_­relaxed.
If and only if the comparison is false then, after the atomic operation, the contents of the memory in expected are replaced by the value read from the memory pointed to by this during the atomic comparison.
If the operation returns true, these operations are atomic read-modify-write operations ([intro.multithread]) on the memory pointed to by this.
Otherwise, these operations are atomic load operations on that memory.
Returns: The result of the comparison.
[Note
:
For example, the effect of compare_­exchange_­strong is
if (memcmp(this, &expected, sizeof(*this)) == 0)
  memcpy(this, &desired, sizeof(*this));
else
  memcpy(expected, this, sizeof(*this));
end note
]
[Example
:
The expected use of the compare-and-exchange operations is as follows.
The compare-and-exchange operations will update expected when another iteration of the loop is needed.
expected = current.load();
do {
  desired = function(expected);
} while (!current.compare_exchange_weak(expected, desired));
end example
]
[Example
:
Because the expected value is updated only on failure, code releasing the memory containing the expected value on success will work.
E.
g.
list head insertion will act atomically and would not introduce a data race in the following code:
do {
  p->next = head; // make new list node point to the current head
} while (!head.compare_exchange_weak(p->next, p)); // try to insert
end example
]
Implementations should ensure that weak compare-and-exchange operations do not consistently return false unless either the atomic object has value different from expected or there are concurrent modifications to the atomic object.
Remarks: A weak compare-and-exchange operation may fail spuriously.
That is, even when the contents of memory referred to by expected and this are equal, it may return false and store back to expected the same memory contents that were originally there.
[Note
:
This spurious failure enables implementation of compare-and-exchange on a broader class of machines, e.g., load-locked store-conditional machines. A consequence of spurious failure is that nearly all uses of weak compare-and-exchange will be in a loop.
When a compare-and-exchange is in a loop, the weak version will yield better performance on some platforms.
When a weak compare-and-exchange would require a loop and a strong one would not, the strong one is preferable.
end note
]
[Note
:
The memcpy and memcmp semantics of the compare-and-exchange operations may result in failed comparisons for values that compare equal with operator== if the underlying type has padding bits, trap bits, or alternate representations of the same value.
Thus, compare_­exchange_­strong should be used with extreme care.
On the other hand, compare_­exchange_­weak should converge rapidly.
end note
]

32.6.2 Specializations for integers [atomics.types.int]

There are specializations of the atomic template for the integral types char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, char16_­t, char32_­t, wchar_­t, and any other types needed by the typedefs in the header <cstdint>.
For each such integral type integral, the specialization atomic<integral> provides additional atomic operations appropriate to integral types.
[Note
:
For the specialization atomic<bool>, see [atomics.types.generic].
end note
]
namespace std {
  template <> struct atomic<integral> {
    using value_type = integral;
    using difference_type = value_type;
    static constexpr bool is_always_lock_free = implementation-defined;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(integral, memory_order = memory_order_seq_cst) noexcept;
    integral load(memory_order = memory_order_seq_cst) const volatile noexcept;
    integral load(memory_order = memory_order_seq_cst) const noexcept;
    operator integral() const volatile noexcept;
    operator integral() const noexcept;
    integral exchange(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral exchange(integral, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(integral&, integral,
                               memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(integral&, integral,
                               memory_order, memory_order) noexcept;
    bool compare_exchange_strong(integral&, integral,
                                 memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(integral&, integral,
                                 memory_order, memory_order) noexcept;
    bool compare_exchange_weak(integral&, integral,
                               memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(integral&, integral,
                               memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(integral&, integral,
                               memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(integral&, integral,
                               memory_order = memory_order_seq_cst) noexcept;
    integral fetch_add(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_add(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_sub(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_sub(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_and(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_and(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_or(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_or(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_xor(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_xor(integral, memory_order = memory_order_seq_cst) noexcept;

    atomic() noexcept = default;
    constexpr atomic(integral) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    integral operator=(integral) volatile noexcept;
    integral operator=(integral) noexcept;

    integral operator++(int) volatile noexcept;
    integral operator++(int) noexcept;
    integral operator--(int) volatile noexcept;
    integral operator--(int) noexcept;
    integral operator++() volatile noexcept;
    integral operator++() noexcept;
    integral operator--() volatile noexcept;
    integral operator--() noexcept;
    integral operator+=(integral) volatile noexcept;
    integral operator+=(integral) noexcept;
    integral operator-=(integral) volatile noexcept;
    integral operator-=(integral) noexcept;
    integral operator&=(integral) volatile noexcept;
    integral operator&=(integral) noexcept;
    integral operator|=(integral) volatile noexcept;
    integral operator|=(integral) noexcept;
    integral operator^=(integral) volatile noexcept;
    integral operator^=(integral) noexcept;
  };
}
The atomic integral specializations are standard-layout structs.
They each have a trivial default constructor and a trivial destructor.
Descriptions are provided below only for members that differ from the primary template.
The following operations perform arithmetic computations.
The key, operator, and computation correspondence is:
Table 133 — Atomic arithmetic computations
key
Op
Computation
key
Op
Computation
add
+
addition
sub
-
subtraction
or
|
bitwise inclusive or
xor
^
bitwise exclusive or
and
&
bitwise and
T fetch_key(T operand, memory_order order = memory_order_seq_cst) volatile noexcept; T fetch_key(T operand, memory_order order = memory_order_seq_cst) noexcept;
Effects: Atomically replaces the value pointed to by this with the result of the computation applied to the value pointed to by this and the given operand.
Memory is affected according to the value of order.
These operations are atomic read-modify-write operations ([intro.multithread]).
Returns: Atomically, the value pointed to by this immediately before the effects.
Remarks: For signed integer types, arithmetic is defined to use two's complement representation.
There are no undefined results.
T operator op=(T operand) volatile noexcept; T operator op=(T operand) noexcept;
Effects: Equivalent to: return fetch_­key(operand) op operand;

32.6.3 Partial specialization for pointers [atomics.types.pointer]

namespace std {
  template <class T> struct atomic<T*> {
    using value_type = T*;
    using difference_type = ptrdiff_t;
    static constexpr bool is_always_lock_free = implementation-defined;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(T*, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(T*, memory_order = memory_order_seq_cst) noexcept;
    T* load(memory_order = memory_order_seq_cst) const volatile noexcept;
    T* load(memory_order = memory_order_seq_cst) const noexcept;
    operator T*() const volatile noexcept;
    operator T*() const noexcept;
    T* exchange(T*, memory_order = memory_order_seq_cst) volatile noexcept;
    T* exchange(T*, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order = memory_order_seq_cst) noexcept;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;

    atomic() noexcept = default;
    constexpr atomic(T*) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    T* operator=(T*) volatile noexcept;
    T* operator=(T*) noexcept;

    T* operator++(int) volatile noexcept;
    T* operator++(int) noexcept;
    T* operator--(int) volatile noexcept;
    T* operator--(int) noexcept;
    T* operator++() volatile noexcept;
    T* operator++() noexcept;
    T* operator--() volatile noexcept;
    T* operator--() noexcept;
    T* operator+=(ptrdiff_t) volatile noexcept;
    T* operator+=(ptrdiff_t) noexcept;
    T* operator-=(ptrdiff_t) volatile noexcept;
    T* operator-=(ptrdiff_t) noexcept;
  };
}
There is a partial specialization of the atomic class template for pointers.
Specializations of this partial specialization are standard-layout structs.
They each have a trivial default constructor and a trivial destructor.
Descriptions are provided below only for members that differ from the primary template.
The following operations perform pointer arithmetic.
The key, operator, and computation correspondence is:
Table 134 — Atomic pointer computations
Key
Op
Computation
Key
Op
Computation
add
+
addition
sub
-
subtraction
T* fetch_key(ptrdiff_t operand, memory_order order = memory_order_seq_cst) volatile noexcept; T* fetch_key(ptrdiff_t operand, memory_order order = memory_order_seq_cst) noexcept;
Requires: T shall be an object type, otherwise the program is ill-formed.
[Note
:
Pointer arithmetic on void* or function pointers is ill-formed.
end note
]
Effects: Atomically replaces the value pointed to by this with the result of the computation applied to the value pointed to by this and the given operand.
Memory is affected according to the value of order.
These operations are atomic read-modify-write operations ([intro.multithread]).
Returns: Atomically, the value pointed to by this immediately before the effects.
Remarks: The result may be an undefined address, but the operations otherwise have no undefined behavior.
T* operator op=(ptrdiff_t operand) volatile noexcept; T* operator op=(ptrdiff_t operand) noexcept;
Effects: Equivalent to: return fetch_­key(operand) op operand;

32.6.4 Member operators common to integers and pointers to objects [atomics.types.memop]

T operator++(int) volatile noexcept; T operator++(int) noexcept;
Effects: Equivalent to: return fetchadd(1);
T operator--(int) volatile noexcept; T operator--(int) noexcept;
Effects: Equivalent to: return fetchsub(1);
T operator++() volatile noexcept; T operator++() noexcept;
Effects: Equivalent to: return fetch_­add(1) + 1;
T operator--() volatile noexcept; T operator--() noexcept;
Effects: Equivalent to: return fetch_­sub(1) - 1;

32.7 Non-member functions [atomics.nonmembers]

A non-member function template whose name matches the pattern atomic_­f or the pattern atomic_­f_­explicit invokes the member function f, with the value of the first parameter as the object expression and the values of the remaining parameters (if any) as the arguments of the member function call, in order.
An argument for a parameter of type atomic<T>​::​value_­type* is dereferenced when passed to the member function call.
If no such member function exists, the program is ill-formed.
template<class T> void atomic_init(volatile atomic<T>* object, typename atomic<T>::value_type desired) noexcept; template<class T> void atomic_init(atomic<T>* object, typename atomic<T>::value_type desired) noexcept;
Effects: Non-atomically initializes *object with value desired.
This function shall only be applied to objects that have been default constructed, and then only once.
[Note
:
These semantics ensure compatibility with C.
end note
]
[Note
:
Concurrent access from another thread, even via an atomic operation, constitutes a data race.
end note
]
[Note
:
The non-member functions enable programmers to write code that can be compiled as either C or C++, for example in a shared header file.
end note
]

32.8 Flag type and operations [atomics.flag]

namespace std {
  struct atomic_flag {
    bool test_and_set(memory_order = memory_order_seq_cst) volatile noexcept;
    bool test_and_set(memory_order = memory_order_seq_cst) noexcept;
    void clear(memory_order = memory_order_seq_cst) volatile noexcept;
    void clear(memory_order = memory_order_seq_cst) noexcept;

    atomic_flag() noexcept = default;
    atomic_flag(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) volatile = delete;
  };

  bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;
  bool atomic_flag_test_and_set(atomic_flag*) noexcept;
  bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept;
  bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept;
  void atomic_flag_clear(volatile atomic_flag*) noexcept;
  void atomic_flag_clear(atomic_flag*) noexcept;
  void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept;
  void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept;

  #define ATOMIC_FLAG_INIT see below
}
The atomic_­flag type provides the classic test-and-set functionality.
It has two states, set and clear.
Operations on an object of type atomic_­flag shall be lock-free.
[Note
:
Hence the operations should also be address-free.
end note
]
The atomic_­flag type is a standard-layout struct.
It has a trivial default constructor and a trivial destructor.
The macro ATOMIC_­FLAG_­INIT shall be defined in such a way that it can be used to initialize an object of type atomic_­flag to the clear state.
The macro can be used in the form:
atomic_flag guard = ATOMIC_FLAG_INIT;
It is unspecified whether the macro can be used in other initialization contexts.
For a complete static-duration object, that initialization shall be static.
Unless initialized with ATOMIC_­FLAG_­INIT, it is unspecified whether an atomic_­flag object has an initial state of set or clear.
bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept; bool atomic_flag_test_and_set(atomic_flag* object) noexcept; bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept; bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept; bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst) volatile noexcept; bool atomic_flag::test_and_set(memory_order order = memory_order_seq_cst) noexcept;
Effects: Atomically sets the value pointed to by object or by this to true.
Memory is affected according to the value of order.
These operations are atomic read-modify-write operations ([intro.multithread]).
Returns: Atomically, the value of the object immediately before the effects.
void atomic_flag_clear(volatile atomic_flag* object) noexcept; void atomic_flag_clear(atomic_flag* object) noexcept; void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept; void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept; void atomic_flag::clear(memory_order order = memory_order_seq_cst) volatile noexcept; void atomic_flag::clear(memory_order order = memory_order_seq_cst) noexcept;
Requires: The order argument shall not be memory_­order_­consume, memory_­order_­acquire, nor memory_­order_­acq_­rel.
Effects: Atomically sets the value pointed to by object or by this to false.
Memory is affected according to the value of order.

32.9 Fences [atomics.fences]

This section introduces synchronization primitives called fences.
Fences can have acquire semantics, release semantics, or both.
A fence with acquire semantics is called an acquire fence.
A fence with release semantics is called a release fence.
A release fence A synchronizes with an acquire fence B if there exist atomic operations X and Y, both operating on some atomic object M, such that A is sequenced before X, X modifies M, Y is sequenced before B, and Y reads the value written by X or a value written by any side effect in the hypothetical release sequence X would head if it were a release operation.
A release fence A synchronizes with an atomic operation B that performs an acquire operation on an atomic object M if there exists an atomic operation X such that A is sequenced before X, X modifies M, and B reads the value written by X or a value written by any side effect in the hypothetical release sequence X would head if it were a release operation.
An atomic operation A that is a release operation on an atomic object M synchronizes with an acquire fence B if there exists some atomic operation X on M such that X is sequenced before B and reads the value written by A or a value written by any side effect in the release sequence headed by A.
extern "C" void atomic_thread_fence(memory_order order) noexcept;
Effects: Depending on the value of order, this operation:
  • has no effects, if order == memory_­order_­relaxed;
  • is an acquire fence, if order == memory_­order_­acquire || order == memory_­order_­consume;
  • is a release fence, if order == memory_­order_­release;
  • is both an acquire fence and a release fence, if order == memory_­order_­acq_­rel;
  • is a sequentially consistent acquire and release fence, if order == memory_­order_­seq_­cst.
extern "C" void atomic_signal_fence(memory_order order) noexcept;
Effects: Equivalent to atomic_­thread_­fence(order), except that the resulting ordering constraints are established only between a thread and a signal handler executed in the same thread.
[Note
:
atomic_­signal_­fence can be used to specify the order in which actions performed by the thread become visible to the signal handler.
Compiler optimizations and reorderings of loads and stores are inhibited in the same way as with atomic_­thread_­fence, but the hardware fence instructions that atomic_­thread_­fence would have inserted are not emitted.
end note
]

33 Thread support library [thread]

33.1 General [thread.general]

The following subclauses describe components to create and manage threads ([intro.multithread]), perform mutual exclusion, and communicate conditions and values between threads, as summarized in Table 135.
Table 135 — Thread support library summary
Subclause
Header(s)
Requirements
Threads
<thread>
Mutual exclusion
<mutex>
<shared_­mutex>
Condition variables
<condition_­variable>
Futures
<future>

33.2 Requirements [thread.req]

33.2.1 Template parameter names [thread.req.paramname]

Throughout this Clause, the names of template parameters are used to express type requirements.
If a template parameter is named Predicate, operator() applied to the template argument shall return a value that is convertible to bool.

33.2.2 Exceptions [thread.req.exception]

Some functions described in this Clause are specified to throw exceptions of type system_­error ([syserr.syserr]).
Such exceptions shall be thrown if any of the function's error conditions is detected or a call to an operating system or other underlying API results in an error that prevents the library function from meeting its specifications.
Failure to allocate storage shall be reported as described in [res.on.exception.handling].
[Example
:
Consider a function in this clause that is specified to throw exceptions of type system_­error and specifies error conditions that include operation_­not_­permitted for a thread that does not have the privilege to perform the operation.
Assume that, during the execution of this function, an errno of EPERM is reported by a POSIX API call used by the implementation.
Since POSIX specifies an errno of EPERM when “the caller does not have the privilege to perform the operation”, the implementation maps EPERM to an error_­condition of operation_­not_­permitted ([syserr]) and an exception of type system_­error is thrown.
end example
]
The error_­code reported by such an exception's code() member function shall compare equal to one of the conditions specified in the function's error condition element.

33.2.3 Native handles [thread.req.native]

Several classes described in this Clause have members native_­handle_­type and native_­handle.
The presence of these members and their semantics is implementation-defined.
[Note
:
These members allow implementations to provide access to implementation details.
Their names are specified to facilitate portable compile-time detection.
Actual use of these members is inherently non-portable.
end note
]

33.2.4 Timing specifications [thread.req.timing]

Several functions described in this Clause take an argument to specify a timeout.
These timeouts are specified as either a duration or a time_­point type as specified in [time].
Implementations necessarily have some delay in returning from a timeout.
Any overhead in interrupt response, function return, and scheduling induces a “quality of implementation” delay, expressed as duration .
Ideally, this delay would be zero.
Further, any contention for processor and memory resources induces a “quality of management” delay, expressed as duration .
The delay durations may vary from timeout to timeout, but in all cases shorter is better.
The member functions whose names end in _­for take an argument that specifies a duration.
These functions produce relative timeouts.
Implementations should use a steady clock to measure time for these functions.330
Given a duration argument , the real-time duration of the timeout is .
The member functions whose names end in _­until take an argument that specifies a time point.
These functions produce absolute timeouts.
Implementations should use the clock specified in the time point to measure time for these functions.
Given a clock time point argument , the clock time point of the return from timeout should be when the clock is not adjusted during the timeout.
If the clock is adjusted to the time during the timeout, the behavior should be as follows:
  • if , the waiting function should wake as soon as possible, i.e. , since the timeout is already satisfied.
    [Note
    :
    This specification may result in the total duration of the wait decreasing when measured against a steady clock.
    end note
    ]
  • if , the waiting function should not time out until Clock​::​now() returns a time , i.e. waking at .
    [Note
    :
    When the clock is adjusted backwards, this specification may result in the total duration of the wait increasing when measured against a steady clock.
    When the clock is adjusted forwards, this specification may result in the total duration of the wait decreasing when measured against a steady clock.
    end note
    ]
An implementation shall return from such a timeout at any point from the time specified above to the time it would return from a steady-clock relative timeout on the difference between and the time point of the call to the _­until function.
[Note
:
Implementations should decrease the duration of the wait when the clock is adjusted forwards.
end note
]
[Note
:
If the clock is not synchronized with a steady clock, e.g., a CPU time clock, these timeouts might not provide useful functionality.
end note
]
The resolution of timing provided by an implementation depends on both operating system and hardware.
The finest resolution provided by an implementation is called the native resolution.
Implementation-provided clocks that are used for these functions shall meet the TrivialClock requirements ([time.clock.req]).
A function that takes an argument which specifies a timeout will throw if, during its execution, a clock, time point, or time duration throws an exception.
Such exceptions are referred to as timeout-related exceptions.
[Note
:
Instantiations of clock, time point and duration types supplied by the implementation as specified in [time.clock] do not throw exceptions.
end note
]
All implementations for which standard time units are meaningful must necessarily have a steady clock within their hardware implementation.

33.2.5 Requirements for Lockable types [thread.req.lockable]

33.2.5.1 In general [thread.req.lockable.general]

An execution agent is an entity such as a thread that may perform work in parallel with other execution agents.
[Note
:
Implementations or users may introduce other kinds of agents such as processes or thread-pool tasks.
end note
]
The calling agent is determined by context, e.g. the calling thread that contains the call, and so on.
[Note
:
Some lockable objects are “agent oblivious” in that they work for any execution agent model because they do not determine or store the agent's ID (e.g., an ordinary spin lock).
end note
]
The standard library templates unique_­lock ([thread.lock.unique]), shared_­lock ([thread.lock.shared]), scoped_­lock ([thread.lock.scoped]), lock_­guard ([thread.lock.guard]), lock, try_­lock ([thread.lock.algorithm]), and condition_­variable_­any ([thread.condition.condvarany]) all operate on user-supplied lockable objects.
The BasicLockable requirements, the Lockable requirements, and the TimedLockable requirements list the requirements imposed by these library types in order to acquire or release ownership of a lock by a given execution agent.
[Note
:
The nature of any lock ownership and any synchronization it may entail are not part of these requirements.
end note
]

33.2.5.2 BasicLockable requirements [thread.req.lockable.basic]

A type L meets the BasicLockable requirements if the following expressions are well-formed and have the specified semantics (m denotes a value of type L).
m.lock()
Effects: Blocks until a lock can be acquired for the current execution agent.
If an exception is thrown then a lock shall not have been acquired for the current execution agent.
m.unlock()
Requires: The current execution agent shall hold a lock on m.
Effects: Releases a lock on m held by the current execution agent.
Throws: Nothing.

33.2.5.3 Lockable requirements [thread.req.lockable.req]

A type L meets the Lockable requirements if it meets the BasicLockable requirements and the following expressions are well-formed and have the specified semantics (m denotes a value of type L).
m.try_lock()
Effects: Attempts to acquire a lock for the current execution agent without blocking.
If an exception is thrown then a lock shall not have been acquired for the current execution agent.
Return type: bool.
Returns: true if the lock was acquired, false otherwise.

33.2.5.4 TimedLockable requirements [thread.req.lockable.timed]

A type L meets the TimedLockable requirements if it meets the Lockable requirements and the following expressions are well-formed and have the specified semantics (m denotes a value of type L, rel_­time denotes a value of an instantiation of duration ([time.duration]), and abs_­time denotes a value of an instantiation of time_­point ([time.point])).
m.try_lock_for(rel_time)
Effects: Attempts to acquire a lock for the current execution agent within the relative timeout ([thread.req.timing]) specified by rel_­time.
The function shall not return within the timeout specified by rel_­time unless it has obtained a lock on m for the current execution agent.
If an exception is thrown then a lock shall not have been acquired for the current execution agent.
Return type: bool.
Returns: true if the lock was acquired, false otherwise.
m.try_lock_until(abs_time)
Effects: Attempts to acquire a lock for the current execution agent before the absolute timeout ([thread.req.timing]) specified by abs_­time.
The function shall not return before the timeout specified by abs_­time unless it has obtained a lock on m for the current execution agent.
If an exception is thrown then a lock shall not have been acquired for the current execution agent.
Return type: bool.
Returns: true if the lock was acquired, false otherwise.

33.2.6 decay_­copy [thread.decaycopy]

In several places in this Clause the operation DECAY_­COPY(x) is used.
All such uses mean call the function decay_­copy(x) and use the result, where decay_­copy is defined as follows:
template <class T> decay_t<T> decay_copy(T&& v)
  { return std::forward<T>(v); }

33.3 Threads [thread.threads]

[thread.threads] describes components that can be used to create and manage threads.
[Note
:
These threads are intended to map one-to-one with operating system threads.
end note
]

33.3.1 Header <thread> synopsis [thread.syn]

namespace std {
  class thread;

  void swap(thread& x, thread& y) noexcept;

  namespace this_thread {
    thread::id get_id() noexcept;

    void yield() noexcept;
    template <class Clock, class Duration>
      void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
    template <class Rep, class Period>
      void sleep_for(const chrono::duration<Rep, Period>& rel_time);
  }
}

33.3.2 Class thread [thread.thread.class]

The class thread provides a mechanism to create a new thread of execution, to join with a thread (i.e., wait for a thread to complete), and to perform other operations that manage and query the state of a thread. A thread object uniquely represents a particular thread of execution.
That representation may be transferred to other thread objects in such a way that no two thread objects simultaneously represent the same thread of execution.
A thread of execution is detached when no thread object represents that thread.
Objects of class thread can be in a state that does not represent a thread of execution.
[Note
:
A thread object does not represent a thread of execution after default construction, after being moved from, or after a successful call to detach or join.
end note
]
namespace std {
  class thread {
  public:
    // types:
    class id;
    using native_handle_type = implementation-defined; // See [thread.req.native]

    // construct/copy/destroy:
    thread() noexcept;
    template <class F, class... Args> explicit thread(F&& f, Args&&... args);
    ~thread();
    thread(const thread&) = delete;
    thread(thread&&) noexcept;
    thread& operator=(const thread&) = delete;
    thread& operator=(thread&&) noexcept;

    // members:
    void swap(thread&) noexcept;
    bool joinable() const noexcept;
    void join();
    void detach();
    id get_id() const noexcept;
    native_handle_type native_handle(); // See [thread.req.native]

    // static members:
    static unsigned hardware_concurrency() noexcept;
  };
}

33.3.2.1 Class thread​::​id [thread.thread.id]

namespace std {
  class thread::id {
  public:
      id() noexcept;
  };

  bool operator==(thread::id x, thread::id y) noexcept;
  bool operator!=(thread::id x, thread::id y) noexcept;
  bool operator<(thread::id x, thread::id y) noexcept;
  bool operator<=(thread::id x, thread::id y) noexcept;
  bool operator>(thread::id x, thread::id y) noexcept;
  bool operator>=(thread::id x, thread::id y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<< (basic_ostream<charT, traits>& out, thread::id id);

  // Hash support
  template <class T> struct hash;
  template <> struct hash<thread::id>;
}
An object of type thread​::​id provides a unique identifier for each thread of execution and a single distinct value for all thread objects that do not represent a thread of execution ([thread.thread.class]).
Each thread of execution has an associated thread​::​id object that is not equal to the thread​::​id object of any other thread of execution and that is not equal to the thread​::​id object of any thread object that does not represent threads of execution.
thread​::​id shall be a trivially copyable class (Clause [class]).
The library may reuse the value of a thread​::​id of a terminated thread that can no longer be joined.
[Note
:
Relational operators allow thread​::​id objects to be used as keys in associative containers.
end note
]
id() noexcept;
Effects: Constructs an object of type id.
Postconditions: The constructed object does not represent a thread of execution.
bool operator==(thread::id x, thread::id y) noexcept;
Returns: true only if x and y represent the same thread of execution or neither x nor y represents a thread of execution.
bool operator!=(thread::id x, thread::id y) noexcept;
Returns: !(x == y)
bool operator<(thread::id x, thread::id y) noexcept;
Returns: A value such that operator< is a total ordering as described in [alg.sorting].
bool operator<=(thread::id x, thread::id y) noexcept;
Returns: !(y < x).
bool operator>(thread::id x, thread::id y) noexcept;
Returns: y < x.
bool operator>=(thread::id x, thread::id y) noexcept;
Returns: !(x < y).
template<class charT, class traits> basic_ostream<charT, traits>& operator<< (basic_ostream<charT, traits>& out, thread::id id);
Effects: Inserts an unspecified text representation of id into out.
For two objects of type thread​::​id x and y, if x == y the thread​::​id objects shall have the same text representation and if x != y the thread​::​id objects shall have distinct text representations.
Returns: out.
template <> struct hash<thread::id>;
The specialization is enabled ([unord.hash]).

33.3.2.2 thread constructors [thread.thread.constr]

thread() noexcept;
Effects: Constructs a thread object that does not represent a thread of execution.
Postconditions: get_­id() == id().
template <class F, class... Args> explicit thread(F&& f, Args&&... args);
Requires: F and each Ti in Args shall satisfy the MoveConstructible requirements.
INVOKE(​DECAY_­COPY(​std​::​forward<F>(f)), DECAY_­COPY(​std​::​forward<Args>(​args))...) ([func.require]) shall be a valid expression.
Remarks: This constructor shall not participate in overload resolution if decay_­t<F> is the same type as std​::​thread.
Effects: Constructs an object of type thread.
The new thread of execution executes INVOKE(​DECAY_­COPY(​std​::​forward<F>(f)), DECAY_­COPY(​std​::​forward<Args>(​args))...) with the calls to DECAY_­COPY being evaluated in the constructing thread.
Any return value from this invocation is ignored.
[Note
:
This implies that any exceptions not thrown from the invocation of the copy of f will be thrown in the constructing thread, not the new thread.
end note
]
If the invocation of INVOKE(​DECAY_­COPY(​std​::​forward<F>(f)), DECAY_­COPY(​std​::​forward<Args>(args))...) terminates with an uncaught exception, terminate shall be called.
Synchronization: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.
Postconditions: get_­id() != id().
*this represents the newly started thread.
Throws: system_­error if unable to start the new thread.
Error conditions:
  • resource_­unavailable_­try_­again — the system lacked the necessary resources to create another thread, or the system-imposed limit on the number of threads in a process would be exceeded.
thread(thread&& x) noexcept;
Effects: Constructs an object of type thread from x, and sets x to a default constructed state.
Postconditions: x.get_­id() == id() and get_­id() returns the value of x.get_­id() prior to the start of construction.

33.3.2.3 thread destructor [thread.thread.destr]

~thread();
If joinable(), calls terminate().
Otherwise, has no effects.
[Note
:
Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is thrown.
Thus the programmer must ensure that the destructor is never executed while the thread is still joinable.
end note
]

33.3.2.4 thread assignment [thread.thread.assign]

thread& operator=(thread&& x) noexcept;
Effects: If joinable(), calls terminate().
Otherwise, assigns the state of x to *this and sets x to a default constructed state.
Postconditions: x.get_­id() == id() and get_­id() returns the value of x.get_­id() prior to the assignment.
Returns: *this.

33.3.2.5 thread members [thread.thread.member]

void swap(thread& x) noexcept;
Effects: Swaps the state of *this and x.
bool joinable() const noexcept;
Returns: get_­id() != id().
void join();
Effects: Blocks until the thread represented by *this has completed.
Synchronization: The completion of the thread represented by *this synchronizes with ([intro.multithread]) the corresponding successful join() return.
[Note
:
Operations on *this are not synchronized.
end note
]
Postconditions: The thread represented by *this has completed.
get_­id() == id().
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • resource_­deadlock_­would_­occur — if deadlock is detected or get_­id() == this_­thread​::​​get_­id().
  • no_­such_­process — if the thread is not valid.
  • invalid_­argument — if the thread is not joinable.
void detach();
Effects: The thread represented by *this continues execution without the calling thread blocking.
When detach() returns, *this no longer represents the possibly continuing thread of execution.
When the thread previously represented by *this ends execution, the implementation shall release any owned resources.
Postconditions: get_­id() == id().
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • no_­such_­process — if the thread is not valid.
  • invalid_­argument — if the thread is not joinable.
id get_id() const noexcept;
Returns: A default constructed id object if *this does not represent a thread, otherwise this_­thread​::​get_­id() for the thread of execution represented by *this.

33.3.2.6 thread static members [thread.thread.static]

unsigned hardware_concurrency() noexcept;
Returns: The number of hardware thread contexts.
[Note
:
This value should only be considered to be a hint.
end note
]
If this value is not computable or well defined an implementation should return 0.

33.3.2.7 thread specialized algorithms [thread.thread.algorithm]

void swap(thread& x, thread& y) noexcept;
Effects: As if by x.swap(y).

33.3.3 Namespace this_­thread [thread.thread.this]

namespace std::this_thread {
  thread::id get_id() noexcept;

  void yield() noexcept;
  template <class Clock, class Duration>
    void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
  template <class Rep, class Period>
    void sleep_for(const chrono::duration<Rep, Period>& rel_time);
}
thread::id this_thread::get_id() noexcept;
Returns: An object of type thread​::​id that uniquely identifies the current thread of execution.
No other thread of execution shall have this id and this thread of execution shall always have this id.
The object returned shall not compare equal to a default constructed thread​::​id.
void this_thread::yield() noexcept;
Effects: Offers the implementation the opportunity to reschedule.
Synchronization: None.
template <class Clock, class Duration> void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
Effects: Blocks the calling thread for the absolute timeout ([thread.req.timing]) specified by abs_­time.
Synchronization: None.
Throws: Timeout-related exceptions ([thread.req.timing]).
template <class Rep, class Period> void sleep_for(const chrono::duration<Rep, Period>& rel_time);
Effects: Blocks the calling thread for the relative timeout ([thread.req.timing]) specified by rel_­time.
Synchronization: None.
Throws: Timeout-related exceptions ([thread.req.timing]).

33.4 Mutual exclusion [thread.mutex]

This section provides mechanisms for mutual exclusion: mutexes, locks, and call once.
These mechanisms ease the production of race-free programs ([intro.multithread]).

33.4.1 Header <mutex> synopsis [mutex.syn]

namespace std {
  class mutex;
  class recursive_mutex;
  class timed_mutex;
  class recursive_timed_mutex;

  struct defer_lock_t { explicit defer_lock_t() = default; };
  struct try_to_lock_t { explicit try_to_lock_t() = default; };
  struct adopt_lock_t { explicit adopt_lock_t() = default; };

  inline constexpr defer_lock_t  defer_lock { };
  inline constexpr try_to_lock_t try_to_lock { };
  inline constexpr adopt_lock_t  adopt_lock { };

  template <class Mutex> class lock_guard;
  template <class... MutexTypes> class scoped_lock;
  template <class Mutex> class unique_lock;

  template <class Mutex>
    void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;

  template <class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
  template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);

  struct once_flag;

  template<class Callable, class... Args>
    void call_once(once_flag& flag, Callable&& func, Args&&... args);
}

33.4.2 Header <shared_­mutex> synopsis [shared_mutex.syn]

namespace std {
  class shared_mutex;
  class shared_timed_mutex;
  template <class Mutex> class shared_lock;
  template <class Mutex>
    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
}

33.4.3 Mutex requirements [thread.mutex.requirements]

33.4.3.1 In general [thread.mutex.requirements.general]

A mutex object facilitates protection against data races and allows safe synchronization of data between execution agents ([thread.req.lockable]).
An execution agent owns a mutex from the time it successfully calls one of the lock functions until it calls unlock.
Mutexes can be either recursive or non-recursive, and can grant simultaneous ownership to one or many execution agents.
Both recursive and non-recursive mutexes are supplied.

33.4.3.2 Mutex types [thread.mutex.requirements.mutex]

The mutex types are the standard library types mutex, recursive_­mutex, timed_­mutex, recursive_­timed_­mutex, shared_­mutex, and shared_­timed_­mutex.
They shall meet the requirements set out in this section.
In this description, m denotes an object of a mutex type.
The mutex types shall meet the Lockable requirements ([thread.req.lockable.req]).
The mutex types shall be DefaultConstructible and Destructible.
If initialization of an object of a mutex type fails, an exception of type system_­error shall be thrown.
The mutex types shall not be copyable or movable.
The error conditions for error codes, if any, reported by member functions of the mutex types shall be:
  • resource_­unavailable_­try_­again — if any native handle type manipulated is not available.
  • operation_­not_­permitted — if the thread does not have the privilege to perform the operation.
  • invalid_­argument — if any native handle type manipulated as part of mutex construction is incorrect.
The implementation shall provide lock and unlock operations, as described below.
For purposes of determining the existence of a data race, these behave as atomic operations ([intro.multithread]).
The lock and unlock operations on a single mutex shall appear to occur in a single total order.
[Note
:
This can be viewed as the modification order ([intro.multithread]) of the mutex.
end note
]
[Note
:
Construction and destruction of an object of a mutex type need not be thread-safe; other synchronization should be used to ensure that mutex objects are initialized and visible to other threads.
end note
]
The expression m.lock() shall be well-formed and have the following semantics:
Requires: If m is of type mutex, timed_­mutex, shared_­mutex, or shared_­timed_­mutex, the calling thread does not own the mutex.
Effects: Blocks the calling thread until ownership of the mutex can be obtained for the calling thread.
Postconditions: The calling thread owns the mutex.
Return type: void.
Synchronization: Prior unlock() operations on the same object shall synchronize with ([intro.multithread]) this operation.
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if the thread does not have the privilege to perform the operation.
  • resource_­deadlock_­would_­occur — if the implementation detects that a deadlock would occur.
The expression m.try_­lock() shall be well-formed and have the following semantics:
Requires: If m is of type mutex, timed_­mutex, shared_­mutex, or shared_­timed_­mutex, the calling thread does not own the mutex.
Effects: Attempts to obtain ownership of the mutex for the calling thread without blocking.
If ownership is not obtained, there is no effect and try_­lock() immediately returns.
An implementation may fail to obtain the lock even if it is not held by any other thread.
[Note
:
This spurious failure is normally uncommon, but allows interesting implementations based on a simple compare and exchange (Clause [atomics]).
end note
]
An implementation should ensure that try_­lock() does not consistently return false in the absence of contending mutex acquisitions.
Return type: bool.
Returns: true if ownership of the mutex was obtained for the calling thread, otherwise false.
Synchronization: If try_­lock() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
[Note
:
Since lock() does not synchronize with a failed subsequent try_­lock(), the visibility rules are weak enough that little would be known about the state after a failure, even in the absence of spurious failures.
end note
]
Throws: Nothing.
The expression m.unlock() shall be well-formed and have the following semantics:
Requires: The calling thread shall own the mutex.
Effects: Releases the calling thread's ownership of the mutex.
Return type: void.
Synchronization: This operation synchronizes with ([intro.multithread]) subsequent lock operations that obtain ownership on the same object.
Throws: Nothing.

33.4.3.2.1 Class mutex [thread.mutex.class]

namespace std {
  class mutex {
  public:
    constexpr mutex() noexcept;
    ~mutex();

    mutex(const mutex&) = delete;
    mutex& operator=(const mutex&) = delete;

    void lock();
    bool try_lock();
    void unlock();

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}
The class mutex provides a non-recursive mutex with exclusive ownership semantics.
If one thread owns a mutex object, attempts by another thread to acquire ownership of that object will fail (for try_­lock()) or block (for lock()) until the owning thread has released ownership with a call to unlock().
[Note
:
After a thread A has called unlock(), releasing a mutex, it is possible for another thread B to lock the same mutex, observe that it is no longer in use, unlock it, and destroy it, before thread A appears to have returned from its unlock call.
Implementations are required to handle such scenarios correctly, as long as thread A doesn't access the mutex after the unlock call returns.
These cases typically occur when a reference-counted object contains a mutex that is used to protect the reference count.
end note
]
The class mutex shall satisfy all of the mutex requirements ([thread.mutex.requirements]).
It shall be a standard-layout class (Clause [class]).
[Note
:
A program may deadlock if the thread that owns a mutex object calls lock() on that object.
If the implementation can detect the deadlock, a resource_­deadlock_­would_­occur error condition may be observed.
end note
]
The behavior of a program is undefined if it destroys a mutex object owned by any thread or a thread terminates while owning a mutex object.

33.4.3.2.2 Class recursive_­mutex [thread.mutex.recursive]

namespace std {
  class recursive_mutex {
  public:
    recursive_mutex();
    ~recursive_mutex();

    recursive_mutex(const recursive_mutex&) = delete;
    recursive_mutex& operator=(const recursive_mutex&) = delete;

    void lock();
    bool try_lock() noexcept;
    void unlock();

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}
The class recursive_­mutex provides a recursive mutex with exclusive ownership semantics.
If one thread owns a recursive_­mutex object, attempts by another thread to acquire ownership of that object will fail (for try_­lock()) or block (for lock()) until the first thread has completely released ownership.
The class recursive_­mutex shall satisfy all of the mutex requirements ([thread.mutex.requirements]).
It shall be a standard-layout class (Clause [class]).
A thread that owns a recursive_­mutex object may acquire additional levels of ownership by calling lock() or try_­lock() on that object.
It is unspecified how many levels of ownership may be acquired by a single thread.
If a thread has already acquired the maximum level of ownership for a recursive_­mutex object, additional calls to try_­lock() shall fail, and additional calls to lock() shall throw an exception of type system_­error.
A thread shall call unlock() once for each level of ownership acquired by calls to lock() and try_­lock().
Only when all levels of ownership have been released may ownership be acquired by another thread.
The behavior of a program is undefined if:
  • it destroys a recursive_­mutex object owned by any thread or
  • a thread terminates while owning a recursive_­mutex object.

33.4.3.3 Timed mutex types [thread.timedmutex.requirements]

The timed mutex types are the standard library types timed_­mutex, recursive_­timed_­mutex, and shared_­timed_­mutex.
They shall meet the requirements set out below.
In this description, m denotes an object of a mutex type, rel_­time denotes an object of an instantiation of duration ([time.duration]), and abs_­time denotes an object of an instantiation of time_­point ([time.point]).
The timed mutex types shall meet the TimedLockable requirements ([thread.req.lockable.timed]).
The expression m.try_­lock_­for(rel_­time) shall be well-formed and have the following semantics:
Requires: If m is of type timed_­mutex or shared_­timed_­mutex, the calling thread does not own the mutex.
Effects: The function attempts to obtain ownership of the mutex within the relative timeout ([thread.req.timing]) specified by rel_­time.
If the time specified by rel_­time is less than or equal to rel_­time.zero(), the function attempts to obtain ownership without blocking (as if by calling try_­lock()).
The function shall return within the timeout specified by rel_­time only if it has obtained ownership of the mutex object.
[Note
:
As with try_­lock(), there is no guarantee that ownership will be obtained if the lock is available, but implementations are expected to make a strong effort to do so.
end note
]
Return type: bool.
Returns: true if ownership was obtained, otherwise false.
Synchronization: If try_­lock_­for() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
Throws: Timeout-related exceptions ([thread.req.timing]).
The expression m.try_­lock_­until(abs_­time) shall be well-formed and have the following semantics:
Requires: If m is of type timed_­mutex or shared_­timed_­mutex, the calling thread does not own the mutex.
Effects: The function attempts to obtain ownership of the mutex.
If abs_­time has already passed, the function attempts to obtain ownership without blocking (as if by calling try_­lock()).
The function shall return before the absolute timeout ([thread.req.timing]) specified by abs_­time only if it has obtained ownership of the mutex object.
[Note
:
As with try_­lock(), there is no guarantee that ownership will be obtained if the lock is available, but implementations are expected to make a strong effort to do so.
end note
]
Return type: bool.
Returns: true if ownership was obtained, otherwise false.
Synchronization: If try_­lock_­until() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
Throws: Timeout-related exceptions ([thread.req.timing]).

33.4.3.3.1 Class timed_­mutex [thread.timedmutex.class]

namespace std {
  class timed_mutex {
  public:
    timed_mutex();
    ~timed_mutex();

    timed_mutex(const timed_mutex&) = delete;
    timed_mutex& operator=(const timed_mutex&) = delete;

    void lock();  // blocking
    bool try_lock();
    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}
The class timed_­mutex provides a non-recursive mutex with exclusive ownership semantics.
If one thread owns a timed_­mutex object, attempts by another thread to acquire ownership of that object will fail (for try_­lock()) or block (for lock(), try_­lock_­for(), and try_­lock_­until()) until the owning thread has released ownership with a call to unlock() or the call to try_­lock_­for() or try_­lock_­until() times out (having failed to obtain ownership).
The class timed_­mutex shall satisfy all of the timed mutex requirements ([thread.timedmutex.requirements]).
It shall be a standard-layout class (Clause [class]).
The behavior of a program is undefined if:
  • it destroys a timed_­mutex object owned by any thread,
  • a thread that owns a timed_­mutex object calls lock(), try_­lock(), try_­lock_­for(), or try_­lock_­until() on that object, or
  • a thread terminates while owning a timed_­mutex object.

33.4.3.3.2 Class recursive_­timed_­mutex [thread.timedmutex.recursive]

namespace std {
  class recursive_timed_mutex {
  public:
    recursive_timed_mutex();
    ~recursive_timed_mutex();

    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

    void lock();  // blocking
    bool try_lock() noexcept;
    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}
The class recursive_­timed_­mutex provides a recursive mutex with exclusive ownership semantics.
If one thread owns a recursive_­timed_­mutex object, attempts by another thread to acquire ownership of that object will fail (for try_­lock()) or block (for lock(), try_­lock_­for(), and try_­lock_­until()) until the owning thread has completely released ownership or the call to try_­lock_­for() or try_­lock_­until() times out (having failed to obtain ownership).
The class recursive_­timed_­mutex shall satisfy all of the timed mutex requirements ([thread.timedmutex.requirements]).
It shall be a standard-layout class (Clause [class]).
A thread that owns a recursive_­timed_­mutex object may acquire additional levels of ownership by calling lock(), try_­lock(), try_­lock_­for(), or try_­lock_­until() on that object.
It is unspecified how many levels of ownership may be acquired by a single thread.
If a thread has already acquired the maximum level of ownership for a recursive_­timed_­mutex object, additional calls to try_­lock(), try_­lock_­for(), or try_­lock_­until() shall fail, and additional calls to lock() shall throw an exception of type system_­error.
A thread shall call unlock() once for each level of ownership acquired by calls to lock(), try_­lock(), try_­lock_­for(), and try_­lock_­until().
Only when all levels of ownership have been released may ownership of the object be acquired by another thread.
The behavior of a program is undefined if:
  • it destroys a recursive_­timed_­mutex object owned by any thread, or
  • a thread terminates while owning a recursive_­timed_­mutex object.

33.4.3.4 Shared mutex types [thread.sharedmutex.requirements]

The standard library types shared_­mutex and shared_­timed_­mutex are shared mutex types.
Shared mutex types shall meet the requirements of mutex types ([thread.mutex.requirements.mutex]), and additionally shall meet the requirements set out below.
In this description, m denotes an object of a shared mutex type.
In addition to the exclusive lock ownership mode specified in [thread.mutex.requirements.mutex], shared mutex types provide a shared lock ownership mode.
Multiple execution agents can simultaneously hold a shared lock ownership of a shared mutex type.
But no execution agent shall hold a shared lock while another execution agent holds an exclusive lock on the same shared mutex type, and vice-versa.
The maximum number of execution agents which can share a shared lock on a single shared mutex type is unspecified, but shall be at least 10000.
If more than the maximum number of execution agents attempt to obtain a shared lock, the excess execution agents shall block until the number of shared locks are reduced below the maximum amount by other execution agents releasing their shared lock.
The expression m.lock_­shared() shall be well-formed and have the following semantics:
Requires: The calling thread has no ownership of the mutex.
Effects: Blocks the calling thread until shared ownership of the mutex can be obtained for the calling thread.
If an exception is thrown then a shared lock shall not have been acquired for the current thread.
Postconditions: The calling thread has a shared lock on the mutex.
Return type: void.
Synchronization: Prior unlock() operations on the same object shall synchronize with ([intro.multithread]) this operation.
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if the thread does not have the privilege to perform the operation.
  • resource_­deadlock_­would_­occur — if the implementation detects that a deadlock would occur.
The expression m.unlock_­shared() shall be well-formed and have the following semantics:
Requires: The calling thread shall hold a shared lock on the mutex.
Effects: Releases a shared lock on the mutex held by the calling thread.
Return type: void.
Synchronization: This operation synchronizes with ([intro.multithread]) subsequent lock() operations that obtain ownership on the same object.
Throws: Nothing.
The expression m.try_­lock_­shared() shall be well-formed and have the following semantics:
Requires: The calling thread has no ownership of the mutex.
Effects: Attempts to obtain shared ownership of the mutex for the calling thread without blocking.
If shared ownership is not obtained, there is no effect and try_­lock_­shared() immediately returns.
An implementation may fail to obtain the lock even if it is not held by any other thread.
Return type: bool.
Returns: true if the shared ownership lock was acquired, false otherwise.
Synchronization: If try_­lock_­shared() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
Throws: Nothing.

33.4.3.4.1 Class shared_mutex [thread.sharedmutex.class]

namespace std {
  class shared_mutex {
  public:
    shared_mutex();
    ~shared_mutex();

    shared_mutex(const shared_mutex&) = delete;
    shared_mutex& operator=(const shared_mutex&) = delete;

    // Exclusive ownership
    void lock(); // blocking
    bool try_lock();
    void unlock();

    // Shared ownership
    void lock_shared(); // blocking
    bool try_lock_shared();
    void unlock_shared();

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}
The class shared_­mutex provides a non-recursive mutex with shared ownership semantics.
The class shared_­mutex shall satisfy all of the shared mutex requirements ([thread.sharedmutex.requirements]).
It shall be a standard-layout class (Clause [class]).
The behavior of a program is undefined if:
  • it destroys a shared_­mutex object owned by any thread,
  • a thread attempts to recursively gain any ownership of a shared_­mutex, or
  • a thread terminates while possessing any ownership of a shared_­mutex.
shared_­mutex may be a synonym for shared_­timed_­mutex.

33.4.3.5 Shared timed mutex types [thread.sharedtimedmutex.requirements]

The standard library type shared_­timed_­mutex is a shared timed mutex type.
Shared timed mutex types shall meet the requirements of timed mutex types ([thread.timedmutex.requirements]), shared mutex types ([thread.sharedmutex.requirements]), and additionally shall meet the requirements set out below.
In this description, m denotes an object of a shared timed mutex type, rel_­type denotes an object of an instantiation of duration ([time.duration]), and abs_­time denotes an object of an instantiation of time_­point ([time.point]).
The expression m.try_­lock_­shared_­for(rel_­time) shall be well-formed and have the following semantics:
Requires: The calling thread has no ownership of the mutex.
Effects: Attempts to obtain shared lock ownership for the calling thread within the relative timeout ([thread.req.timing]) specified by rel_­time.
If the time specified by rel_­time is less than or equal to rel_­time.zero(), the function attempts to obtain ownership without blocking (as if by calling try_­lock_­shared()).
The function shall return within the timeout specified by rel_­time only if it has obtained shared ownership of the mutex object.
[Note
:
As with try_­lock(), there is no guarantee that ownership will be obtained if the lock is available, but implementations are expected to make a strong effort to do so.
end note
]
If an exception is thrown then a shared lock shall not have been acquired for the current thread.
Return type: bool.
Returns: true if the shared lock was acquired, false otherwise.
Synchronization: If try_­lock_­shared_­for() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
Throws: Timeout-related exceptions ([thread.req.timing]).
The expression m.try_­lock_­shared_­until(abs_­time) shall be well-formed and have the following semantics:
Requires: The calling thread has no ownership of the mutex.
Effects: The function attempts to obtain shared ownership of the mutex.
If abs_­time has already passed, the function attempts to obtain shared ownership without blocking (as if by calling try_­lock_­shared()).
The function shall return before the absolute timeout ([thread.req.timing]) specified by abs_­time only if it has obtained shared ownership of the mutex object.
[Note
:
As with try_­lock(), there is no guarantee that ownership will be obtained if the lock is available, but implementations are expected to make a strong effort to do so.
end note
]
If an exception is thrown then a shared lock shall not have been acquired for the current thread.
Return type: bool.
Returns: true if the shared lock was acquired, false otherwise.
Synchronization: If try_­lock_­shared_­until() returns true, prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
Throws: Timeout-related exceptions ([thread.req.timing]).

33.4.3.5.1 Class shared_­timed_­mutex [thread.sharedtimedmutex.class]

namespace std {
  class shared_timed_mutex {
  public:
    shared_timed_mutex();
    ~shared_timed_mutex();

    shared_timed_mutex(const shared_timed_mutex&) = delete;
    shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;

    // Exclusive ownership
    void lock();  // blocking
    bool try_lock();
    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    // Shared ownership
    void lock_shared();  // blocking
    bool try_lock_shared();
    template <class Rep, class Period>
      bool
      try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
    template <class Clock, class Duration>
      bool
      try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock_shared();
  };
}
The class shared_­timed_­mutex provides a non-recursive mutex with shared ownership semantics.
The class shared_­timed_­mutex shall satisfy all of the shared timed mutex requirements ([thread.sharedtimedmutex.requirements]).
It shall be a standard-layout class (Clause [class]).
The behavior of a program is undefined if:
  • it destroys a shared_­timed_­mutex object owned by any thread,
  • a thread attempts to recursively gain any ownership of a shared_­timed_­mutex, or
  • a thread terminates while possessing any ownership of a shared_­timed_­mutex.

33.4.4 Locks [thread.lock]

A lock is an object that holds a reference to a lockable object and may unlock the lockable object during the lock's destruction (such as when leaving block scope).
An execution agent may use a lock to aid in managing ownership of a lockable object in an exception safe manner.
A lock is said to own a lockable object if it is currently managing the ownership of that lockable object for an execution agent.
A lock does not manage the lifetime of the lockable object it references.
[Note
:
Locks are intended to ease the burden of unlocking the lockable object under both normal and exceptional circumstances.
end note
]
Some lock constructors take tag types which describe what should be done with the lockable object during the lock's construction.
namespace std {
  struct defer_lock_t  { };     // do not acquire ownership of the mutex
  struct try_to_lock_t { };     // try to acquire ownership of the mutex
                                // without blocking
  struct adopt_lock_t  { };     // assume the calling thread has already
                                // obtained mutex ownership and manage it

  inline constexpr defer_lock_t   defer_lock { };
  inline constexpr try_to_lock_t  try_to_lock { };
  inline constexpr adopt_lock_t   adopt_lock { };
}

33.4.4.1 Class template lock_­guard [thread.lock.guard]

namespace std {
  template <class Mutex>
  class lock_guard {
  public:
    using mutex_type = Mutex;

    explicit lock_guard(mutex_type& m);
    lock_guard(mutex_type& m, adopt_lock_t);
    ~lock_guard();

    lock_guard(const lock_guard&) = delete;
    lock_guard& operator=(const lock_guard&) = delete;

  private:
    mutex_type& pm; // exposition only
  };

  template<class Mutex> lock_guard(lock_guard<Mutex>) -> lock_guard<Mutex>;
}
An object of type lock_­guard controls the ownership of a lockable object within a scope.
A lock_­guard object maintains ownership of a lockable object throughout the lock_­guard object's lifetime ([basic.life]).
The behavior of a program is undefined if the lockable object referenced by pm does not exist for the entire lifetime of the lock_­guard object.
The supplied Mutex type shall meet the BasicLockable requirements ([thread.req.lockable.basic]).
explicit lock_guard(mutex_type& m);
Requires: If mutex_­type is not a recursive mutex, the calling thread does not own the mutex m.
Effects: As if by m.lock().
Postconditions:&pm == &m
lock_guard(mutex_type& m, adopt_lock_t);
Requires: The calling thread owns the mutex m.
Postconditions:&pm == &m
Throws: Nothing.
~lock_guard();
Effects: As if by pm.unlock().

33.4.4.2 Class template scoped_­lock [thread.lock.scoped]

namespace std {
  template <class... MutexTypes>
  class scoped_lock {
  public:
    using mutex_type = Mutex;  // If MutexTypes... consists of the single type Mutex

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

    scoped_lock(const scoped_lock&) = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;

  private:
    tuple<MutexTypes&...> pm; // exposition only
  };

  template<class... MutexTypes>
    scoped_lock(scoped_lock<MutexTypes...>) -> scoped_lock<MutexTypes...>;
}
An object of type scoped_­lock controls the ownership of lockable objects within a scope.
A scoped_­lock object maintains ownership of lockable objects throughout the scoped_­lock object's lifetime ([basic.life]).
The behavior of a program is undefined if the lockable objects referenced by pm do not exist for the entire lifetime of the scoped_­lock object.
When sizeof...(MutexTypes) is 1, the supplied Mutex type shall meet the BasicLockable requirements ([thread.req.lockable.basic]).
Otherwise, each of the mutex types shall meet the Lockable requirements ([thread.req.lockable.req]).
explicit scoped_lock(MutexTypes&... m);
Requires: If a MutexTypes type is not a recursive mutex, the calling thread does not own the corresponding mutex element of m.
Effects: Initializes pm with tie(m...).
Then if sizeof...(MutexTypes) is 0, no effects.
Otherwise if sizeof...(MutexTypes) is 1, then m.lock().
Otherwise, lock(m...).
explicit scoped_lock(MutexTypes&... m, adopt_lock_t);
Requires: The calling thread owns all the mutexes in m.
Effects: Initializes pm with tie(m...).
Throws: Nothing.
~scoped_lock();
Effects: For all i in [0, sizeof...(MutexTypes)), get<i>(pm).unlock().

33.4.4.3 Class template unique_­lock [thread.lock.unique]

namespace std {
  template <class Mutex>
  class unique_lock {
  public:
    using mutex_type = Mutex;

    // [thread.lock.unique.cons], construct/copy/destroy
    unique_lock() noexcept;
    explicit unique_lock(mutex_type& m);
    unique_lock(mutex_type& m, defer_lock_t) noexcept;
    unique_lock(mutex_type& m, try_to_lock_t);
    unique_lock(mutex_type& m, adopt_lock_t);
    template <class Clock, class Duration>
      unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
    template <class Rep, class Period>
      unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
    ~unique_lock();

    unique_lock(const unique_lock&) = delete;
    unique_lock& operator=(const unique_lock&) = delete;

    unique_lock(unique_lock&& u) noexcept;
    unique_lock& operator=(unique_lock&& u);

    // [thread.lock.unique.locking], locking
    void lock();
    bool try_lock();

    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);

    void unlock();

    // [thread.lock.unique.mod], modifiers
    void swap(unique_lock& u) noexcept;
    mutex_type* release() noexcept;

    // [thread.lock.unique.obs], observers
    bool owns_lock() const noexcept;
    explicit operator bool () const noexcept;
    mutex_type* mutex() const noexcept;

  private:
    mutex_type* pm; // exposition only
    bool owns;      // exposition only
  };

  template<class Mutex> unique_lock(unique_lock<Mutex>) -> unique_lock<Mutex>;

  template <class Mutex>
    void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
}
An object of type unique_­lock controls the ownership of a lockable object within a scope.
Ownership of the lockable object may be acquired at construction or after construction, and may be transferred, after acquisition, to another unique_­lock object.
Objects of type unique_­lock are not copyable but are movable.
The behavior of a program is undefined if the contained pointer pm is not null and the lockable object pointed to by pm does not exist for the entire remaining lifetime ([basic.life]) of the unique_­lock object.
The supplied Mutex type shall meet the BasicLockable requirements ([thread.req.lockable.basic]).
[Note
:
unique_­lock<Mutex> meets the BasicLockable requirements.
If Mutex meets the Lockable requirements ([thread.req.lockable.req]), unique_­lock<Mutex> also meets the Lockable requirements; if Mutex meets the TimedLockable requirements ([thread.req.lockable.timed]), unique_­lock<Mutex> also meets the TimedLockable requirements.
end note
]

33.4.4.3.1 unique_­lock constructors, destructor, and assignment [thread.lock.unique.cons]

unique_lock() noexcept;
Effects: Constructs an object of type unique_­lock.
Postconditions: pm == 0 and owns == false.
explicit unique_lock(mutex_type& m);
Requires: If mutex_­type is not a recursive mutex the calling thread does not own the mutex.
Effects: Constructs an object of type unique_­lock and calls m.lock().
Postconditions: pm == addressof(m) and owns == true.
unique_lock(mutex_type& m, defer_lock_t) noexcept;
Effects: Constructs an object of type unique_­lock.
Postconditions: pm == addressof(m) and owns == false.
unique_lock(mutex_type& m, try_to_lock_t);
Requires: The supplied Mutex type shall meet the Lockable requirements ([thread.req.lockable.req]).
If mutex_­type is not a recursive mutex the calling thread does not own the mutex.
Effects: Constructs an object of type unique_­lock and calls m.try_­lock().
Postconditions: pm == addressof(m) and owns == res, where res is the value returned by the call to m.try_­lock().
unique_lock(mutex_type& m, adopt_lock_t);
Requires: The calling thread owns the mutex.
Effects: Constructs an object of type unique_­lock.
Postconditions: pm == addressof(m) and owns == true.
Throws: Nothing.
template <class Clock, class Duration> unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
Requires: If mutex_­type is not a recursive mutex the calling thread does not own the mutex.
The supplied Mutex type shall meet the TimedLockable requirements ([thread.req.lockable.timed]).
Effects: Constructs an object of type unique_­lock and calls m.try_­lock_­until(abs_­time).
Postconditions: pm == addressof(m) and owns == res, where res is the value returned by the call to m.try_­lock_­until(abs_­time).
template <class Rep, class Period> unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
Requires: If mutex_­type is not a recursive mutex the calling thread does not own the mutex.
The supplied Mutex type shall meet the TimedLockable requirements ([thread.req.lockable.timed]).
Effects: Constructs an object of type unique_­lock and calls m.try_­lock_­for(rel_­time).
Postconditions: pm == addressof(m) and owns == res, where res is the value returned by the call to m.try_­lock_­for(rel_­time).
unique_lock(unique_lock&& u) noexcept;
Postconditions: pm == u_­p.pm and owns == u_­p.owns (where u_­p is the state of u just prior to this construction), u.pm == 0 and u.owns == false.
unique_lock& operator=(unique_lock&& u);
Effects: If owns calls pm->unlock().
Postconditions: pm == u_­p.pm and owns == u_­p.owns (where u_­p is the state of u just prior to this construction), u.pm == 0 and u.owns == false.
[Note
:
With a recursive mutex it is possible for both *this and u to own the same mutex before the assignment.
In this case, *this will own the mutex after the assignment and u will not.
end note
]
Throws: Nothing.
~unique_lock();
Effects: If owns calls pm->unlock().

33.4.4.3.2 unique_­lock locking [thread.lock.unique.locking]

void lock();
Effects: As if by pm->lock().
Postconditions: owns == true.
Throws: Any exception thrown by pm->lock().
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
bool try_lock();
Requires: The supplied Mutex shall meet the Lockable requirements ([thread.req.lockable.req]).
Effects: As if by pm->try_­lock().
Returns: The value returned by the call to try_­lock().
Postconditions: owns == res, where res is the value returned by the call to try_­lock().
Throws: Any exception thrown by pm->try_­lock().
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
template <class Clock, class Duration> bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
Requires: The supplied Mutex type shall meet the TimedLockable requirements ([thread.req.lockable.timed]).
Effects: As if by pm->try_­lock_­until(abs_­time).
Returns: The value returned by the call to try_­lock_­until(abs_­time).
Postconditions: owns == res, where res is the value returned by the call to try_­lock_­until(abs_­time).
Throws: Any exception thrown by pm->try_­lock_­until().
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
template <class Rep, class Period> bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
Requires: The supplied Mutex type shall meet the TimedLockable requirements ([thread.req.lockable.timed]).
Effects: As if by pm->try_­lock_­for(rel_­time).
Returns: The value returned by the call to try_­lock_­until(rel_­time).
Postconditions: owns == res, where res is the value returned by the call to try_­lock_­for(rel_­time).
Throws: Any exception thrown by pm->try_­lock_­for().
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
void unlock();
Effects: As if by pm->unlock().
Postconditions: owns == false.
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if on entry owns is false.

33.4.4.3.3 unique_­lock modifiers [thread.lock.unique.mod]

void swap(unique_lock& u) noexcept;
Effects: Swaps the data members of *this and u.
mutex_type* release() noexcept;
Returns: The previous value of pm.
Postconditions: pm == 0 and owns == false.
template <class Mutex> void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
Effects: As if by x.swap(y).

33.4.4.3.4 unique_­lock observers [thread.lock.unique.obs]

bool owns_lock() const noexcept;
Returns: owns.
explicit operator bool() const noexcept;
Returns: owns.
mutex_type *mutex() const noexcept;
Returns: pm.

33.4.4.4 Class template shared_­lock [thread.lock.shared]

namespace std {
  template <class Mutex>
  class shared_lock {
  public:
    using mutex_type = Mutex;

    // [thread.lock.shared.cons], construct/copy/destroy
    shared_lock() noexcept;
    explicit shared_lock(mutex_type& m);  // blocking
    shared_lock(mutex_type& m, defer_lock_t) noexcept;
    shared_lock(mutex_type& m, try_to_lock_t);
    shared_lock(mutex_type& m, adopt_lock_t);
    template <class Clock, class Duration>
      shared_lock(mutex_type& m,
                  const chrono::time_point<Clock, Duration>& abs_time);
    template <class Rep, class Period>
      shared_lock(mutex_type& m,
                const chrono::duration<Rep, Period>& rel_time);
    ~shared_lock();

    shared_lock(const shared_lock&) = delete;
    shared_lock& operator=(const shared_lock&) = delete;

    shared_lock(shared_lock&& u) noexcept;
    shared_lock& operator=(shared_lock&& u) noexcept;

    // [thread.lock.shared.locking], locking
    void lock();  // blocking
    bool try_lock();
    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    // [thread.lock.shared.mod], modifiers
    void swap(shared_lock& u) noexcept;
    mutex_type* release() noexcept;

    // [thread.lock.shared.obs], observers
    bool owns_lock() const noexcept;
    explicit operator bool () const noexcept;
    mutex_type* mutex() const noexcept;

  private:
    mutex_type* pm; // exposition only
    bool owns;      // exposition only
  };

  template<class Mutex> shared_lock(shared_lock<Mutex>) -> shared_lock<Mutex>;

  template <class Mutex>
    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
}
An object of type shared_­lock controls the shared ownership of a lockable object within a scope.
Shared ownership of the lockable object may be acquired at construction or after construction, and may be transferred, after acquisition, to another shared_­lock object.
Objects of type shared_­lock are not copyable but are movable.
The behavior of a program is undefined if the contained pointer pm is not null and the lockable object pointed to by pm does not exist for the entire remaining lifetime ([basic.life]) of the shared_­lock object.
The supplied Mutex type shall meet the shared mutex requirements ([thread.sharedtimedmutex.requirements]).
[Note
:
shared_­lock<Mutex> meets the TimedLockable requirements ([thread.req.lockable.timed]).
end note
]

33.4.4.4.1 shared_­lock constructors, destructor, and assignment [thread.lock.shared.cons]

shared_lock() noexcept;
Effects: Constructs an object of type shared_­lock.
Postconditions: pm == nullptr and owns == false.
explicit shared_lock(mutex_type& m);
Requires: The calling thread does not own the mutex for any ownership mode.
Effects: Constructs an object of type shared_­lock and calls m.lock_­shared().
Postconditions: pm == addressof(m) and owns == true.
shared_lock(mutex_type& m, defer_lock_t) noexcept;
Effects: Constructs an object of type shared_­lock.
Postconditions: pm == addressof(m) and owns == false.
shared_lock(mutex_type& m, try_to_lock_t);
Requires: The calling thread does not own the mutex for any ownership mode.
Effects: Constructs an object of type shared_­lock and calls m.try_­lock_­shared().
Postconditions: pm == addressof(m) and owns == res where res is the value returned by the call to m.try_­lock_­shared().
shared_lock(mutex_type& m, adopt_lock_t);
Requires: The calling thread has shared ownership of the mutex.
Effects: Constructs an object of type shared_­lock.
Postconditions: pm == addressof(m) and owns == true.
template <class Clock, class Duration> shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
Requires: The calling thread does not own the mutex for any ownership mode.
Effects: Constructs an object of type shared_­lock and calls m.try_­lock_­shared_­until(abs_­time).
Postconditions: pm == addressof(m) and owns == res where res is the value returned by the call to m.try_­lock_­shared_­until(abs_­time).
template <class Rep, class Period> shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
Requires: The calling thread does not own the mutex for any ownership mode.
Effects: Constructs an object of type shared_­lock and calls m.try_­lock_­shared_­for(rel_­time).
Postconditions: pm == addressof(m) and owns == res where res is the value returned by the call to m.try_­lock_­shared_­for(rel_­time).
~shared_lock();
Effects: If owns calls pm->unlock_­shared().
shared_lock(shared_lock&& sl) noexcept;
Postconditions: pm == sl_­p.pm and owns == sl_­p.owns (where sl_­p is the state of sl just prior to this construction), sl.pm == nullptr and sl.owns == false.
shared_lock& operator=(shared_lock&& sl) noexcept;
Effects: If owns calls pm->unlock_­shared().
Postconditions: pm == sl_­p.pm and owns == sl_­p.owns (where sl_­p is the state of sl just prior to this assignment), sl.pm == nullptr and sl.owns == false.

33.4.4.4.2 shared_­lock locking [thread.lock.shared.locking]

void lock();
Effects: As if by pm->lock_­shared().
Postconditions: owns == true.
Throws: Any exception thrown by pm->lock_­shared().
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
bool try_lock();
Effects: As if by pm->try_­lock_­shared().
Returns: The value returned by the call to pm->try_­lock_­shared().
Postconditions: owns == res, where res is the value returned by the call to pm->try_­lock_­shared().
Throws: Any exception thrown by pm->try_­lock_­shared().
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
template <class Clock, class Duration> bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
Effects: As if by pm->try_­lock_­shared_­until(abs_­time).
Returns: The value returned by the call to pm->try_­lock_­shared_­until(abs_­time).
Postconditions: owns == res, where res is the value returned by the call to pm->try_­lock_­shared_­until(abs_­time).
Throws: Any exception thrown by pm->try_­lock_­shared_­until(abs_­time).
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
template <class Rep, class Period> bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
Effects: As if by pm->try_­lock_­shared_­for(rel_­time).
Returns: The value returned by the call to pm->try_­lock_­shared_­for(rel_­time).
Postconditions: owns == res, where res is the value returned by the call to pm->try_­lock_­shared_­for(rel_­time).
Throws: Any exception thrown by pm->try_­lock_­shared_­for(rel_­time).
system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if pm is nullptr.
  • resource_­deadlock_­would_­occur — if on entry owns is true.
void unlock();
Effects: As if by pm->unlock_­shared().
Postconditions: owns == false.
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • operation_­not_­permitted — if on entry owns is false.

33.4.4.4.3 shared_­lock modifiers [thread.lock.shared.mod]

void swap(shared_lock& sl) noexcept;
Effects: Swaps the data members of *this and sl.
mutex_type* release() noexcept;
Returns: The previous value of pm.
Postconditions: pm == nullptr and owns == false.
template <class Mutex> void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
Effects: As if by x.swap(y).

33.4.4.4.4 shared_­lock observers [thread.lock.shared.obs]

bool owns_lock() const noexcept;
Returns: owns.
explicit operator bool() const noexcept;
Returns: owns.
mutex_type* mutex() const noexcept;
Returns: pm.

33.4.5 Generic locking algorithms [thread.lock.algorithm]

template <class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
Requires: Each template parameter type shall meet the Lockable requirements.
[Note
:
The unique_­lock class template meets these requirements when suitably instantiated.
end note
]
Effects: Calls try_­lock() for each argument in order beginning with the first until all arguments have been processed or a call to try_­lock() fails, either by returning false or by throwing an exception.
If a call to try_­lock() fails, unlock() shall be called for all prior arguments and there shall be no further calls to try_­lock().
Returns: -1 if all calls to try_­lock() returned true, otherwise a zero-based index value that indicates the argument for which try_­lock() returned false.
template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
Requires: Each template parameter type shall meet the Lockable requirements,
[Note
:
The unique_­lock class template meets these requirements when suitably instantiated.
end note
]
Effects: All arguments are locked via a sequence of calls to lock(), try_­lock(), or unlock() on each argument.
The sequence of calls shall not result in deadlock, but is otherwise unspecified.
[Note
:
A deadlock avoidance algorithm such as try-and-back-off must be used, but the specific algorithm is not specified to avoid over-constraining implementations.
end note
]
If a call to lock() or try_­lock() throws an exception, unlock() shall be called for any argument that had been locked by a call to lock() or try_­lock().

33.4.6 Call once [thread.once]

33.4.6.1 Struct once_­flag [thread.once.onceflag]

namespace std {
  struct once_flag {
    constexpr once_flag() noexcept;

    once_flag(const once_flag&) = delete;
    once_flag& operator=(const once_flag&) = delete;
  };
}
The class once_­flag is an opaque data structure that call_­once uses to initialize data without causing a data race or deadlock.
constexpr once_flag() noexcept;
Effects: Constructs an object of type once_­flag.
Synchronization: The construction of a once_­flag object is not synchronized.
Postconditions: The object's internal state is set to indicate to an invocation of call_­once with the object as its initial argument that no function has been called.

33.4.6.2 Function call_­once [thread.once.callonce]

template<class Callable, class... Args> void call_once(once_flag& flag, Callable&& func, Args&&... args);
Requires:
INVOKE(std::forward<Callable>(func), std::forward<Args>(args)...)
(see [func.require]) shall be a valid expression.
Effects: An execution of call_­once that does not call its func is a passive execution.
An execution of call_­once that calls its func is an active execution.
An active execution shall call INVOKE(​std​::​forward<Callable>(func), std​::​forward<Args>(args)...).
If such a call to func throws an exception the execution is exceptional, otherwise it is returning.
An exceptional execution shall propagate the exception to the caller of call_­once.
Among all executions of call_­once for any given once_­flag: at most one shall be a returning execution; if there is a returning execution, it shall be the last active execution; and there are passive executions only if there is a returning execution.
[Note
:
Passive executions allow other threads to reliably observe the results produced by the earlier returning execution.
end note
]
Synchronization: For any given once_­flag: all active executions occur in a total order; completion of an active execution synchronizes with ([intro.multithread]) the start of the next one in this total order; and the returning execution synchronizes with the return from all passive executions.
Throws: system_­error when an exception is required ([thread.req.exception]), or any exception thrown by func.
[Example
:
// global flag, regular function
void init();
std::once_flag flag;

void f() {
  std::call_once(flag, init);
}

// function static flag, function object
struct initializer {
  void operator()();
};

void g() {
  static std::once_flag flag2;
  std::call_once(flag2, initializer());
}

// object flag, member function
class information {
  std::once_flag verified;
  void verifier();
public:
  void verify() { std::call_once(verified, &information::verifier, *this); }
};
end example
]

33.5 Condition variables [thread.condition]

Condition variables provide synchronization primitives used to block a thread until notified by some other thread that some condition is met or until a system time is reached.
Class condition_­variable provides a condition variable that can only wait on an object of type unique_­lock<mutex>, allowing maximum efficiency on some platforms.
Class condition_­variable_­any provides a general condition variable that can wait on objects of user-supplied lock types.
Condition variables permit concurrent invocation of the wait, wait_­for, wait_­until, notify_­one and notify_­all member functions.
The execution of notify_­one and notify_­all shall be atomic.
The execution of wait, wait_­for, and wait_­until shall be performed in three atomic parts:
  1. 1.
    the release of the mutex and entry into the waiting state;
  2. 2.
    the unblocking of the wait; and
  3. 3.
    the reacquisition of the lock.
The implementation shall behave as if all executions of notify_­one, notify_­all, and each part of the wait, wait_­for, and wait_­until executions are executed in a single unspecified total order consistent with the "happens before" order.
Condition variable construction and destruction need not be synchronized.

33.5.1 Header <condition_­variable> synopsis [condition_variable.syn]

namespace std {
  class condition_variable;
  class condition_variable_any;

  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);

  enum class cv_status { no_timeout, timeout };
}

33.5.2 Non-member functions [thread.condition.nonmember]

void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
Requires: lk is locked by the calling thread and either
  • no other thread is waiting on cond, or
  • lk.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_­for, or wait_­until) threads.
Effects: Transfers ownership of the lock associated with lk into internal storage and schedules cond to be notified when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.
This notification shall be as if:
lk.unlock();
cond.notify_all();
Synchronization: The implied lk.unlock() call is sequenced after the destruction of all objects with thread storage duration associated with the current thread.
[Note
:
The supplied lock will be held until the thread exits, and care must be taken to ensure that this does not cause deadlock due to lock ordering issues.
After calling notify_­all_­at_­thread_­exit it is recommended that the thread should be exited as soon as possible, and that no blocking or time-consuming tasks are run on that thread.
end note
]
[Note
:
It is the user's responsibility to ensure that waiting threads do not erroneously assume that the thread has finished if they experience spurious wakeups.
This typically requires that the condition being waited for is satisfied while holding the lock on lk, and that this lock is not released and reacquired prior to calling notify_­all_­at_­thread_­exit.
end note
]

33.5.3 Class condition_­variable [thread.condition.condvar]

namespace std {
  class condition_variable {
  public:

    condition_variable();
    ~condition_variable();

    condition_variable(const condition_variable&) = delete;
    condition_variable& operator=(const condition_variable&) = delete;

    void notify_one() noexcept;
    void notify_all() noexcept;
    void wait(unique_lock<mutex>& lock);
    template <class Predicate>
      void wait(unique_lock<mutex>& lock, Predicate pred);
    template <class Clock, class Duration>
      cv_status wait_until(unique_lock<mutex>& lock,
                           const chrono::time_point<Clock, Duration>& abs_time);
    template <class Clock, class Duration, class Predicate>
      bool wait_until(unique_lock<mutex>& lock,
                      const chrono::time_point<Clock, Duration>& abs_time,
                      Predicate pred);

    template <class Rep, class Period>
      cv_status wait_for(unique_lock<mutex>& lock,
                         const chrono::duration<Rep, Period>& rel_time);
    template <class Rep, class Period, class Predicate>
      bool wait_for(unique_lock<mutex>& lock,
                    const chrono::duration<Rep, Period>& rel_time,
                    Predicate pred);

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}
The class condition_­variable shall be a standard-layout class (Clause [class]).
condition_variable();
Effects: Constructs an object of type condition_­variable.
Throws: system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • resource_­unavailable_­try_­again — if some non-memory resource limitation prevents initialization.
~condition_variable();
Requires: There shall be no thread blocked on *this.
[Note
:
That is, all threads shall have been notified; they may subsequently block on the lock specified in the wait.
This relaxes the usual rules, which would have required all wait calls to happen before destruction.
Only the notification to unblock the wait must happen before destruction.
The user must take care to ensure that no threads wait on *this once the destructor has been started, especially when the waiting threads are calling the wait functions in a loop or using the overloads of wait, wait_­for, or wait_­until that take a predicate.
end note
]
Effects: Destroys the object.
void notify_one() noexcept;
Effects: If any threads are blocked waiting for *this, unblocks one of those threads.
void notify_all() noexcept;
Effects: Unblocks all threads that are blocked waiting for *this.
void wait(unique_lock<mutex>& lock);
Requires: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread, and either
  • no other thread is waiting on this condition_­variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_­for, or wait_­until) threads.
Effects:
  • Atomically calls lock.unlock() and blocks on *this.
  • When unblocked, calls lock.lock() (possibly blocking on the lock), then returns.
  • The function will unblock when signaled by a call to notify_­one() or a call to notify_­all(), or spuriously.
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread.
Throws: Nothing.
template <class Predicate> void wait(unique_lock<mutex>& lock, Predicate pred);
Requires: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread, and either
  • no other thread is waiting on this condition_­variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_­for, or wait_­until) threads.
Effects: Equivalent to:
while (!pred())
  wait(lock);
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread.
Throws: Any exception thrown by pred.
template <class Clock, class Duration> cv_status wait_until(unique_lock<mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time);
Requires: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread, and either
  • no other thread is waiting on this condition_­variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_­for, or wait_­until) threads.
Effects:
  • Atomically calls lock.unlock() and blocks on *this.
  • When unblocked, calls lock.lock() (possibly blocking on the lock), then returns.
  • The function will unblock when signaled by a call to notify_­one(), a call to notify_­all(), expiration of the absolute timeout ([thread.req.timing]) specified by abs_­time, or spuriously.
  • If the function exits via an exception, lock.lock() shall be called prior to exiting the function.
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread.
Returns: cv_­status​::​timeout if the absolute timeout ([thread.req.timing]) specified by abs_­time expired, otherwise cv_­status​::​no_­timeout.
Throws: Timeout-related exceptions ([thread.req.timing]).
template <class Rep, class Period> cv_status wait_for(unique_lock<mutex>& lock, const chrono::duration<Rep, Period>& rel_time);
Requires: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread, and either
  • no other thread is waiting on this condition_­variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_­for, or wait_­until) threads.
Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time);
Returns: cv_­status​::​timeout if the relative timeout ([thread.req.timing]) specified by rel_­time expired, otherwise cv_­status​::​no_­timeout.
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread.
Throws: Timeout-related exceptions ([thread.req.timing]).
template <class Clock, class Duration, class Predicate> bool wait_until(unique_lock<mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
Requires: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread, and either
  • no other thread is waiting on this condition_­variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_­for, or wait_­until) threads.
Effects: Equivalent to:
while (!pred())
  if (wait_until(lock, abs_time) == cv_status::timeout)
    return pred();
return true;
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread.
[Note
:
The returned value indicates whether the predicate evaluated to true regardless of whether the timeout was triggered.
end note
]
Throws: Timeout-related exceptions ([thread.req.timing]) or any exception thrown by pred.
template <class Rep, class Period, class Predicate> bool wait_for(unique_lock<mutex>& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
Requires: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread, and either
  • no other thread is waiting on this condition_­variable object or
  • lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_­for, or wait_­until) threads.
Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
[Note
:
There is no blocking if pred() is initially true, even if the timeout has already expired.
end note
]
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock.owns_­lock() is true and lock.mutex() is locked by the calling thread.
[Note
:
The returned value indicates whether the predicate evaluates to true regardless of whether the timeout was triggered.
end note
]
Throws: Timeout-related exceptions ([thread.req.timing]) or any exception thrown by pred.

33.5.4 Class condition_­variable_­any [thread.condition.condvarany]

A Lock type shall meet the BasicLockable requirements ([thread.req.lockable.basic]).
[Note
:
All of the standard mutex types meet this requirement.
If a Lock type other than one of the standard mutex types or a unique_­lock wrapper for a standard mutex type is used with condition_­variable_­any, the user must ensure that any necessary synchronization is in place with respect to the predicate associated with the condition_­variable_­any instance.
end note
]
namespace std {
  class condition_variable_any {
  public:
    condition_variable_any();
    ~condition_variable_any();

    condition_variable_any(const condition_variable_any&) = delete;
    condition_variable_any& operator=(const condition_variable_any&) = delete;

    void notify_one() noexcept;
    void notify_all() noexcept;
    template <class Lock>
      void wait(Lock& lock);
    template <class Lock, class Predicate>
      void wait(Lock& lock, Predicate pred);

    template <class Lock, class Clock, class Duration>
      cv_status wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time);
    template <class Lock, class Clock, class Duration, class Predicate>
      bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time,
        Predicate pred);
    template <class Lock, class Rep, class Period>
      cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
    template <class Lock, class Rep, class Period, class Predicate>
      bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time,
        Predicate pred);
  };
}
condition_variable_any();
Effects: Constructs an object of type condition_­variable_­any.
Throws: bad_­alloc or system_­error when an exception is required ([thread.req.exception]).
Error conditions:
  • resource_­unavailable_­try_­again — if some non-memory resource limitation prevents initialization.
  • operation_­not_­permitted — if the thread does not have the privilege to perform the operation.
~condition_variable_any();
Requires: There shall be no thread blocked on *this.
[Note
:
That is, all threads shall have been notified; they may subsequently block on the lock specified in the wait.
This relaxes the usual rules, which would have required all wait calls to happen before destruction.
Only the notification to unblock the wait must happen before destruction.
The user must take care to ensure that no threads wait on *this once the destructor has been started, especially when the waiting threads are calling the wait functions in a loop or using the overloads of wait, wait_­for, or wait_­until that take a predicate.
end note
]
Effects: Destroys the object.
void notify_one() noexcept;
Effects: If any threads are blocked waiting for *this, unblocks one of those threads.
void notify_all() noexcept;
Effects: Unblocks all threads that are blocked waiting for *this.
template <class Lock> void wait(Lock& lock);
[Note
:
If any of the wait functions exits via an exception, it is unspecified whether the Lock is held.
One can use a Lock type that allows to query that, such as the unique_­lock wrapper.
end note
]
Effects:
  • Atomically calls lock.unlock() and blocks on *this.
  • When unblocked, calls lock.lock() (possibly blocking on the lock) and returns.
  • The function will unblock when signaled by a call to notify_­one(), a call to notify_­all(), or spuriously.
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock is locked by the calling thread.
Throws: Nothing.
template <class Lock, class Predicate> void wait(Lock& lock, Predicate pred);
Effects: Equivalent to:
while (!pred())
  wait(lock);
template <class Lock, class Clock, class Duration> cv_status wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time);
Effects:
  • Atomically calls lock.unlock() and blocks on *this.
  • When unblocked, calls lock.lock() (possibly blocking on the lock) and returns.
  • The function will unblock when signaled by a call to notify_­one(), a call to notify_­all(), expiration of the absolute timeout ([thread.req.timing]) specified by abs_­time, or spuriously.
  • If the function exits via an exception, lock.lock() shall be called prior to exiting the function.
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock is locked by the calling thread.
Returns: cv_­status​::​timeout if the absolute timeout ([thread.req.timing]) specified by abs_­time expired, otherwise cv_­status​::​no_­timeout.
Throws: Timeout-related exceptions ([thread.req.timing]).
template <class Lock, class Rep, class Period> cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time);
Returns: cv_­status​::​timeout if the relative timeout ([thread.req.timing]) specified by rel_­time expired, otherwise cv_­status​::​no_­timeout.
Remarks: If the function fails to meet the postcondition, terminate() shall be called ([except.terminate]).
[Note
:
This can happen if the re-locking of the mutex throws an exception.
end note
]
Postconditions: lock is locked by the calling thread.
Throws: Timeout-related exceptions ([thread.req.timing]).
template <class Lock, class Clock, class Duration, class Predicate> bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
Effects: Equivalent to:
while (!pred())
  if (wait_until(lock, abs_time) == cv_status::timeout)
    return pred();
return true;
[Note
:
There is no blocking if pred() is initially true, or if the timeout has already expired.
end note
]
[Note
:
The returned value indicates whether the predicate evaluates to true regardless of whether the timeout was triggered.
end note
]
template <class Lock, class Rep, class Period, class Predicate> bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));

33.6 Futures [futures]

33.6.1 Overview [futures.overview]

[futures] describes components that a C++ program can use to retrieve in one thread the result (value or exception) from a function that has run in the same thread or another thread.
[Note
:
These components are not restricted to multi-threaded programs but can be useful in single-threaded programs as well.
end note
]

33.6.2 Header <future> synopsis [future.syn]

namespace std {
  enum class future_errc {
    broken_promise = implementation-defined,
    future_already_retrieved = implementation-defined,
    promise_already_satisfied = implementation-defined,
    no_state = implementation-defined
  };

  enum class launch : unspecified {
    async = unspecified,
    deferred = unspecified,
    implementation-defined
  };

  enum class future_status {
    ready,
    timeout,
    deferred
  };

  template <> struct is_error_code_enum<future_errc> : public true_type { };
  error_code make_error_code(future_errc e) noexcept;
  error_condition make_error_condition(future_errc e) noexcept;

  const error_category& future_category() noexcept;

  class future_error;

  template <class R> class promise;
  template <class R> class promise<R&>;
  template <> class promise<void>;

  template <class R>
    void swap(promise<R>& x, promise<R>& y) noexcept;

  template <class R, class Alloc>
    struct uses_allocator<promise<R>, Alloc>;

  template <class R> class future;
  template <class R> class future<R&>;
  template <> class future<void>;

  template <class R> class shared_future;
  template <class R> class shared_future<R&>;
  template <> class shared_future<void>;

  template <class> class packaged_task;   // not defined
  template <class R, class... ArgTypes>
    class packaged_task<R(ArgTypes...)>;

  template <class R, class... ArgTypes>
    void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;

  template <class R, class Alloc>
    struct uses_allocator<packaged_task<R>, Alloc>;

  template <class F, class... Args>
    future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(F&& f, Args&&... args);
  template <class F, class... Args>
    future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(launch policy, F&& f, Args&&... args);
}
The enum type launch is a bitmask type ([bitmask.types]) with elements launch​::​async and launch​::​deferred.
[Note
:
Implementations can provide bitmasks to specify restrictions on task interaction by functions launched by async() applicable to a corresponding subset of available launch policies.
Implementations can extend the behavior of the first overload of async() by adding their extensions to the launch policy under the “as if” rule.
end note
]
The enum values of future_­errc are distinct and not zero.

33.6.3 Error handling [futures.errors]

const error_category& future_category() noexcept;
Returns: A reference to an object of a type derived from class error_­category.
The object's default_­error_­condition and equivalent virtual functions shall behave as specified for the class error_­category.
The object's name virtual function shall return a pointer to the string "future".
error_code make_error_code(future_errc e) noexcept;
Returns: error_­code(static_­cast<int>(e), future_­category()).
error_condition make_error_condition(future_errc e) noexcept;
Returns: error_­condition(static_­cast<int>(e), future_­category()).

33.6.4 Class future_­error [futures.future_error]

namespace std {
  class future_error : public logic_error {
  public:
    explicit future_error(future_errc e);

    const error_code& code() const noexcept;
    const char*       what() const noexcept;
  private:
    error_code ec_;  // exposition only
  };
}
explicit future_error(future_errc e);
Effects: Constructs an object of class future_­error and initializes ec_­ with make_­error_­code(e).
const error_code& code() const noexcept;
Returns: ec_­.
const char* what() const noexcept;
Returns: An ntbs incorporating code().message().

33.6.5 Shared state [futures.state]

Many of the classes introduced in this subclause use some state to communicate results.
This shared state consists of some state information and some (possibly not yet evaluated) result, which can be a (possibly void) value or an exception.
[Note
:
Futures, promises, and tasks defined in this clause reference such shared state.
end note
]
[Note
:
The result can be any kind of object including a function to compute that result, as used by async when policy is launch​::​deferred.
end note
]
An asynchronous return object is an object that reads results from a shared state.
A waiting function of an asynchronous return object is one that potentially blocks to wait for the shared state to be made ready.
If a waiting function can return before the state is made ready because of a timeout ([thread.req.lockable]), then it is a timed waiting function, otherwise it is a non-timed waiting function.
An asynchronous provider is an object that provides a result to a shared state.
The result of a shared state is set by respective functions on the asynchronous provider.
[Note
:
Such as promises or tasks.
end note
]
The means of setting the result of a shared state is specified in the description of those classes and functions that create such a state object.
When an asynchronous return object or an asynchronous provider is said to release its shared state, it means:
  • if the return object or provider holds the last reference to its shared state, the shared state is destroyed; and
  • the return object or provider gives up its reference to its shared state; and
  • these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std​::​async, the shared state is not yet ready, and this was the last reference to the shared state.
When an asynchronous provider is said to make its shared state ready, it means:
  • first, the provider marks its shared state as ready; and
  • second, the provider unblocks any execution agents waiting for its shared state to become ready.
When an asynchronous provider is said to abandon its shared state, it means:
  • first, if that state is not ready, the provider
    • stores an exception object of type future_­error with an error condition of broken_­promise within its shared state; and then
    • makes its shared state ready;
  • second, the provider releases its shared state.
A shared state is ready only if it holds a value or an exception ready for retrieval.
Waiting for a shared state to become ready may invoke code to compute the result on the waiting thread if so specified in the description of the class or function that creates the state object.
Calls to functions that successfully set the stored result of a shared state synchronize with ([intro.multithread]) calls to functions successfully detecting the ready state resulting from that setting.
The storage of the result (whether normal or exceptional) into the shared state synchronizes with ([intro.multithread]) the successful return from a call to a waiting function on the shared state.
Some functions (e.g., promise​::​set_­value_­at_­thread_­exit) delay making the shared state ready until the calling thread exits.
The destruction of each of that thread's objects with thread storage duration ([basic.stc.thread]) is sequenced before making that shared state ready.
Access to the result of the same shared state may conflict ([intro.multithread]).
[Note
:
This explicitly specifies that the result of the shared state is visible in the objects that reference this state in the sense of data race avoidance ([res.on.data.races]).
For example, concurrent accesses through references returned by shared_­future​::​get() ([futures.shared_future]) must either use read-only operations or provide additional synchronization.
end note
]

33.6.6 Class template promise [futures.promise]

namespace std {
  template <class R>
  class promise {
  public:
    promise();
    template <class Allocator>
      promise(allocator_arg_t, const Allocator& a);
    promise(promise&& rhs) noexcept;
    promise(const promise& rhs) = delete;
    ~promise();

    // assignment
    promise& operator=(promise&& rhs) noexcept;
    promise& operator=(const promise& rhs) = delete;
    void swap(promise& other) noexcept;

    // retrieving the result
    future<R> get_future();

    // setting the result
    void set_value(see below);
    void set_exception(exception_ptr p);

    // setting the result with deferred notification
    void set_value_at_thread_exit(see below);
    void set_exception_at_thread_exit(exception_ptr p);
  };
  template <class R>
    void swap(promise<R>& x, promise<R>& y) noexcept;
  template <class R, class Alloc>
    struct uses_allocator<promise<R>, Alloc>;
}
The implementation shall provide the template promise and two specializations, promise<R&> and promise<​void>.
These differ only in the argument type of the member functions set_­value and set_­value_­at_­thread_­exit, as set out in their descriptions, below.
The set_­value, set_­exception, set_­value_­at_­thread_­exit, and set_­exception_­at_­thread_­exit member functions behave as though they acquire a single mutex associated with the promise object while updating the promise object.
template <class R, class Alloc> struct uses_allocator<promise<R>, Alloc> : true_type { };
Requires: Alloc shall be an Allocator ([allocator.requirements]).
promise(); template <class Allocator> promise(allocator_arg_t, const Allocator& a);
Effects: constructs a promise object and a shared state.
The second constructor uses the allocator a to allocate memory for the shared state.
promise(promise&& rhs) noexcept;
Effects: constructs a new promise object and transfers ownership of the shared state of rhs (if any) to the newly-constructed object.
Postconditions: rhs has no shared state.
~promise();
Effects: Abandons any shared state ([futures.state]).
promise& operator=(promise&& rhs) noexcept;
Effects: Abandons any shared state ([futures.state]) and then as if promise(std​::​move(rhs)).swap(*this).
Returns: *this.
void swap(promise& other) noexcept;
Effects: Exchanges the shared state of *this and other.
Postconditions: *this has the shared state (if any) that other had prior to the call to swap.
other has the shared state (if any) that *this had prior to the call to swap.
future<R> get_future();
Returns: A future<R> object with the same shared state as *this.
Throws: future_­error if *this has no shared state or if get_­future has already been called on a promise with the same shared state as *this.
Error conditions:
  • future_­already_­retrieved if get_­future has already been called on a promise with the same shared state as *this.
  • no_­state if *this has no shared state.
void promise::set_value(const R& r); void promise::set_value(R&& r); void promise<R&>::set_value(R& r); void promise<void>::set_value();
Effects: Atomically stores the value r in the shared state and makes that state ready ([futures.state]).
Throws:
  • future_­error if its shared state already has a stored value or exception, or
  • for the first version, any exception thrown by the constructor selected to copy an object of R, or
  • for the second version, any exception thrown by the constructor selected to move an object of R.
Error conditions:
  • promise_­already_­satisfied if its shared state already has a stored value or exception.
  • no_­state if *this has no shared state.
void set_exception(exception_ptr p);
Requires: p is not null.
Effects: Atomically stores the exception pointer p in the shared state and makes that state ready ([futures.state]).
Throws: future_­error if its shared state already has a stored value or exception.
Error conditions:
  • promise_­already_­satisfied if its shared state already has a stored value or exception.
  • no_­state if *this has no shared state.
void promise::set_value_at_thread_exit(const R& r); void promise::set_value_at_thread_exit(R&& r); void promise<R&>::set_value_at_thread_exit(R& r); void promise<void>::set_value_at_thread_exit();
Effects: Stores the value r in the shared state without making that state ready immediately.
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.
Throws:
  • future_­error if its shared state already has a stored value or exception, or
  • for the first version, any exception thrown by the constructor selected to copy an object of R, or
  • for the second version, any exception thrown by the constructor selected to move an object of R.
Error conditions:
  • promise_­already_­satisfied if its shared state already has a stored value or exception.
  • no_­state if *this has no shared state.
void set_exception_at_thread_exit(exception_ptr p);
Requires: p is not null.
Effects: Stores the exception pointer p in the shared state without making that state ready immediately.
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.
Throws: future_­error if an error condition occurs.
Error conditions:
  • promise_­already_­satisfied if its shared state already has a stored value or exception.
  • no_­state if *this has no shared state.
template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
Effects: As if by x.swap(y).

33.6.7 Class template future [futures.unique_future]

The class template future defines a type for asynchronous return objects which do not share their shared state with other asynchronous return objects.
A default-constructed future object has no shared state.
A future object with shared state can be created by functions on asynchronous providers ([futures.state]) or by the move constructor and shares its shared state with the original asynchronous provider.
The result (value or exception) of a future object can be set by calling a respective function on an object that shares the same shared state.
[Note
:
Member functions of future do not synchronize with themselves or with member functions of shared_­future.
end note
]
The effect of calling any member function other than the destructor, the move-assignment operator, share, or valid on a future object for which valid() == false is undefined.
[Note
:
It is valid to move from a future object for which valid() == false.
end note
]
[Note
:
Implementations are encouraged to detect this case and throw an object of type future_­error with an error condition of future_­errc​::​no_­state.
end note
]
namespace std {
  template <class R>
  class future {
  public:
    future() noexcept;
    future(future&&) noexcept;
    future(const future& rhs) = delete;
    ~future();
    future& operator=(const future& rhs) = delete;
    future& operator=(future&&) noexcept;
    shared_future<R> share() noexcept;

    // retrieving the value
    see below get();

    // functions to check state
    bool valid() const noexcept;

    void wait() const;
    template <class Rep, class Period>
      future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
    template <class Clock, class Duration>
      future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
  };
}
The implementation shall provide the template future and two specializations, future<R&> and future<​void>.
These differ only in the return type and return value of the member function get, as set out in its description, below.
future() noexcept;
Effects: Constructs an empty future object that does not refer to a shared state.
Postconditions: valid() == false.
future(future&& rhs) noexcept;
Effects: Move constructs a future object that refers to the shared state that was originally referred to by rhs (if any).
Postconditions:
  • valid() returns the same value as rhs.valid() prior to the constructor invocation.
  • rhs.valid() == false.
~future();
Effects:
future& operator=(future&& rhs) noexcept;
Effects:
Postconditions:
  • valid() returns the same value as rhs.valid() prior to the assignment.
  • rhs.valid() == false.
shared_future<R> share() noexcept;
Returns: shared_­future<R>(std​::​move(*this)).
Postconditions: valid() == false.
R future::get(); R& future<R&>::get(); void future<void>::get();
[Note
:
As described above, the template and its two required specializations differ only in the return type and return value of the member function get.
end note
]
Effects:
  • wait()s until the shared state is ready, then retrieves the value stored in the shared state;
  • releases any shared state ([futures.state]).
Returns:
  • future​::​get() returns the value v stored in the object's shared state as std​::​move(v).
  • future<R&>​::​get() returns the reference stored as value in the object's shared state.
  • future<void>​::​get() returns nothing.
Throws: the stored exception, if an exception was stored in the shared state.
Postconditions: valid() == false.
bool valid() const noexcept;
Returns: true only if *this refers to a shared state.
void wait() const;
Effects: Blocks until the shared state is ready.
template <class Rep, class Period> future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the relative timeout ([thread.req.timing]) specified by rel_­time has expired.
Returns:
  • future_­status​::​deferred if the shared state contains a deferred function.
  • future_­status​::​ready if the shared state is ready.
  • future_­status​::​timeout if the function is returning because the relative timeout ([thread.req.timing]) specified by rel_­time has expired.
Throws: timeout-related exceptions ([thread.req.timing]).
template <class Clock, class Duration> future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the absolute timeout ([thread.req.timing]) specified by abs_­time has expired.
Returns:
  • future_­status​::​deferred if the shared state contains a deferred function.
  • future_­status​::​ready if the shared state is ready.
  • future_­status​::​timeout if the function is returning because the absolute timeout ([thread.req.timing]) specified by abs_­time has expired.
Throws: timeout-related exceptions ([thread.req.timing]).

33.6.8 Class template shared_­future [futures.shared_future]

The class template shared_­future defines a type for asynchronous return objects which may share their shared state with other asynchronous return objects.
A default-constructed shared_­future object has no shared state.
A shared_­future object with shared state can be created by conversion from a future object and shares its shared state with the original asynchronous provider ([futures.state]) of the shared state.
The result (value or exception) of a shared_­future object can be set by calling a respective function on an object that shares the same shared state.
[Note
:
Member functions of shared_­future do not synchronize with themselves, but they synchronize with the shared state.
end note
]
The effect of calling any member function other than the destructor, the move-assignment operator, the copy-assignment operator, or valid() on a shared_­future object for which valid() == false is undefined.
[Note
:
It is valid to copy or move from a shared_­future object for which valid() is false.
end note
]
[Note
:
Implementations are encouraged to detect this case and throw an object of type future_­error with an error condition of future_­errc​::​no_­state.
end note
]
namespace std {
  template <class R>
  class shared_future {
  public:
    shared_future() noexcept;
    shared_future(const shared_future& rhs) noexcept;
    shared_future(future<R>&&) noexcept;
    shared_future(shared_future&& rhs) noexcept;
    ~shared_future();
    shared_future& operator=(const shared_future& rhs) noexcept;
    shared_future& operator=(shared_future&& rhs) noexcept;

    // retrieving the value
    see below get() const;

    // functions to check state
    bool valid() const noexcept;

    void wait() const;
    template <class Rep, class Period>
      future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
    template <class Clock, class Duration>
      future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
  };
}
The implementation shall provide the template shared_­future and two specializations, shared_­future<R&> and shared_­future<void>.
These differ only in the return type and return value of the member function get, as set out in its description, below.
shared_future() noexcept;
Effects: Constructs an empty shared_­future object that does not refer to a shared state.
Postconditions: valid() == false.
shared_future(const shared_future& rhs) noexcept;
Effects: Constructs a shared_­future object that refers to the same shared state as rhs (if any).
Postconditions: valid() returns the same value as rhs.valid().
shared_future(future<R>&& rhs) noexcept; shared_future(shared_future&& rhs) noexcept;
Effects: Move constructs a shared_­future object that refers to the shared state that was originally referred to by rhs (if any).
Postconditions:
  • valid() returns the same value as rhs.valid() returned prior to the constructor invocation.
  • rhs.valid() == false.
~shared_future();
Effects:
shared_future& operator=(shared_future&& rhs) noexcept;
Effects:
Postconditions:
  • valid() returns the same value as rhs.valid() returned prior to the assignment.
  • rhs.valid() == false.
shared_future& operator=(const shared_future& rhs) noexcept;
Effects:
  • Releases any shared state ([futures.state]);
  • assigns the contents of rhs to *this.
    [Note
    :
    As a result, *this refers to the same shared state as rhs (if any).
    end note
    ]
Postconditions: valid() == rhs.valid().
const R& shared_future::get() const; R& shared_future<R&>::get() const; void shared_future<void>::get() const;
[Note
:
As described above, the template and its two required specializations differ only in the return type and return value of the member function get.
end note
]
[Note
:
Access to a value object stored in the shared state is unsynchronized, so programmers should apply only those operations on R that do not introduce a data race ([intro.multithread]).
end note
]
Effects: wait()s until the shared state is ready, then retrieves the value stored in the shared state.
Returns:
  • shared_­future​::​get() returns a const reference to the value stored in the object's shared state.
    [Note
    :
    Access through that reference after the shared state has been destroyed produces undefined behavior; this can be avoided by not storing the reference in any storage with a greater lifetime than the shared_­future object that returned the reference.
    end note
    ]
  • shared_­future<R&>​::​get() returns the reference stored as value in the object's shared state.
  • shared_­future<void>​::​get() returns nothing.
Throws: the stored exception, if an exception was stored in the shared state.
bool valid() const noexcept;
Returns: true only if *this refers to a shared state.
void wait() const;
Effects: Blocks until the shared state is ready.
template <class Rep, class Period> future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the relative timeout ([thread.req.timing]) specified by rel_­time has expired.
Returns:
  • future_­status​::​deferred if the shared state contains a deferred function.
  • future_­status​::​ready if the shared state is ready.
  • future_­status​::​timeout if the function is returning because the relative timeout ([thread.req.timing]) specified by rel_­time has expired.
Throws: timeout-related exceptions ([thread.req.timing]).
template <class Clock, class Duration> future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the absolute timeout ([thread.req.timing]) specified by abs_­time has expired.
Returns:
  • future_­status​::​deferred if the shared state contains a deferred function.
  • future_­status​::​ready if the shared state is ready.
  • future_­status​::​timeout if the function is returning because the absolute timeout ([thread.req.timing]) specified by abs_­time has expired.
Throws: timeout-related exceptions ([thread.req.timing]).

33.6.9 Function template async [futures.async]

The function template async provides a mechanism to launch a function potentially in a new thread and provides the result of the function in a future object with which it shares a shared state.
template <class F, class... Args> future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(F&& f, Args&&... args); template <class F, class... Args> future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(launch policy, F&& f, Args&&... args);
Requires: F and each Ti in Args shall satisfy the MoveConstructible requirements, and
INVOKE(DECAY_COPY(std::forward<F>(f)),
       DECAY_COPY(std::forward<Args>(args))...)     // see [func.require], [thread.thread.constr]
shall be a valid expression.
Effects: The first function behaves the same as a call to the second function with a policy argument of launch​::​async | launch​::​deferred and the same arguments for F and Args.
The second function creates a shared state that is associated with the returned future object.
The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):
  • If launch​::​async is set in policy, calls INVOKE(DECAY_­COPY(std​::​forward<F>(f)), DECAY_­COPY(std​::​forward<Args>(args))...) ([func.require], [thread.thread.constr]) as if in a new thread of execution represented by a thread object with the calls to DECAY_­COPY() being evaluated in the thread that called async.
    Any return value is stored as the result in the shared state.
    Any exception propagated from the execution of INVOKE(DECAY_­COPY(std​::​forward<F>(f)), DECAY_­COPY(std​::​forward<Args>(args))...) is stored as the exceptional result in the shared state.
    The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.
  • If launch​::​deferred is set in policy, stores DECAY_­COPY(std​::​forward<F>(f)) and DECAY_­COPY(std​::​forward<Args>(args))... in the shared state.
    These copies of f and args constitute a deferred function.
    Invocation of the deferred function evaluates INVOKE(std​::​move(g), std​::​move(xyz)) where g is the stored value of DECAY_­COPY(std​::​forward<F>(f)) and xyz is the stored copy of DECAY_­COPY(std​::​forward<Args>(args))....
    Any return value is stored as the result in the shared state.
    Any exception propagated from the execution of the deferred function is stored as the exceptional result in the shared state.
    The shared state is not made ready until the function has completed.
    The first call to a non-timed waiting function ([futures.state]) on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function.
    Once evaluation of INVOKE(std​::​move(g), std​::​move(xyz)) begins, the function is no longer considered deferred.
    [Note
    :
    If this policy is specified together with other policies, such as when using a policy value of launch​::​async | launch​::​deferred, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.
    end note
    ]
  • If no value is set in the launch policy, or a value is set that is neither specified in this International Standard nor by the implementation, the behavior is undefined.
Returns: An object of type future<invoke_­result_­t<decay_­t<F>, decay_­t<Args>...>> that refers to the shared state created by this call to async.
[Note
:
If a future obtained from async is moved outside the local scope, other code that uses the future must be aware that the future's destructor may block for the shared state to become ready.
end note
]
Synchronization: Regardless of the provided policy argument,
  • the invocation of async synchronizes with ([intro.multithread]) the invocation of f.
    [Note
    :
    This statement applies even when the corresponding future object is moved to another thread.
    end note
    ]
    ; and
  • the completion of the function f is sequenced before ([intro.multithread]) the shared state is made ready.
    [Note
    :
    f might not be called at all, so its completion might never happen.
    end note
    ]
If the implementation chooses the launch​::​async policy,
  • a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined, or else time out ([thread.thread.member]);
  • the associated thread completion synchronizes with ([intro.multithread]) the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.
Throws: system_­error if policy == launch​::​async and the implementation is unable to start a new thread, or std​::​bad_­alloc if memory for the internal data structures could not be allocated.
Error conditions:
  • resource_­unavailable_­try_­again — if policy == launch​::​async and the system is unable to start a new thread.
[Example
:
int work1(int value);
int work2(int value);
int work(int value) {
  auto handle = std::async([=]{ return work2(value); });
  int tmp = work1(value);
  return tmp + handle.get();    // #1
}
[Note
:
Line #1 might not result in concurrency because the async call uses the default policy, which may use launch​::​deferred, in which case the lambda might not be invoked until the get() call; in that case, work1 and work2 are called on the same thread and there is no concurrency.
end note
]
end example
]

33.6.10 Class template packaged_­task [futures.task]

The class template packaged_­task defines a type for wrapping a function or callable object so that the return value of the function or callable object is stored in a future when it is invoked.
When the packaged_­task object is invoked, its stored task is invoked and the result (whether normal or exceptional) stored in the shared state.
Any futures that share the shared state will then be able to access the stored result.
namespace std {
  template<class> class packaged_task; // not defined

  template<class R, class... ArgTypes>
  class packaged_task<R(ArgTypes...)> {
  public:
    // construction and destruction
    packaged_task() noexcept;
    template <class F>
      explicit packaged_task(F&& f);
    ~packaged_task();

    // no copy
    packaged_task(const packaged_task&) = delete;
    packaged_task& operator=(const packaged_task&) = delete;

    // move support
    packaged_task(packaged_task&& rhs) noexcept;
    packaged_task& operator=(packaged_task&& rhs) noexcept;
    void swap(packaged_task& other) noexcept;

    bool valid() const noexcept;

    // result retrieval
    future<R> get_future();

    // execution
    void operator()(ArgTypes... );
    void make_ready_at_thread_exit(ArgTypes...);

    void reset();
  };
  template <class R, class... ArgTypes>
    void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
  template <class R, class Alloc>
    struct uses_allocator<packaged_task<R>, Alloc>;
}

33.6.10.1 packaged_­task member functions [futures.task.members]

packaged_task() noexcept;
Effects: Constructs a packaged_­task object with no shared state and no stored task.
template <class F> packaged_task(F&& f);
Requires: INVOKE<R>(f, t1, t2, ..., tN), where t1, t2, ..., tN are values of the corresponding types in ArgTypes..., shall be a valid expression.
Invoking a copy of f shall behave the same as invoking f.
Remarks: This constructor shall not participate in overload resolution if decay_­t<F> is the same type as packaged_­task<R(ArgTypes...)>.
Effects: Constructs a new packaged_­task object with a shared state and initializes the object's stored task with std​::​forward<F>(f).
Throws:
  • Any exceptions thrown by the copy or move constructor of f.
  • For the first version, bad_­alloc if memory for the internal data structures could not be allocated.
  • For the second version, any exceptions thrown by allocator_­traits<Allocator>​::​template rebind_­traits<unspecified>​::​allocate.
packaged_task(packaged_task&& rhs) noexcept;
Effects: Constructs a new packaged_­task object and transfers ownership of rhs's shared state to *this, leaving rhs with no shared state.
Moves the stored task from rhs to *this.
Postconditions: rhs has no shared state.
packaged_task& operator=(packaged_task&& rhs) noexcept;
Effects:
~packaged_task();
Effects: Abandons any shared state ([futures.state]).
void swap(packaged_task& other) noexcept;
Effects: Exchanges the shared states and stored tasks of *this and other.
Postconditions: *this has the same shared state and stored task (if any) as other prior to the call to swap.
other has the same shared state and stored task (if any) as *this prior to the call to swap.
bool valid() const noexcept;
Returns: true only if *this has a shared state.
future<R> get_future();
Returns: A future object that shares the same shared state as *this.
Throws: a future_­error object if an error occurs.
Error conditions:
  • future_­already_­retrieved if get_­future has already been called on a packaged_­task object with the same shared state as *this.
  • no_­state if *this has no shared state.
void operator()(ArgTypes... args);
Effects: As if by INVOKE<R>(f, t1, t2, ..., tN), where f is the stored task of *this and t1, t2, ..., tN are the values in args....
If the task returns normally, the return value is stored as the asynchronous result in the shared state of *this, otherwise the exception thrown by the task is stored.
The shared state of *this is made ready, and any threads blocked in a function waiting for the shared state of *this to become ready are unblocked.
Throws: a future_­error exception object if there is no shared state or the stored task has already been invoked.
Error conditions:
  • promise_­already_­satisfied if the stored task has already been invoked.
  • no_­state if *this has no shared state.
void make_ready_at_thread_exit(ArgTypes... args);
Effects: As if by INVOKE<R>(f, t1, t2, ..., tN), where f is the stored task and t1, t2, ..., tN are the values in args....
If the task returns normally, the return value is stored as the asynchronous result in the shared state of *this, otherwise the exception thrown by the task is stored.
In either case, this shall be done without making that state ready ([futures.state]) immediately.
Schedules the shared state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.
Throws: future_­error if an error condition occurs.
Error conditions:
  • promise_­already_­satisfied if the stored task has already been invoked.
  • no_­state if *this has no shared state.
void reset();
Effects: As if *this = packaged_­task(std​::​move(f)), where f is the task stored in *this.
[Note
:
This constructs a new shared state for *this.
The old state is abandoned ([futures.state]).
end note
]
Throws:
  • bad_­alloc if memory for the new shared state could not be allocated.
  • any exception thrown by the move constructor of the task stored in the shared state.
  • future_­error with an error condition of no_­state if *this has no shared state.

33.6.10.2 packaged_­task globals [futures.task.nonmembers]

template <class R, class... ArgTypes> void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
Effects: As if by x.swap(y).
template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc> : true_type { };
Requires: Alloc shall be an Allocator ([allocator.requirements]).

Annex A (informative) Grammar summary [gram]

This summary of C++  grammar is intended to be an aid to comprehension.
It is not an exact statement of the language.
In particular, the grammar described here accepts a superset of valid C++  constructs.
Disambiguation rules ([stmt.ambig], [dcl.spec], [class.member.lookup]) must be applied to distinguish expressions from declarations.
Further, access control, ambiguity, and type rules must be used to weed out syntactically valid but meaningless constructs.

A.1 Keywords [gram.key]

New context-dependent keywords are introduced into a program by typedef ([dcl.typedef]), namespace ([namespace.def]), class (Clause [class]), enumeration ([dcl.enum]), and template (Clause [temp]) declarations.

A.2 Lexical conventions [gram.lex]

hex-quad:
	hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
universal-character-name:
	\u hex-quad
	\U hex-quad hex-quad
preprocessing-token:
	header-name
	identifier
	pp-number
	character-literal
	user-defined-character-literal
	string-literal
	user-defined-string-literal
	preprocessing-op-or-punc
	each non-white-space character that cannot be one of the above
token:
	identifier
	keyword
	literal
	operator
	punctuator
header-name:
	< h-char-sequence >
	" q-char-sequence "
h-char-sequence:
	h-char
	h-char-sequence h-char
h-char:
	any member of the source character set except new-line and >
q-char-sequence:
	q-char
	q-char-sequence q-char
q-char:
	any member of the source character set except new-line and "
pp-number:
	digit
	. digit
	pp-number digit
	pp-number identifier-nondigit
	pp-number ' digit
	pp-number ' nondigit
	pp-number e sign
	pp-number E sign
	pp-number p sign
	pp-number P sign
	pp-number .
identifier:
	identifier-nondigit
	identifier identifier-nondigit
	identifier digit
identifier-nondigit:
	nondigit
	universal-character-name
nondigit: one of
	a b c d e f g h i j k l m
	n o p q r s t u v w x y z
	A B C D E F G H I J K L M
	N O P Q R S T U V W X Y Z _
digit: one of
	0 1 2 3 4 5 6 7 8 9
preprocessing-op-or-punc: one of
	{ 	} 	[ 	] 	# 	## 	( 	)
	<: 	:> 	<% 	%> 	%: 	%:%: 	; 	: 	...
	new 	delete 	? 	:: 	. 	.*
	+ 	- 	* 	/ 	% 	^	& 	| 	~
	! 	= 	< 	> 	+= 	-= 	*= 	/= 	%=
	^= 	&= 	|= 	<< 	>> 	>>= 	<<= 	== 	!=
	<= 	>= 	&& 	|| 	++ 	-- 	, 	->* 	->
	and 	and_eq 	bitand 	bitor 	compl 	not 	not_eq
	or 	or_eq 	xor 	xor_eq
literal:
	integer-literal
	character-literal
	floating-literal
	string-literal
	boolean-literal
	pointer-literal
	user-defined-literal
integer-literal:
	binary-literal integer-suffix
	octal-literal integer-suffix
	decimal-literal integer-suffix
	hexadecimal-literal integer-suffix
binary-literal:
	0b binary-digit
	0B binary-digit
	binary-literal ' binary-digit
octal-literal:
	0
	octal-literal ' octal-digit
decimal-literal:
	nonzero-digit
	decimal-literal ' digit
hexadecimal-literal:
	hexadecimal-prefix hexadecimal-digit-sequence
binary-digit:
	0
	1
octal-digit: one of
	0  1  2  3  4  5  6  7
nonzero-digit: one of
	1  2  3  4  5  6  7  8  9
hexadecimal-prefix: one of
	0x  0X
hexadecimal-digit-sequence:
	hexadecimal-digit
	hexadecimal-digit-sequence ' hexadecimal-digit
hexadecimal-digit: one of
	0  1  2  3  4  5  6  7  8  9
	a  b  c  d  e  f
	A  B  C  D  E  F
integer-suffix:
	unsigned-suffix long-suffix
	unsigned-suffix long-long-suffix
	long-suffix unsigned-suffix
	long-long-suffix unsigned-suffix
unsigned-suffix: one of
	u  U
long-suffix: one of
	l  L
long-long-suffix: one of
	ll  LL
character-literal:
	encoding-prefix ' c-char-sequence '
encoding-prefix: one of
	u8  u  U  L
c-char-sequence:
	c-char
	c-char-sequence c-char
c-char:
	any member of the source character set except
		the single-quote ', backslash \, or new-line character
	escape-sequence
	universal-character-name
escape-sequence:
	simple-escape-sequence
	octal-escape-sequence
	hexadecimal-escape-sequence
simple-escape-sequence: one of
	\'  \"  \?  \\
	\a  \b  \f  \n  \r  \t  \v
octal-escape-sequence:
	\ octal-digit
	\ octal-digit octal-digit
	\ octal-digit octal-digit octal-digit
hexadecimal-escape-sequence:
	\x hexadecimal-digit
	hexadecimal-escape-sequence hexadecimal-digit
floating-literal:
	decimal-floating-literal
	hexadecimal-floating-literal
decimal-floating-literal:
	fractional-constant exponent-part floating-suffix
	digit-sequence exponent-part floating-suffix
hexadecimal-floating-literal:
	hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffix
	hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffix
fractional-constant:
	digit-sequence . digit-sequence
	digit-sequence .
hexadecimal-fractional-constant:
	hexadecimal-digit-sequence . hexadecimal-digit-sequence
	hexadecimal-digit-sequence .
exponent-part:
	e sign digit-sequence
	E sign digit-sequence
binary-exponent-part:
	p sign digit-sequence
	P sign digit-sequence
sign: one of
	+  -
digit-sequence:
	digit
	digit-sequence ' digit
floating-suffix: one of
	f  l  F  L
string-literal:
	encoding-prefix " s-char-sequence "
	encoding-prefix R raw-string
s-char-sequence:
	s-char
	s-char-sequence s-char
s-char:
	any member of the source character set except
		the double-quote ", backslash \, or new-line character
	escape-sequence
	universal-character-name
raw-string:
	" d-char-sequence ( r-char-sequence ) d-char-sequence "
r-char-sequence:
	r-char
	r-char-sequence r-char
r-char:
	any member of the source character set, except
		a right parenthesis ) followed by the initial d-char-sequence
		(which may be empty) followed by a double quote ".
d-char-sequence:
	d-char
	d-char-sequence d-char
d-char:
	any member of the basic source character set except:
		space, the left parenthesis (, the right parenthesis ), the backslash \,
		and the control characters representing horizontal tab,
		vertical tab, form feed, and newline.
boolean-literal:
	false
	true
pointer-literal:
	nullptr
user-defined-literal:
	user-defined-integer-literal
	user-defined-floating-literal
	user-defined-string-literal
	user-defined-character-literal
user-defined-integer-literal:
	decimal-literal ud-suffix
	octal-literal ud-suffix
	hexadecimal-literal ud-suffix
	binary-literal ud-suffix
user-defined-floating-literal:
	fractional-constant exponent-part ud-suffix
	digit-sequence exponent-part ud-suffix
	hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part ud-suffix
	hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part ud-suffix
user-defined-string-literal:
	string-literal ud-suffix
user-defined-character-literal:
	character-literal ud-suffix
ud-suffix:
	identifier

A.4 Expressions [gram.expr]

primary-expression:
	literal
	this
	( expression )
	id-expression
	lambda-expression
	fold-expression
id-expression:
	unqualified-id
	qualified-id
unqualified-id:
	identifier
	operator-function-id
	conversion-function-id
	literal-operator-id
	~ class-name
	~ decltype-specifier
	template-id
qualified-id:
	nested-name-specifier template unqualified-id
nested-name-specifier:
	::
	type-name ::
	namespace-name ::
	decltype-specifier ::
	nested-name-specifier identifier ::
	nested-name-specifier template simple-template-id ::
lambda-expression:
	lambda-introducer lambda-declarator compound-statement
lambda-introducer:
	[ lambda-capture ]
lambda-declarator:
	( parameter-declaration-clause ) decl-specifier-seq
	noexcept-specifier attribute-specifier-seq trailing-return-type
lambda-capture:
	capture-default
	capture-list
	capture-default , capture-list
capture-default:
	&
	=
capture-list:
	capture ...
	capture-list , capture ...
capture:
	simple-capture
	init-capture
simple-capture:
	identifier
	& identifier
	this
	* this
init-capture:
	identifier initializer
	& identifier initializer
fold-expression:
	( cast-expression fold-operator ... )
	( ... fold-operator cast-expression )
	( cast-expression fold-operator ... fold-operator cast-expression )
fold-operator: one of
	+   -   *   /   %   ^   &   |   <<   >> 
	+=  -=  *=  /=  %=  ^=  &=  |=  <<=  >>=  =
	==  !=  <   >   <=  >=  &&  ||  ,    .*   ->*
postfix-expression:
	primary-expression
	postfix-expression [ expr-or-braced-init-list ]
	postfix-expression ( expression-list )
	simple-type-specifier ( expression-list )
	typename-specifier ( expression-list )
	simple-type-specifier braced-init-list
	typename-specifier braced-init-list
	postfix-expression . template id-expression
	postfix-expression -> template id-expression
	postfix-expression . pseudo-destructor-name
	postfix-expression -> pseudo-destructor-name
	postfix-expression ++
	postfix-expression --
	dynamic_cast < type-id > ( expression )
	static_cast < type-id > ( expression )
	reinterpret_cast < type-id > ( expression )
	const_cast < type-id > ( expression )
	typeid ( expression )
	typeid ( type-id )
expression-list:
	initializer-list
pseudo-destructor-name:
	nested-name-specifier type-name ::~ type-name
	nested-name-specifier template simple-template-id ::~ type-name
	~ type-name
	~ decltype-specifier
unary-expression:
	postfix-expression
	++ cast-expression
	-- cast-expression
	unary-operator cast-expression
	sizeof unary-expression
	sizeof ( type-id )
	sizeof ... ( identifier )
	alignof ( type-id )
	noexcept-expression
	new-expression
	delete-expression
unary-operator: one of
	*  &  +  -  !  ~
new-expression:
	:: new new-placement new-type-id new-initializer
	:: new new-placement ( type-id ) new-initializer
new-placement:
	( expression-list )
new-type-id:
	type-specifier-seq new-declarator
new-declarator:
	ptr-operator new-declarator
	noptr-new-declarator
noptr-new-declarator:
	[ expression ] attribute-specifier-seq
	noptr-new-declarator [ constant-expression ] attribute-specifier-seq
new-initializer:
	( expression-list )
	braced-init-list
delete-expression:
	:: delete cast-expression
	:: delete [ ] cast-expression
noexcept-expression:
	noexcept ( expression )
cast-expression:
	unary-expression
	( type-id ) cast-expression
pm-expression:
	cast-expression
	pm-expression .* cast-expression
	pm-expression ->* cast-expression
multiplicative-expression:
	pm-expression
	multiplicative-expression * pm-expression
	multiplicative-expression / pm-expression
	multiplicative-expression % pm-expression
additive-expression:
	multiplicative-expression
	additive-expression + multiplicative-expression
	additive-expression - multiplicative-expression
shift-expression:
	additive-expression
	shift-expression << additive-expression
	shift-expression >> additive-expression
relational-expression:
	shift-expression
	relational-expression < shift-expression
	relational-expression > shift-expression
	relational-expression <= shift-expression
	relational-expression >= shift-expression
equality-expression:
	relational-expression
	equality-expression == relational-expression
	equality-expression != relational-expression
and-expression:
	equality-expression
	and-expression & equality-expression
exclusive-or-expression:
	and-expression
	exclusive-or-expression ^ and-expression
inclusive-or-expression:
	exclusive-or-expression
	inclusive-or-expression | exclusive-or-expression
logical-and-expression:
	inclusive-or-expression
	logical-and-expression && inclusive-or-expression
logical-or-expression:
	logical-and-expression
	logical-or-expression || logical-and-expression
conditional-expression:
	logical-or-expression
	logical-or-expression ? expression : assignment-expression
throw-expression:
	throw  assignment-expression
assignment-expression:
	conditional-expression
	logical-or-expression assignment-operator initializer-clause
	throw-expression
assignment-operator: one of
	=  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=
expression:
	assignment-expression
	expression , assignment-expression
constant-expression:
	conditional-expression

A.5 Statements [gram.stmt]

A.6 Declarations [gram.dcl]

declaration-seq:
	declaration
	declaration-seq declaration
declaration:
	block-declaration
	nodeclspec-function-declaration
	function-definition
	template-declaration
	deduction-guide
	explicit-instantiation
	explicit-specialization
	linkage-specification
	namespace-definition
	empty-declaration
	attribute-declaration
block-declaration:
	simple-declaration
	asm-definition
	namespace-alias-definition
	using-declaration
	using-directive
	static_assert-declaration
	alias-declaration
	opaque-enum-declaration
nodeclspec-function-declaration:
	attribute-specifier-seq declarator ;
alias-declaration:
	using identifier attribute-specifier-seq = defining-type-id ;
simple-declaration:
	decl-specifier-seq init-declarator-list ;
	attribute-specifier-seq decl-specifier-seq init-declarator-list ;
	attribute-specifier-seq decl-specifier-seq ref-qualifier [ identifier-list ] initializer ;
static_assert-declaration:
	static_assert ( constant-expression ) ;
	static_assert ( constant-expression , string-literal ) ;
empty-declaration:
	;
attribute-declaration:
	attribute-specifier-seq ;
decl-specifier:
	storage-class-specifier
	defining-type-specifier
	function-specifier
	friend
	typedef
	constexpr
	inline
decl-specifier-seq:
	decl-specifier attribute-specifier-seq
	decl-specifier decl-specifier-seq
storage-class-specifier:
	static
	thread_local
	extern
	mutable
function-specifier:
	virtual
	explicit
typedef-name:
	identifier
type-specifier:
	simple-type-specifier
	elaborated-type-specifier
	typename-specifier
	cv-qualifier
type-specifier-seq:
	type-specifier attribute-specifier-seq
	type-specifier type-specifier-seq
defining-type-specifier:
	type-specifier
	class-specifier
	enum-specifier
defining-type-specifier-seq:
	defining-type-specifier attribute-specifier-seq
	defining-type-specifier defining-type-specifier-seq
simple-type-specifier:
	nested-name-specifier type-name
	nested-name-specifier template simple-template-id
	nested-name-specifier template-name
	char
	char16_t
	char32_t
	wchar_t
	bool
	short
	int
	long
	signed
	unsigned
	float
	double
	void
	auto
	decltype-specifier
type-name:
	class-name
	enum-name
	typedef-name
	simple-template-id
decltype-specifier:
	decltype ( expression )
	decltype ( auto )
elaborated-type-specifier:
	class-key attribute-specifier-seq nested-name-specifier identifier
	class-key simple-template-id
	class-key nested-name-specifier template simple-template-id
	enum nested-name-specifier identifier
enum-name:
	identifier
enum-specifier:
	enum-head { enumerator-list }
	enum-head { enumerator-list , }
enum-head:
	enum-key attribute-specifier-seq enum-head-name enum-base
enum-head-name:
	nested-name-specifier identifier
opaque-enum-declaration:
	enum-key attribute-specifier-seq nested-name-specifier identifier enum-base ;
enum-key:
	enum
	enum class
	enum struct
enum-base:
	: type-specifier-seq
enumerator-list:
	enumerator-definition
	enumerator-list , enumerator-definition
enumerator-definition:
	enumerator
	enumerator = constant-expression
enumerator:
	identifier attribute-specifier-seq
namespace-name:
	identifier
	namespace-alias
namespace-definition:
	named-namespace-definition
	unnamed-namespace-definition
	nested-namespace-definition
named-namespace-definition:
	inline namespace attribute-specifier-seq identifier { namespace-body }
unnamed-namespace-definition:
	inline namespace attribute-specifier-seq { namespace-body }
nested-namespace-definition:
	namespace enclosing-namespace-specifier :: identifier { namespace-body }
enclosing-namespace-specifier:
	identifier
	enclosing-namespace-specifier :: identifier
namespace-body:
	declaration-seq
namespace-alias:
	identifier
namespace-alias-definition:
	namespace identifier = qualified-namespace-specifier ;
qualified-namespace-specifier:
	nested-name-specifier namespace-name
using-declaration:
	using using-declarator-list ;
using-declarator-list:
	using-declarator ...
	using-declarator-list , using-declarator ...
using-declarator:
	typename nested-name-specifier unqualified-id
using-directive:
	attribute-specifier-seq using  namespace nested-name-specifier namespace-name ;
asm-definition:
	attribute-specifier-seq asm ( string-literal ) ;
linkage-specification:
	extern string-literal { declaration-seq }
	extern string-literal declaration
attribute-specifier-seq:
	attribute-specifier-seq attribute-specifier
attribute-specifier:
	[ [ attribute-using-prefix attribute-list ] ]
	alignment-specifier
alignment-specifier:
	alignas ( type-id ... )
	alignas ( constant-expression ... )
attribute-using-prefix:
	using attribute-namespace :
attribute-list:
	attribute
	attribute-list , attribute
	attribute ...
	attribute-list , attribute ...
attribute:
	attribute-token attribute-argument-clause
attribute-token:
	identifier
	attribute-scoped-token
attribute-scoped-token:
	attribute-namespace :: identifier
attribute-namespace:
	identifier
attribute-argument-clause:
	( balanced-token-seq )
balanced-token-seq:
	balanced-token
	balanced-token-seq balanced-token
balanced-token:
	( balanced-token-seq )
	[ balanced-token-seq ]
	{ balanced-token-seq }
	any token other than a parenthesis, a bracket, or a brace

A.7 Declarators [gram.decl]

init-declarator-list:
	init-declarator
	init-declarator-list , init-declarator
init-declarator:
	declarator initializer
declarator:
	ptr-declarator
	noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator:
	noptr-declarator
	ptr-operator ptr-declarator
noptr-declarator:
	declarator-id attribute-specifier-seq
	noptr-declarator parameters-and-qualifiers
	noptr-declarator [ constant-expression ] attribute-specifier-seq
	( ptr-declarator )
parameters-and-qualifiers:
	( parameter-declaration-clause ) cv-qualifier-seq
ref-qualifier noexcept-specifier attribute-specifier-seq
trailing-return-type:
	-> type-id
ptr-operator:
	* attribute-specifier-seq cv-qualifier-seq
	& attribute-specifier-seq
	&& attribute-specifier-seq
	nested-name-specifier * attribute-specifier-seq cv-qualifier-seq
cv-qualifier-seq:
	cv-qualifier cv-qualifier-seq
cv-qualifier:
	const
	volatile
ref-qualifier:
	&
	&&
declarator-id:
	... id-expression
type-id:
	type-specifier-seq abstract-declarator
defining-type-id:
	defining-type-specifier-seq abstract-declarator
abstract-declarator:
	ptr-abstract-declarator
	noptr-abstract-declarator parameters-and-qualifiers trailing-return-type
	abstract-pack-declarator
ptr-abstract-declarator:
	noptr-abstract-declarator
	ptr-operator ptr-abstract-declarator
noptr-abstract-declarator:
	noptr-abstract-declarator parameters-and-qualifiers
	noptr-abstract-declarator [ constant-expression ] attribute-specifier-seq
	( ptr-abstract-declarator )
abstract-pack-declarator:
	noptr-abstract-pack-declarator
	ptr-operator abstract-pack-declarator
noptr-abstract-pack-declarator:
	noptr-abstract-pack-declarator parameters-and-qualifiers
	noptr-abstract-pack-declarator [ constant-expression ] attribute-specifier-seq
	...
parameter-declaration-clause:
	parameter-declaration-list ...
	parameter-declaration-list , ...
parameter-declaration-list:
	parameter-declaration
	parameter-declaration-list , parameter-declaration
parameter-declaration:
	attribute-specifier-seq decl-specifier-seq declarator
	attribute-specifier-seq decl-specifier-seq declarator = initializer-clause
	attribute-specifier-seq decl-specifier-seq abstract-declarator
	attribute-specifier-seq decl-specifier-seq abstract-declarator = initializer-clause
function-definition:
	attribute-specifier-seq decl-specifier-seq declarator virt-specifier-seq function-body
function-body:
	ctor-initializer compound-statement
	function-try-block
	= default ;
	= delete ;
initializer:
	brace-or-equal-initializer
	( expression-list )
brace-or-equal-initializer:
	= initializer-clause
	braced-init-list
initializer-clause:
	assignment-expression
	braced-init-list
initializer-list:
	initializer-clause ...
	initializer-list , initializer-clause ...
braced-init-list:
	{ initializer-list , }
	{ }
expr-or-braced-init-list:
	expression
	braced-init-list

A.11 Overloading [gram.over]

operator-function-id:
	operator operator
operator: one of
	new	delete	new[]	delete[]
	+	-	*	/	%	^	&	|	~
	!	=	<	>	+=	-=	*=	/=	%=
	^=	&=	|=	<<	>>	>>=	<<=	==	!=
	<=	>=	&&	||	++	--	,	->*	->
	()	[]
literal-operator-id:
	operator string-literal identifier
	operator user-defined-string-literal

A.14 Preprocessing directives [gram.cpp]

preprocessing-file:
	group
group:
	group-part
	group group-part
group-part:
	control-line
	if-section
	text-line
	# conditionally-supported-directive
control-line:
	# include		pp-tokens new-line
	# define		identifier replacement-list new-line
	# define		identifier lparen identifier-list ) replacement-list new-line
	# define		identifier lparen ... ) replacement-list new-line
	# define		identifier lparen identifier-list , ... ) replacement-list new-line
	# undef		identifier new-line
	# line		pp-tokens new-line
	# error		pp-tokens new-line
	# pragma		pp-tokens new-line
	# new-line
if-section:
	if-group elif-groups else-group endif-line
if-group:
	# if		constant-expression new-line group
	# ifdef		identifier new-line group
	# ifndef		identifier new-line group
elif-groups:
	elif-group
	elif-groups elif-group
elif-group:
	# elif		constant-expression new-line group
else-group:
	# else		new-line group
endif-line:
	# endif		new-line
text-line:
	pp-tokens new-line
conditionally-supported-directive:
	pp-tokens new-line
lparen:
	a ( character not immediately preceded by white-space
identifier-list:
	identifier
	identifier-list , identifier
replacement-list:
	pp-tokens
pp-tokens:
	preprocessing-token
	pp-tokens preprocessing-token
new-line:
	the new-line character
defined-macro-expression:
	defined identifier
	defined ( identifier )
h-preprocessing-token:
	any preprocessing-token other than >
h-pp-tokens:
	h-preprocessing-token
	h-pp-tokens h-preprocessing-token
has-include-expression:
	__has_­include ( < h-char-sequence > )
	__has_­include ( " q-char-sequence " )
	__has_­include (   string-literal  )
	__has_­include ( < h-pp-tokens     > )

Annex B (informative) Implementation quantities [implimits]

Because computers are finite, C++ implementations are inevitably limited in the size of the programs they can successfully process.
Every implementation shall document those limitations where known.
This documentation may cite fixed limits where they exist, say how to compute variable limits as a function of available resources, or say that fixed limits do not exist or are unknown.
The limits may constrain quantities that include those described below or others.
The bracketed number following each quantity is recommended as the minimum for that quantity.
However, these quantities are only guidelines and do not determine compliance.
  • Nesting levels of compound statements, iteration control structures, and selection control structures [256].
  • Nesting levels of conditional inclusion [256].
  • Pointer, array, and function declarators (in any combination) modifying a class, arithmetic, or incomplete type in a declaration [256].
  • Nesting levels of parenthesized expressions within a full-expression [256].
  • Number of characters in an internal identifier or macro name [1024].
  • Number of characters in an external identifier [1024].
  • External identifiers in one translation unit [65536].
  • Identifiers with block scope declared in one block [1024].
  • Structured bindings introduced in one declaration [256].
  • Macro identifiers simultaneously defined in one translation unit [65536].
  • Parameters in one function definition [256].
  • Arguments in one function call [256].
  • Parameters in one macro definition [256].
  • Arguments in one macro invocation [256].
  • Characters in one logical source line [65536].
  • Characters in a string literal (after concatenation) [65536].
  • Size of an object [262144].
  • Nesting levels for #include files [256].
  • Case labels for a switch statement (excluding those for any nested switch statements) [16384].
  • Data members in a single class [16384].
  • Lambda-captures in one lambda-expression [256].
  • Enumeration constants in a single enumeration [4096].
  • Levels of nested class definitions in a single member-specification [256].
  • Functions registered by atexit() [32].
  • Functions registered by at_­quick_­exit() [32].
  • Direct and indirect base classes [16384].
  • Direct base classes for a single class [1024].
  • Members declared in a single class [4096].
  • Final overriding virtual functions in a class, accessible or not [16384].
  • Direct and indirect virtual bases of a class [1024].
  • Static members of a class [1024].
  • Friend declarations in a class [4096].
  • Access control declarations in a class [4096].
  • Member initializers in a constructor definition [6144].
  • Scope qualifications of one identifier [256].
  • Nested external specifications [1024].
  • Recursive constexpr function invocations [512].
  • Full-expressions evaluated within a core constant expression [1048576].
  • Template arguments in a template declaration [1024].
  • Recursively nested template instantiations, including substitution during template argument deduction ([temp.deduct]) [1024].
  • Handlers per try block [256].
  • Number of placeholders ([func.bind.place]) [10].

Annex C (informative) Compatibility [diff]

C.1 C++ and ISO C [diff.iso]

This subclause lists the differences between C++ and ISO C, by the chapters of this document.

C.1.1 Clause [lex]: lexical conventions [diff.lex]

[lex.key]
Change: New Keywords
New keywords are added to C++; see [lex.key].

Rationale: These keywords were added in order to implement the new semantics of C++.

Effect on original feature: Change to semantics of well-defined feature.
Any ISO C programs that used any of these keywords as identifiers are not valid C++ programs.

Difficulty of converting: Syntactic transformation.
Converting one specific program is easy.
Converting a large collection of related programs takes more work.

How widely used: Common.
[lex.ccon]
Change: Type of character literal is changed from int to char.

Rationale: This is needed for improved overloaded function argument type matching.
For example:
int function( int i );
int function( char c );

function( 'x' );
It is preferable that this call match the second version of function rather than the first.

Effect on original feature: Change to semantics of well-defined feature.
ISO C programs which depend on
sizeof('x') == sizeof(int)
will not work the same as C++ programs.

Difficulty of converting: Simple.

How widely used: Programs which depend upon sizeof('x') are probably rare.
Subclause [lex.string]:
Change: String literals made const.

The type of a string literal is changed from “array of char” to “array of const char.
The type of a char16_­t string literal is changed from “array of some-integer-type” to “array of const char16_­t.
The type of a char32_­t string literal is changed from “array of some-integer-type” to “array of const char32_­t.
The type of a wide string literal is changed from “array of wchar_­t” to “array of const wchar_­t.

Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Syntactic transformation.
The fix is to add a cast:
char* p = "abc";                // valid in C, invalid in C++
void f(char*) {
  char* p = (char*)"abc";       // OK: cast added
  f(p);
  f((char*)"def");              // OK: cast added
}

How widely used: Programs that have a legitimate reason to treat string literals as pointers to potentially modifiable memory are probably rare.

C.1.2 Clause [basic]: basic concepts [diff.basic]

[basic.def]
Change: C++ does not have “tentative definitions” as in C.

E.
g.
, at file scope,
int i;
int i;
is valid in C, invalid in C++.
This makes it impossible to define mutually referential file-local static objects, if initializers are restricted to the syntactic forms of C.
For example,
struct X { int i; struct X* next; };

static struct X a;
static struct X b = { 0, &a };
static struct X a = { 1, &b };

Rationale: This avoids having different initialization rules for fundamental types and user-defined types.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
In C++, the initializer for one of a set of mutually-referential file-local static objects must invoke a function call to achieve the initialization.

How widely used: Seldom.
[basic.scope]
Change: A struct is a scope in C++, not in C.

Rationale: Class scope is crucial to C++, and a struct is a class.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Semantic transformation.

How widely used: C programs use struct extremely frequently, but the change is only noticeable when struct, enumeration, or enumerator names are referred to outside the struct.
The latter is probably rare.
[basic.link] [also [dcl.type]]
Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage.

Rationale: Because const objects may be used as values during translation in C++, this feature urges programmers to provide an explicit initializer for each const object.
This feature allows the user to put const objects in source files that are included in more than one translation unit.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Semantic transformation.

How widely used: Seldom.
[basic.start.main]
Change: The main function cannot be called recursively and cannot have its address taken.

Rationale: The main function may require special actions.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Trivial: create an intermediary function such as mymain(argc, argv).

How widely used: Seldom.
[basic.types]
Change: C allows “compatible types” in several places, C++ does not.

For example, otherwise-identical struct types with different tag names are “compatible” in C but are distinctly different types in C++.

Rationale: Stricter type checking is essential for C++.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
The “typesafe linkage” mechanism will find many, but not all, of such problems.
Those problems not found by typesafe linkage will continue to function properly, according to the “layout compatibility rules” of this International Standard.

How widely used: Common.

C.1.3 Clause [conv]: standard conversions [diff.conv]

[conv.ptr]
Change: Converting void* to a pointer-to-object type requires casting.
char a[10];
void* b=a;
void foo() {
  char* c=b;
}
ISO C will accept this usage of pointer to void being assigned to a pointer to object type.
C++ will not.

Rationale: C++ tries harder than C to enforce compile-time type safety.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Could be automated.
Violations will be diagnosed by the C++ translator.
The fix is to add a cast.
For example:
char* c = (char*) b;

How widely used: This is fairly widely used but it is good programming practice to add the cast when assigning pointer-to-void to pointer-to-object.
Some ISO C translators will give a warning if the cast is not used.

C.1.4 Clause [expr]: expressions [diff.expr]

[expr.call]
Change: Implicit declaration of functions is not allowed.

Rationale: The type-safe nature of C++.

Effect on original feature: Deletion of semantically well-defined feature.
Note: the original feature was labeled as “obsolescent” in ISO C.

Difficulty of converting: Syntactic transformation.
Facilities for producing explicit function declarations are fairly widespread commercially.

How widely used: Common.
[expr.post.incr], [expr.pre.incr]
Change: Decrement operator is not allowed with bool operand.

Rationale: Feature with surprising semantics.

Effect on original feature: A valid ISO C expression utilizing the decrement operator on a bool lvalue (for instance, via the C typedef in <stdbool.h>) is ill-formed in this International Standard.
[expr.sizeof], [expr.cast]
Change: Types must be defined in declarations, not in expressions.

In C, a sizeof expression or cast expression may define a new type.
For example,
p = (void*)(struct x {int i;} *)0;
defines a new type, struct x.

Rationale: This prohibition helps to clarify the location of definitions in the source code.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.

How widely used: Seldom.
[expr.cond], [expr.ass], [expr.comma]
Change: The result of a conditional expression, an assignment expression, or a comma expression may be an lvalue.

Rationale: C++ is an object-oriented language, placing relatively more emphasis on lvalues.
For example, functions may return lvalues.

Effect on original feature: Change to semantics of well-defined feature.
Some C expressions that implicitly rely on lvalue-to-rvalue conversions will yield different results.
For example,
char arr[100];
sizeof(0, arr)
yields 100 in C++ and sizeof(char*) in C.

Difficulty of converting: Programs must add explicit casts to the appropriate rvalue.

How widely used: Rare.

C.1.5 Clause [stmt.stmt]: statements [diff.stat]

[stmt.switch], [stmt.goto]
Change: It is now invalid to jump past a declaration with explicit or implicit initializer (except across entire block not entered).

Rationale: Constructors used in initializers may allocate resources which need to be de-allocated upon leaving the block.
Allowing jump past initializers would require complicated runtime determination of allocation.
Furthermore, any use of the uninitialized object could be a disaster.
With this simple compile-time rule, C++ assures that if an initialized variable is in scope, then it has assuredly been initialized.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.

How widely used: Seldom.
[stmt.return]
Change: It is now invalid to return (explicitly or implicitly) from a function which is declared to return a value without actually returning a value.

Rationale: The caller and callee may assume fairly elaborate return-value mechanisms for the return of class objects.
If some flow paths execute a return without specifying any value, the implementation must embody many more complications.
Besides, promising to return a value of a given type, and then not returning such a value, has always been recognized to be a questionable practice, tolerated only because very-old C had no distinction between void functions and int functions.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
Add an appropriate return value to the source code, such as zero.

How widely used: Seldom.
For several years, many existing C implementations have produced warnings in this case.

C.1.6 Clause [dcl.dcl]: declarations [diff.dcl]

[dcl.stc]
Change: In C++, the static or extern specifiers can only be applied to names of objects or functions.

Using these specifiers with type declarations is illegal in C++.
In C, these specifiers are ignored when used on type declarations.
Example:
static struct S {               // valid C, invalid in C++
  int i;
};

Rationale: Storage class specifiers don't have any meaning when associated with a type.
In C++, class members can be declared with the static storage class specifier.
Allowing storage class specifiers on type declarations could render the code confusing for users.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.

How widely used: Seldom.
[dcl.stc]
Change: In C++, register is not a storage class specifier.

Rationale: The storage class specifier had no effect in C++.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.

How widely used: Common.
[dcl.typedef]
Change: A C++ typedef name must be different from any class type name declared in the same scope (except if the typedef is a synonym of the class name with the same name).
In C, a typedef name and a struct tag name declared in the same scope can have the same name (because they have different name spaces).
Example:
typedef struct name1 { /* ... */ } name1;         // valid C and C++
struct name { /* ... */ };
typedef int name;               // valid C, invalid C++

Rationale: For ease of use, C++ doesn't require that a type name be prefixed with the keywords class, struct or union when used in object declarations or type casts.
Example:
class name { /* ... */ };
name i;                         // i has type class name

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
One of the 2 types has to be renamed.

How widely used: Seldom.
[dcl.type] [see also [basic.link]]
Change: const objects must be initialized in C++ but can be left uninitialized in C.

Rationale: A const object cannot be assigned to so it must be initialized to hold a useful value.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.

How widely used: Seldom.
[dcl.type]
Change: Banning implicit int.
In C++ a decl-specifier-seq must contain a type-specifier, unless it is followed by a declarator for a constructor, a destructor, or a conversion function.
In the following example, the left-hand column presents valid C; the right-hand column presents equivalent C++:
void f(const parm);            void f(const int parm);
const n = 3;                   const int n = 3;
main()                         int main()
    /* ... */                      /* ... */

Rationale: In C++, implicit int creates several opportunities for ambiguity between expressions involving function-like casts and declarations.
Explicit declaration is increasingly considered to be proper style.
Liaison with WG14 (C) indicated support for (at least) deprecating implicit int in the next revision of C.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.
Could be automated.

How widely used: Common.
[dcl.spec.auto]
Change: The keyword auto cannot be used as a storage class specifier.
void f() {
  auto int x;     // valid C, invalid C++
}

Rationale: Allowing the use of auto to deduce the type of a variable from its initializer results in undesired interpretations of auto as a storage class specifier in certain contexts.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.

How widely used: Rare.
[dcl.enum]
Change: C++ objects of enumeration type can only be assigned values of the same enumeration type.
In C, objects of enumeration type can be assigned values of any integral type.
Example:
enum color { red, blue, green };
enum color c = 1;               // valid C, invalid C++

Rationale: The type-safe nature of C++.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.
(The type error produced by the assignment can be automatically corrected by applying an explicit cast.)

How widely used: Common.
[dcl.enum]
Change: In C++, the type of an enumerator is its enumeration.
In C, the type of an enumerator is int.
Example:
enum e { A };
sizeof(A) == sizeof(int)        // in C
sizeof(A) == sizeof(e)          // in C++
/* and sizeof(int) is not necessarily equal to sizeof(e) */

Rationale: In C++, an enumeration is a distinct type.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Semantic transformation.

How widely used: Seldom.
The only time this affects existing C code is when the size of an enumerator is taken.
Taking the size of an enumerator is not a common C coding practice.

C.1.7 Clause [dcl.decl]: declarators [diff.decl]

[dcl.fct]
Change: In C++, a function declared with an empty parameter list takes no arguments.
In C, an empty parameter list means that the number and type of the function arguments are unknown.
Example:
int f();            // means   int f(void) in C++
                    // int f( unknown ) in C

Rationale: This is to avoid erroneous function calls (i.e., function calls with the wrong number or type of arguments).
Effect on original feature: Change to semantics of well-defined feature.
This feature was marked as “obsolescent” in C.

Difficulty of converting: Syntactic transformation.
The function declarations using C incomplete declaration style must be completed to become full prototype declarations.
A program may need to be updated further if different calls to the same (non-prototype) function have different numbers of arguments or if the type of corresponding arguments differed.

How widely used: Common.
[dcl.fct] [see [expr.sizeof]]
Change: In C++, types may not be defined in return or parameter types.
In C, these type definitions are allowed.
Example:
void f( struct S { int a; } arg ) {}    // valid C, invalid C++
enum E { A, B, C } f() {}               // valid C, invalid C++

Rationale: When comparing types in different translation units, C++ relies on name equivalence when C relies on structural equivalence.
Regarding parameter types: since the type defined in a parameter list would be in the scope of the function, the only legal calls in C++ would be from within the function itself.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
The type definitions must be moved to file scope, or in header files.

How widely used: Seldom.
This style of type definition is seen as poor coding style.
[dcl.fct.def]
Change: In C++, the syntax for function definition excludes the “old-style” C function.
In C, “old-style” syntax is allowed, but deprecated as “obsolescent”.

Rationale: Prototypes are essential to type safety.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Syntactic transformation.

How widely used: Common in old programs, but already known to be obsolescent.
[dcl.init.string]
Change: In C++, when initializing an array of character with a string, the number of characters in the string (including the terminating '\0') must not exceed the number of elements in the array.
In C, an array can be initialized with a string even if the array is not large enough to contain the string-terminating '\0'.
Example:
char array[4] = "abcd";         // valid C, invalid C++

Rationale: When these non-terminated arrays are manipulated by standard string functions, there is potential for major catastrophe.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
The arrays must be declared one element bigger to contain the string terminating '\0'.

How widely used: Seldom.
This style of array initialization is seen as poor coding style.

C.1.8 Clause [class]: classes [diff.class]

[class.name] [see also [dcl.typedef]]
Change: In C++, a class declaration introduces the class name into the scope where it is declared and hides any object, function or other declaration of that name in an enclosing scope.
In C, an inner scope declaration of a struct tag name never hides the name of an object or function in an outer scope.
Example:
int x[99];
void f() {
  struct x { int a; };
  sizeof(x);  /* size of the array in C */
  /* size of the struct in C++ */
}

Rationale: This is one of the few incompatibilities between C and C++ that can be attributed to the new C++ name space definition where a name can be declared as a type and as a non-type in a single scope causing the non-type name to hide the type name and requiring that the keywords class, struct, union or enum be used to refer to the type name.
This new name space definition provides important notational conveniences to C++ programmers and helps making the use of the user-defined types as similar as possible to the use of fundamental types.
The advantages of the new name space definition were judged to outweigh by far the incompatibility with C described above.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Semantic transformation.
If the hidden name that needs to be accessed is at global scope, the ​::​ C++ operator can be used.
If the hidden name is at block scope, either the type or the struct tag has to be renamed.

How widely used: Seldom.
[class.bit]
Change: Bit-fields of type plain int are signed.

Rationale: Leaving the choice of signedness to implementations could lead to inconsistent definitions of template specializations.
For consistency, the implementation freedom was eliminated for non-dependent types, too.

Effect on original feature: The choice is implementation-defined in C, but not so in C++.

Difficulty of converting: Syntactic transformation.

How widely used: Seldom.
[class.nest]
Change: In C++, the name of a nested class is local to its enclosing class.
In C the name of the nested class belongs to the same scope as the name of the outermost enclosing class.
Example:
struct X {
  struct Y { /* ... */ } y;
};
struct Y yy;                    // valid C, invalid C++

Rationale: C++ classes have member functions which require that classes establish scopes.
The C rule would leave classes as an incomplete scope mechanism which would prevent C++ programmers from maintaining locality within a class.
A coherent set of scope rules for C++ based on the C rule would be very complicated and C++ programmers would be unable to predict reliably the meanings of nontrivial examples involving nested or local functions.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Semantic transformation.
To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined.
Example:
struct Y;                       // struct Y and struct X are at the same scope
struct X {
  struct Y { /* ... */ } y;
};
All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of the enclosing struct could be exported to the scope of the enclosing struct.
Note: this is a consequence of the difference in scope rules, which is documented in [basic.scope].

How widely used: Seldom.
[class.nested.type]
Change: In C++, a typedef name may not be redeclared in a class definition after being used in that definition.
Example:
typedef int I;
struct S {
  I i;
  int I;                  // valid C, invalid C++
};

Rationale: When classes become complicated, allowing such a redefinition after the type has been used can create confusion for C++ programmers as to what the meaning of I really is.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
Either the type or the struct member has to be renamed.

How widely used: Seldom.

C.1.9 Clause [special]: special member functions [diff.special]

[class.copy]
Change: Copying volatile objects.
The implicitly-declared copy constructor and implicitly-declared copy assignment operator cannot make a copy of a volatile lvalue.
For example, the following is valid in ISO C:
struct X { int i; };
volatile struct X x1 = {0};
struct X x2 = x1;               // invalid C++
struct X x3;
x3 = x1;                        // also invalid C++

Rationale: Several alternatives were debated at length.
Changing the parameter to volatile const X& would greatly complicate the generation of efficient code for class objects.
Discussion of providing two alternative signatures for these implicitly-defined operations raised unanswered concerns about creating ambiguities and complicating the rules that specify the formation of these operators according to the bases and members.

Effect on original feature: Deletion of semantically well-defined feature.

Difficulty of converting: Semantic transformation.
If volatile semantics are required for the copy, a user-declared constructor or assignment must be provided.
If non-volatile semantics are required, an explicit const_­cast can be used.

How widely used: Seldom.

C.1.10 Clause [cpp]: preprocessing directives [diff.cpp]

[cpp.predefined]
Change: Whether __STDC__ is defined and if so, what its value is, are implementation-defined.

Rationale: C++ is not identical to ISO C.
Mandating that __STDC__ be defined would require that translators make an incorrect claim.
Each implementation must choose the behavior that will be most useful to its marketplace.

Effect on original feature: Change to semantics of well-defined feature.

Difficulty of converting: Semantic transformation.

How widely used: Programs and headers that reference __STDC__ are quite common.

C.2 C++ and ISO C++ 2003 [diff.cpp03]

This subclause lists the differences between C++ and ISO C++ 2003 (ISO/IEC 14882:2003, Programming Languages — C++), by the chapters of this document.

C.2.1 Clause [lex]: lexical conventions [diff.cpp03.lex]

[lex.pptoken]
Change: New kinds of string literals.

Rationale: Required for new features.

Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard.
Specifically, macros named R, u8, u8R, u, uR, U, UR, or LR will not be expanded when adjacent to a string literal but will be interpreted as part of the string literal.
For example,
#define u8 "abc"
const char* s = u8"def";        // Previously "abcdef", now "def"
[lex.pptoken]
Change: User-defined literal string support.

Rationale: Required for new features.

Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard, as the following example illustrates.
#define _x "there"
"hello"_x         // #1
Previously, #1 would have consisted of two separate preprocessing tokens and the macro _­x would have been expanded.
In this International Standard, #1 consists of a single preprocessing token, so the macro is not expanded.
[lex.key]
Change: New keywords.

Rationale: Required for new features.

Effect on original feature: Added to Table 5, the following identifiers are new keywords: alignas, alignof, char16_­t, char32_­t, constexpr, decltype, noexcept, nullptr, static_­assert, and thread_­local.
Valid C++ 2003 code using these identifiers is invalid in this International Standard.
[lex.icon]
Change: Type of integer literals.

Rationale: C99 compatibility.

Effect on original feature: Certain integer literals larger than can be represented by long could change from an unsigned integer type to signed long long.

C.2.2 Clause [conv]: standard conversions [diff.cpp03.conv]

[conv.ptr]
Change: Only literals are integer null pointer constants.

Rationale: Removing surprising interactions with templates and constant expressions.

Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard, as the following example illustrates:
void f(void *);  // #1
void f(...);     // #2
template<int N> void g() {
  f(0*N);        // calls #2; used to call #1
}

C.2.3 Clause [expr]: expressions [diff.cpp03.expr]

[expr.mul]
Change: Specify rounding for results of integer / and %.

Rationale: Increase portability, C99 compatibility.

Effect on original feature: Valid C++ 2003 code that uses integer division rounds the result toward 0 or toward negative infinity, whereas this International Standard always rounds the result toward 0.
[expr.log.and]
Change:&& is valid in a type-name.

Rationale: Required for new features.

Effect on original feature: Valid C++ 2003 code may fail to compile or produce different results in this International Standard, as the following example illustrates:
bool b1 = new int && false;           // previously false, now ill-formed
struct S { operator int(); };
bool b2 = &S::operator int && false;  // previously false, now ill-formed

C.2.4 Clause [dcl.dcl]: declarations [diff.cpp03.dcl.dcl]

[dcl.spec]
Change: Remove auto as a storage class specifier.

Rationale: New feature.

Effect on original feature: Valid C++ 2003 code that uses the keyword auto as a storage class specifier may be invalid in this International Standard.
In this International Standard, auto indicates that the type of a variable is to be deduced from its initializer expression.

C.2.5 Clause [dcl.decl]: declarators [diff.cpp03.dcl.decl]

[dcl.init.list]
Change: Narrowing restrictions in aggregate initializers.

Rationale: Catches bugs.

Effect on original feature: Valid C++ 2003 code may fail to compile in this International Standard.
For example, the following code is valid in C++ 2003 but invalid in this International Standard because double to int is a narrowing conversion:
int x[] = { 2.0 };

C.2.6 Clause [special]: special member functions [diff.cpp03.special]

[class.ctor], [class.dtor], [class.copy]
Change: Implicitly-declared special member functions are defined as deleted when the implicit definition would have been ill-formed.

Rationale: Improves template argument deduction failure.

Effect on original feature: A valid C++ 2003 program that uses one of these special member functions in a context where the definition is not required (e.g., in an expression that is not potentially evaluated) becomes ill-formed.
[class.dtor] (destructors)
Change: User-declared destructors have an implicit exception specification.

Rationale: Clarification of destructor requirements.

Effect on original feature: Valid C++ 2003 code may execute differently in this International Standard.
In particular, destructors that throw exceptions will call std​::​terminate (without calling std​::​unexpected) if their exception specification is non-throwing.

C.2.7 Clause [temp]: templates [diff.cpp03.temp]

[temp.param]
Change: Remove export.

Rationale: No implementation consensus.

Effect on original feature: A valid C++ 2003 declaration containing export is ill-formed in this International Standard.
[temp.arg]
Change: Remove whitespace requirement for nested closing template right angle brackets.

Rationale: Considered a persistent but minor annoyance.
Template aliases representing non-class types would exacerbate whitespace issues.

Effect on original feature: Change to semantics of well-defined expression.
A valid C++ 2003 expression containing a right angle bracket (“>”) followed immediately by another right angle bracket may now be treated as closing two templates.
For example, the following code is valid in C++ 2003 because “>>” is a right-shift operator, but invalid in this International Standard because “>>” closes two templates.
template <class T> struct X { };
template <int N> struct Y { };
X< Y< 1 >> 2 > > x;
[temp.dep.candidate]
Change: Allow dependent calls of functions with internal linkage.

Rationale: Overly constrained, simplify overload resolution rules.

Effect on original feature: A valid C++ 2003 program could get a different result than this International Standard.

C.2.8 Clause [library]: library introduction [diff.cpp03.library]

[library][thread]
Change: New reserved identifiers.

Rationale: Required by new features.

Effect on original feature: Valid C++ 2003 code that uses any identifiers added to the C++ standard library by this International Standard may fail to compile or produce different results in this International Standard.
A comprehensive list of identifiers used by the C++ standard library can be found in the Index of Library Names in this International Standard.
[headers]
Change: New headers.

Rationale: New functionality.

Effect on original feature: The following C++ headers are new: <array>, <atomic>, <chrono>, <codecvt>, <condition_­variable>, <forward_­list>, <future>, <initializer_­list>, <mutex>, <random>, <ratio>, <regex>, <scoped_­allocator>, <system_­error>, <thread>, <tuple>, <typeindex>, <type_­traits>,
<unordered_­map>, and <unordered_­set>.
In addition the following C compatibility headers are new: <ccomplex>, <cfenv>, <cinttypes>, <cstdalign>, <cstdbool>, <cstdint>, <ctgmath>, and <cuchar>.
Valid C++ 2003 code that #includes headers with these names may be invalid in this International Standard.
[swappable.requirements]
Effect on original feature: Function swap moved to a different header
Rationale: Remove dependency on <algorithm> for swap.

Effect on original feature: Valid C++ 2003 code that has been compiled expecting swap to be in <algorithm> may have to instead include <utility>.
[namespace.posix]
Change: New reserved namespace.

Rationale: New functionality.

Effect on original feature: The global namespace posix is now reserved for standardization.
Valid C++ 2003 code that uses a top-level namespace posix may be invalid in this International Standard.
[res.on.macro.definitions]
Change: Additional restrictions on macro names.

Rationale: Avoid hard to diagnose or non-portable constructs.

Effect on original feature: Names of attribute identifiers may not be used as macro names.
Valid C++ 2003 code that defines override, final, carries_­dependency, or noreturn as macros is invalid in this International Standard.

C.2.9 Clause [language.support]: language support library [diff.cpp03.language.support]

[new.delete.single]
Change: Linking new and delete operators.

Rationale: The two throwing single-object signatures of operator new and operator delete are now specified to form the base functionality for the other operators.
This clarifies that replacing just these two signatures changes others, even if they are not explicitly changed.

Effect on original feature: Valid C++ 2003 code that replaces global new or delete operators may execute differently in this International Standard.
For example, the following program should write "custom deallocation" twice, once for the single-object delete and once for the array delete.
#include <cstdio>
#include <cstdlib>
#include <new>

void* operator new(std::size_t size) throw(std::bad_alloc) {
  return std::malloc(size);
}

void operator delete(void* ptr) throw() {
  std::puts("custom deallocation");
  std::free(ptr);
}

int main() {
  int* i = new int;
  delete i;                     // single-object delete
  int* a = new int[3];
  delete [] a;                  // array delete
}
[new.delete.single]
Change: operator new may throw exceptions other than std​::​bad_­alloc.

Rationale: Consistent application of noexcept.

Effect on original feature: Valid C++ 2003 code that assumes that global operator new only throws std​::​bad_­alloc may execute differently in this International Standard.

C.2.10 Clause [diagnostics]: diagnostics library [diff.cpp03.diagnostics]

[errno]
Change: Thread-local error numbers.

Rationale: Support for new thread facilities.

Effect on original feature: Valid but implementation-specific C++ 2003 code that relies on errno being the same across threads may change behavior in this International Standard.

C.2.11 Clause [utilities]: general utilities library [diff.cpp03.utilities]

[util.dynamic.safety]
Change: Minimal support for garbage-collected regions.

Rationale: Required by new feature.

Effect on original feature: Valid C++ 2003 code, compiled without traceable pointer support, that interacts with newer C++ code using regions declared reachable may have different runtime behavior.
[refwrap], [arithmetic.operations], [comparisons], [logical.operations], [bitwise.operations], [depr.negators]
Change: Standard function object types no longer derived from std​::​unary_­function or std​::​binary_­function.

Rationale: Superseded by new feature; unary_­function and binary_­function are no longer defined.

Effect on original feature: Valid C++ 2003 code that depends on function object types being derived from unary_­function or binary_­function may fail to compile in this International Standard.

C.2.12 Clause [strings]: strings library [diff.cpp03.strings]

[string.classes]
Change: basic_­string requirements no longer allow reference-counted strings.

Rationale: Invalidation is subtly different with reference-counted strings.
This change regularizes behavior for this International Standard.

Effect on original feature: Valid C++ 2003 code may execute differently in this International Standard.
[string.require]
Change: Loosen basic_­string invalidation rules.

Rationale: Allow small-string optimization.

Effect on original feature: Valid C++ 2003 code may execute differently in this International Standard.
Some const member functions, such as data and c_­str, no longer invalidate iterators.

C.2.13 Clause [containers]: containers library [diff.cpp03.containers]

[container.requirements]
Change: Complexity of size() member functions now constant.

Rationale: Lack of specification of complexity of size() resulted in divergent implementations with inconsistent performance characteristics.

Effect on original feature: Some container implementations that conform to C++ 2003 may not conform to the specified size() requirements in this International Standard.
Adjusting containers such as std​::​list to the stricter requirements may require incompatible changes.
[container.requirements]
Change: Requirements change: relaxation.

Rationale: Clarification.

Effect on original feature: Valid C++ 2003 code that attempts to meet the specified container requirements may now be over-specified.
Code that attempted to be portable across containers may need to be adjusted as follows:
  • not all containers provide size(); use empty() instead of size() == 0;
  • not all containers are empty after construction (array);
  • not all containers have constant complexity for swap() (array).
[container.requirements]
Change: Requirements change: default constructible.

Rationale: Clarification of container requirements.

Effect on original feature: Valid C++ 2003 code that attempts to explicitly instantiate a container using a user-defined type with no default constructor may fail to compile.
[sequence.reqmts], [associative.reqmts]
Change: Signature changes: from void return types.

Rationale: Old signature threw away useful information that may be expensive to recalculate.

Effect on original feature: The following member functions have changed:
  • erase(iter) for set, multiset, map, multimap
  • erase(begin, end) for set, multiset, map, multimap
  • insert(pos, num, val) for vector, deque, list, forward_­list
  • insert(pos, beg, end) for vector, deque, list, forward_­list
Valid C++ 2003 code that relies on these functions returning void (e.g., code that creates a pointer to member function that points to one of these functions) will fail to compile with this International Standard.
[sequence.reqmts], [associative.reqmts]
Change: Signature changes: from iterator to const_­iterator parameters.

Rationale: Overspecification.

Effect on original feature: The signatures of the following member functions changed from taking an iterator to taking a const_­iterator:
  • insert(iter, val) for vector, deque, list, set, multiset, map, multimap
  • insert(pos, beg, end) for vector, deque, list, forward_­list
  • erase(begin, end) for set, multiset, map, multimap
  • all forms of list​::​splice
  • all forms of list​::​merge
Valid C++ 2003 code that uses these functions may fail to compile with this International Standard.
[sequence.reqmts], [associative.reqmts]
Change: Signature changes: resize.

Rationale: Performance, compatibility with move semantics.

Effect on original feature: For vector, deque, and list the fill value passed to resize is now passed by reference instead of by value, and an additional overload of resize has been added.
Valid C++ 2003 code that uses this function may fail to compile with this International Standard.

C.2.14 Clause [algorithms]: algorithms library [diff.cpp03.algorithms]

[algorithms.general]
Change: Result state of inputs after application of some algorithms.

Rationale: Required by new feature.

Effect on original feature: A valid C++ 2003 program may detect that an object with a valid but unspecified state has a different valid but unspecified state with this International Standard.
For example, std​::​remove and std​::​remove_­if may leave the tail of the input sequence with a different set of values than previously.

C.2.15 Clause [numerics]: numerics library [diff.cpp03.numerics]

[complex.numbers]
Change: Specified representation of complex numbers.

Rationale: Compatibility with C99.

Effect on original feature: Valid C++ 2003 code that uses implementation-specific knowledge about the binary representation of the required template specializations of std​::​complex may not be compatible with this International Standard.

C.2.16 Clause [input.output]: input/output library [diff.cpp03.input.output]

[istream::sentry], [ostream::sentry], [iostate.flags]
Change: Specify use of explicit in existing boolean conversion functions.

Rationale: Clarify intentions, avoid workarounds.

Effect on original feature: Valid C++ 2003 code that relies on implicit boolean conversions will fail to compile with this International Standard.
Such conversions occur in the following conditions:
  • passing a value to a function that takes an argument of type bool;
  • using operator== to compare to false or true;
  • returning a value from a function with a return type of bool;
  • initializing members of type bool via aggregate initialization;
  • initializing a const bool& which would bind to a temporary.
[ios::failure]
Change: Change base class of std​::​ios_­base​::​failure.

Rationale: More detailed error messages.

Effect on original feature: std​::​ios_­base​::​failure is no longer derived directly from std​::​exception, but is now derived from std​::​system_­error, which in turn is derived from std​::​runtime_­error.
Valid C++ 2003 code that assumes that std​::​ios_­base​::​failure is derived directly from std​::​exception may execute differently in this International Standard.
[ios.base]
Change: Flag types in std​::​ios_­base are now bitmasks with values defined as constexpr static members.

Rationale: Required for new features.

Effect on original feature: Valid C++ 2003 code that relies on std​::​ios_­base flag types being represented as std​::​bitset or as an integer type may fail to compile with this International Standard.
For example:
#include <iostream>

int main() {
  int flag = std::ios_base::hex;
  std::cout.setf(flag);         // error: setf does not take argument of type int
}

C.3 C++ and ISO C++ 2011 [diff.cpp11]

This subclause lists the differences between C++ and ISO C++ 2011 (ISO/IEC 14882:2011, Programming Languages — C++), by the chapters of this document.

C.3.1 Clause [lex]: lexical conventions [diff.cpp11.lex]

[lex.ppnumber]
Change: pp-number can contain one or more single quotes.

Rationale: Necessary to enable single quotes as digit separators.

Effect on original feature: Valid C++ 2011 code may fail to compile or may change meaning in this International Standard.
For example, the following code is valid both in C++ 2011 and in this International Standard, but the macro invocation produces different outcomes because the single quotes delimit a character literal in C++ 2011, whereas they are digit separators in this International Standard:
#define M(x, ...) __VA_ARGS__
int x[2] = { M(1'2,3'4, 5) };
// int x[2] = { 5 };      — C++ 2011
// int x[2] = { 3'4, 5 }; — this International Standard

C.3.2 Clause [basic]: basic concepts [diff.cpp11.basic]

[basic.stc.dynamic.deallocation]
Change: New usual (non-placement) deallocator.

Rationale: Required for sized deallocation.

Effect on original feature: Valid C++ 2011 code could declare a global placement allocation function and deallocation function as follows:
void* operator new(std::size_t, std::size_t);
void operator delete(void*, std::size_t) noexcept;
In this International Standard, however, the declaration of operator delete might match a predefined usual (non-placement) operator delete ([basic.stc.dynamic]).
If so, the program is ill-formed, as it was for class member allocation functions and deallocation functions ([expr.new]).

C.3.3 Clause [expr]: expressions [diff.cpp11.expr]

[expr.cond]
Change: A conditional expression with a throw expression as its second or third operand keeps the type and value category of the other operand.

Rationale: Formerly mandated conversions (lvalue-to-rvalue ([conv.lval]), array-to-pointer ([conv.array]), and function-to-pointer ([conv.func]) standard conversions), especially the creation of the temporary due to lvalue-to-rvalue conversion, were considered gratuitous and surprising.

Effect on original feature: Valid C++ 2011 code that relies on the conversions may behave differently in this International Standard:
struct S {
  int x = 1;
  void mf() { x = 2; }
};
int f(bool cond) {
  S s;
  (cond ? s : throw 0).mf();
  return s.x;
}
In C++ 2011, f(true) returns 1.
In this International Standard, it returns 2.
sizeof(true ? "" : throw 0)
In C++ 2011, the expression yields sizeof(const char*).
In this International Standard, it yields sizeof(const char[1]).

C.3.4 Clause [dcl.dcl]: declarations [diff.cpp11.dcl.dcl]

[dcl.constexpr]
Change: constexpr non-static member functions are not implicitly const member functions.

Rationale: Necessary to allow constexpr member functions to mutate the object.

Effect on original feature: Valid C++ 2011 code may fail to compile in this International Standard.
For example, the following code is valid in C++ 2011 but invalid in this International Standard because it declares the same member function twice with different return types:
struct S {
  constexpr const int &f();
  int &f();
};

C.3.5 Clause [dcl.decl]: declarators [diff.cpp11.dcl.decl]

[dcl.init.aggr]
Change: Classes with default member initializers can be aggregates.

Rationale: Necessary to allow default member initializers to be used by aggregate initialization.

Effect on original feature: Valid C++ 2011 code may fail to compile or may change meaning in this International Standard.
struct S { // Aggregate in C++ 2014 onwards.
  int m = 1;
};
struct X {
  operator int();
  operator S();
};
X a{};
S b{a};  // uses copy constructor in C++ 2011,
         // performs aggregate initialization in this International Standard

C.3.6 Clause [library]: library introduction [diff.cpp11.library]

[headers]
Change: New header.

Rationale: New functionality.

Effect on original feature: The C++ header <shared_­mutex> is new.
Valid C++ 2011 code that #includes a header with that name may be invalid in this International Standard.

C.3.7 Clause [input.output]: input/output library [diff.cpp11.input.output]

[c.files]
Change: gets is not defined.

Rationale: Use of gets is considered dangerous.

Effect on original feature: Valid C++ 2011 code that uses the gets function may fail to compile in this International Standard.

C.4 C++ and ISO C++ 2014 [diff.cpp14]

This subclause lists the differences between C++ and ISO C++ 2014 (ISO/IEC 14882:2014, Programming Languages — C++), by the chapters of this document.

C.4.1 Clause [lex]: lexical conventions [diff.cpp14.lex]

[lex.phases]
Change: Removal of trigraph support as a required feature.

Rationale: Prevents accidental uses of trigraphs in non-raw string literals and comments.

Effect on original feature: Valid C++ 2014 code that uses trigraphs may not be valid or may have different semantics in this International Standard.
Implementations may choose to translate trigraphs as specified in C++ 2014 if they appear outside of a raw string literal, as part of the implementation-defined mapping from physical source file characters to the basic source character set.
[lex.ppnumber]
Change: pp-number can contain p sign and P sign.

Rationale: Necessary to enable hexadecimal floating literals.

Effect on original feature: Valid C++ 2014 code may fail to compile or produce different results in this International Standard.
Specifically, character sequences like 0p+0 and 0e1_­p+0 are three separate tokens each in C++ 2014, but one single token in this International Standard.
#define F(a) b ## a
int b0p = F(0p+0);  // ill-formed; equivalent to “int b0p = b0p + 0;” in C++ 2014

C.4.2 Clause [expr]: expressions [diff.cpp14.expr]

[expr.post.incr], [expr.pre.incr]
Change: Remove increment operator with bool operand.

Rationale: Obsolete feature with occasionally surprising semantics.

Effect on original feature: A valid C++ 2014 expression utilizing the increment operator on a bool lvalue is ill-formed in this International Standard.
Note that this might occur when the lvalue has a type given by a template parameter.
[expr.new], [expr.delete]
Change: Dynamic allocation mechanism for over-aligned types.

Rationale: Simplify use of over-aligned types.

Effect on original feature: In C++ 2014 code that uses a new-expression to allocate an object with an over-aligned class type, where that class has no allocation functions of its own, ​::​operator new(std​::​size_­t) is used to allocate the memory.
In this International Standard, ​::​operator new(std​::​size_­t, std​::​align_­val_­t) is used instead.

C.4.3 Clause [dcl.dcl]: declarations [diff.cpp14.dcl.dcl]

[dcl.stc]
Change: Removal of register storage-class-specifier.

Rationale: Enable repurposing of deprecated keyword in future revisions of this International Standard.

Effect on original feature: A valid C++ 2014 declaration utilizing the register storage-class-specifier is ill-formed in this International Standard.
The specifier can simply be removed to retain the original meaning.
[dcl.spec.auto]
Change: auto deduction from braced-init-list.

Rationale: More intuitive deduction behavior.

Effect on original feature: Valid C++ 2014 code may fail to compile or may change meaning in this International Standard.
For example:
auto x1{1};    // was std​::​initializer_­list<int>, now int
auto x2{1, 2}; // was std​::​initializer_­list<int>, now ill-formed

C.4.4 Clause [dcl.decl]: declarators [diff.cpp14.decl]

[dcl.fct]
Change: Make exception specifications be part of the type system.

Rationale: Improve type-safety.

Effect on original feature: Valid C++ 2014 code may fail to compile or change meaning in this International Standard:
void g1() noexcept;
void g2();
template<class T> int f(T *, T *);
int x = f(g1, g2);    // ill-formed; previously well-formed
[dcl.init.aggr]
Change: Definition of an aggregate is extended to apply to user-defined types with base classes.

Rationale: To increase convenience of aggregate initialization.

Effect on original feature: Valid C++ 2014 code may fail to compile or produce different results in this International Standard; initialization from an empty initializer list will perform aggregate initialization instead of invoking a default constructor for the affected types:
struct derived;
struct base {
  friend struct derived;
private:
  base();
};
struct derived : base {};

derived d1{};       // Error. The code was well-formed before.
derived d2;         // still OK

C.4.5 Clause [special]: special member functions [diff.cpp14.special]

[class.inhctor.init]
Change: Inheriting a constructor no longer injects a constructor into the derived class.

Rationale: Better interaction with other language features.

Effect on original feature: Valid C++ 2014 code that uses inheriting constructors may not be valid or may have different semantics.
A using-declaration that names a constructor now makes the corresponding base class constructors visible to initializations of the derived class rather than declaring additional derived class constructors.
struct A {
  template<typename T> A(T, typename T::type = 0);
  A(int);
};
struct B : A {
  using A::A;
  B(int);
};
B b(42L); // now calls B(int), used to call B<long>(long),
          // which called A(int) due to substitution failure
          // in A<long>(long).

C.4.6 Clause [temp]: templates [diff.cpp14.temp]

[temp.deduct.type]
Change: Allowance to deduce from the type of a non-type template argument.

Rationale: In combination with the ability to declare non-type template arguments with placeholder types, allows partial specializations to decompose from the type deduced for the non-type template argument.

Effect on original feature: Valid C++ 2014 code may fail to compile or produce different results in this International Standard:
template <int N> struct A;
template <typename T, T N> int foo(A<N> *) = delete;
void foo(void *);
void bar(A<0> *p) {
  foo(p); // ill-formed; previously well-formed
}

C.4.7 Clause [except]: exception handling [diff.cpp14.except]

[except.spec]
Change: Remove dynamic exception specifications.

Rationale: Dynamic exception specifications were a deprecated feature that was complex and brittle in use.
They interacted badly with the type system, which became a more significant issue in this International Standard where (non-dynamic) exception specifications are part of the function type.

Effect on original feature: A valid C++ 2014 function declaration, member function declaration, function pointer declaration, or function reference declaration, if it has a potentially throwing dynamic exception specification, will be rejected as ill-formed in this International Standard.
Violating a non-throwing dynamic exception specification will call terminate rather than unexpected and might not perform stack unwinding prior to such a call.

C.4.8 Clause [library]: library introduction [diff.cpp14.library]

[namespace.future]
Change: New reserved namespaces.

Rationale: Reserve namespaces for future revisions of the standard library that might otherwise be incompatible with existing programs.

Effect on original feature: The global namespaces std followed by an arbitrary sequence of digits is reserved for future standardization.
Valid C++ 2014 code that uses such a top-level namespace, e.g., std2, may be invalid in this International Standard.

C.4.9 Clause [utilities]: general utilities library [diff.cpp14.utilities]

[func.wrap]
Change: Constructors taking allocators removed.

Rationale: No implementation consensus.

Effect on original feature: Valid C++ 2014 code may fail to compile or may change meaning in this International Standard.
Specifically, constructing a std​::​function with an allocator is ill-formed and uses-allocator construction will not pass an allocator to std​::​function constructors in this International Standard.
[util.smartptr.shared]
Change: Different constraint on conversions from unique_­ptr.

Rationale: Adding array support to shared_­ptr, via the syntax shared_­ptr<T[]> and shared_­ptr<T[N]>.

Effect on original feature: Valid C++ 2014 code may fail to compile or may change meaning in this International Standard.
For example:
#include <memory>
std::unique_ptr<int[]> arr(new int[1]);
std::shared_ptr<int> ptr(std::move(arr)); // error: int(*)[] is not compatible with int*

C.4.10 Clause [strings]: strings library [diff.cpp14.string]

[basic.string]
Change: Non-const .data() member added.

Rationale: The lack of a non-const .data() differed from the similar member of std​::​vector.
This change regularizes behavior for this International Standard.

Effect on original feature: Overloaded functions which have differing code paths for char* and const char* arguments will execute differently when called with a non-const string's .data() member in this International Standard.
int f(char *) = delete;
int f(const char *);
string s;
int x = f(s.data()); // ill-formed; previously well-formed

C.4.11 Clause [containers]: containers library [diff.cpp14.containers]

[associative.reqmts]
Change: Requirements change:
Rationale: Increase portability, clarification of associative container requirements.

Effect on original feature: Valid C++ 2014 code that attempts to use associative containers having a comparison object with non-const function call operator may fail to compile in this International Standard:
#include <set>

struct compare
{
  bool operator()(int a, int b)
  {
    return a < b;
  }
};

int main() {
  const std::set<int, compare> s;
  s.find(0);
}

C.4.12 Annex [depr]: compatibility features [diff.cpp14.depr]


Change: The class templates auto_­ptr, unary_­function, and binary_­function, the function templates random_­shuffle, and the function templates (and their return types) ptr_­fun, mem_­fun, mem_­fun_­ref, bind1st, and bind2nd are not defined.

Rationale: Superseded by new features.

Effect on original feature: Valid C++ 2014 code that uses these class templates and function templates may fail to compile in this International Standard.

Change: Remove old iostreams members [depr.
ios.
members].

Rationale: Redundant feature for compatibility with pre-standard code has served its time.

Effect on original feature: A valid C++ 2014 program using these identifiers may be ill-formed in this International Standard.

C.5 C standard library [diff.library]

This subclause summarizes the explicit changes in headers, definitions, declarations, or behavior between the C standard library in the C standard and the parts of the C++ standard library that were included from the C standard library.

C.5.1 Modifications to headers [diff.mods.to.headers]

For compatibility with the C standard library, the C++ standard library provides the C headers enumerated in [depr.c.headers], but their use is deprecated in C++.
There are no C++ headers for the C headers <stdatomic.h>, <stdnoreturn.h>, and <threads.h>, nor are the C headers themselves part of C++.
The C++ headers <ccomplex> ([depr.ccomplex.syn]) and <ctgmath> ([depr.ctgmath.syn]), as well as their corresponding C headers <complex.h> and <tgmath.h>, do not contain any of the content from the C standard library and instead merely include other headers from the C++ standard library.
The headers <ciso646>, <cstdalign> ([depr.cstdalign.syn]), and <cstdbool> ([depr.cstdbool.syn]) are meaningless in C++.
Use of the C++ headers <ccomplex>, <cstdalign>, <cstdbool>, and <ctgmath> is deprecated ([depr.c.headers]).

C.5.2 Modifications to definitions [diff.mods.to.definitions]

C.5.2.1 Types char16_­t and char32_­t [diff.char16]

The types char16_­t and char32_­t are distinct types rather than typedefs to existing integral types.
The tokens char16_­t and char32_­t are keywords in this International Standard ([lex.key]).
They do not appear as macro names defined in <cuchar> ([cuchar.syn]).

C.5.2.2 Type wchar_­t [diff.wchar.t]

The type wchar_­t is a distinct type rather than a typedef to an existing integral type.
The token wchar_­t is a keyword in this International Standard ([lex.key]).
It does not appear as a type name defined in any of <cstddef> ([cstddef.syn]), <cstdlib> ([cstdlib.syn]), or <cwchar> ([cwchar.syn]).

C.5.2.3 Header <assert.h> [diff.header.assert.h]

The token static_­assert is a keyword in this International Standard ([lex.key]).
It does not appear as a macro name defined in <cassert> ([cassert.syn]).

C.5.2.4 Header <iso646.h> [diff.header.iso646.h]

The tokens and, and_­eq, bitand, bitor, compl, not_­eq, not, or, or_­eq, xor, and xor_­eq are keywords in this International Standard ([lex.key]).
They do not appear as macro names defined in <ciso646>.

C.5.2.5 Header <stdalign.h> [diff.header.stdalign.h]

The token alignas is a keyword in this International Standard ([lex.key]).
It does not appear as a macro name defined in <cstdalign> ([depr.cstdalign.syn]).

C.5.2.6 Header <stdbool.h> [diff.header.stdbool.h]

The tokens bool, true, and false are keywords in this International Standard ([lex.key]).
They do not appear as macro names defined in <cstdbool> ([depr.cstdbool.syn]).

C.5.2.7 Macro NULL [diff.null]

The macro NULL, defined in any of <clocale> ([c.locales]), <cstddef> ([cstddef.syn]), <cstdio> ([cstdio.syn]), <cstdlib> ([cstdlib.syn]), <cstring> ([cstring.syn]), <ctime> ([ctime.syn]), or <cwchar> ([cwchar.syn]), is an implementation-defined C++ null pointer constant in this International Standard ([support.types]).

C.5.3 Modifications to declarations [diff.mods.to.declarations]

Header <cstring> ([cstring.syn]): The following functions have different declarations:
Subclause [cstring.syn] describes the changes.
Header <cwchar> ([cwchar.syn]): The following functions have different declarations:
Subclause [cwchar.syn] describes the changes.
Header <cstddef> ([cstddef.syn]) declares the name nullptr_­t in addition to the names declared in <stddef.h> in the C standard library.

C.5.4 Modifications to behavior [diff.mods.to.behavior]

Header <cstdlib> ([cstdlib.syn]): The following functions have different behavior:
Subclause [support.start.term] describes the changes.
Header <csetjmp> ([csetjmp.syn]): The following functions have different behavior:
Subclause [csetjmp.syn] describes the changes.

C.5.4.1 Macro offsetof(type, member-designator) [diff.offsetof]

The macro offsetof, defined in <cstddef> ([cstddef.syn]), accepts a restricted set of type arguments in this International Standard.
Subclause [support.types.layout] describes the change.

C.5.4.2 Memory allocation functions [diff.malloc]

The functions aligned_­alloc, calloc, malloc, and realloc are restricted in this International Standard.
Subclause [c.malloc] describes the changes.

Annex D (normative) Compatibility features [depr]

This Clause describes features of the C++ Standard that are specified for compatibility with existing implementations.
These are deprecated features, where deprecated is defined as: Normative for the current edition of this International Standard, but having been identified as a candidate for removal from future revisions.
An implementation may declare library names and entities described in this section with the deprecated attribute ([dcl.attr.deprecated]).

D.1 Redeclaration of static constexpr data members [depr.static_constexpr]

For compatibility with prior C++ International Standards, a constexpr static data member may be redundantly redeclared outside the class with no initializer.
This usage is deprecated.
[Example
:
struct A {
  static constexpr int n = 5;  // definition (declaration in C++ 2014)
};

constexpr int A::n;  // redundant declaration (definition in C++ 2014)
end example
]

D.2 Implicit declaration of copy functions [depr.impldec]

The implicit definition of a copy constructor as defaulted is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.
The implicit definition of a copy assignment operator as defaulted is deprecated if the class has a user-declared copy constructor or a user-declared destructor ([class.dtor], [class.copy]).
In a future revision of this International Standard, these implicit definitions could become deleted ([dcl.fct.def]).

D.3 Deprecated exception specifications [depr.except.spec]

The noexcept-specifier throw() is deprecated.

D.4 C++ standard library headers [depr.cpp.headers]

For compatibility with prior C++ International Standards, the C++ standard library provides headers <ccomplex> ([depr.ccomplex.syn]), <cstdalign> ([depr.cstdalign.syn]), <cstdbool> ([depr.cstdbool.syn]), and <ctgmath> ([depr.ctgmath.syn]).
The use of these headers is deprecated.

D.4.1 Header <ccomplex> synopsis [depr.ccomplex.syn]

#include <complex>
The header <ccomplex> behaves as if it simply includes the header <complex> ([complex.syn]).

D.4.2 Header <cstdalign> synopsis [depr.cstdalign.syn]

#define __alignas_­is_­defined 1
The contents of the header <cstdalign> are the same as the C standard library header <stdalign.h>, with the following changes: The header <cstdalign> and the header <stdalign.h> shall not define a macro named alignas.
See also: ISO C 7.
15.

D.4.3 Header <cstdbool> synopsis [depr.cstdbool.syn]

#define __bool_­true_­false_­are_­defined 1
The contents of the header <cstdbool> are the same as the C standard library header <stdbool.h>, with the following changes: The header <cstdbool> and the header <stdbool.h> shall not define macros named bool, true, or false.
See also: ISO C 7.
18.

D.4.4 Header <ctgmath> synopsis [depr.ctgmath.syn]

#include <complex>
#include <cmath>
The header <ctgmath> simply includes the headers <complex> ([complex.syn]) and <cmath> ([cmath.syn]).
[Note
:
The overloads provided in C by type-generic macros are already provided in <complex> and <cmath> by “sufficient” additional overloads.
end note
]

D.5 C standard library headers [depr.c.headers]

For compatibility with the C standard library, the C++ standard library provides the C headers shown in Table 136.
Table 136 — C headers
<assert.h>
<inttypes.h>
<signal.h>
<stdio.h>
<wchar.h>
<complex.h>
<iso646.h>
<stdalign.h>
<stdlib.h>
<wctype.h>
<ctype.h>
<limits.h>
<stdarg.h>
<string.h>
<errno.h>
<locale.h>
<stdbool.h>
<tgmath.h>
<fenv.h>
<math.h>
<stddef.h>
<time.h>
<float.h>
<setjmp.h>
<stdint.h>
<uchar.h>
The header <complex.h> behaves as if it simply includes the header <ccomplex>.
The header <tgmath.h> behaves as if it simply includes the header <ctgmath>.
Every other C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope, except for the functions described in [sf.cmath], the declaration of std​::​byte ([cstddef.syn]), and the functions and function templates described in [support.types.byteops].
It is unspecified whether these names are first declared or defined within namespace scope ([basic.scope.namespace]) of the namespace std and are then injected into the global namespace scope by explicit using-declarations.
[Example
:
The header <cstdlib> assuredly provides its declarations and definitions within the namespace std.
It may also provide these names within the global namespace.
The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard.
It may also provide these names within the namespace std.
end example
]

D.6 char* streams [depr.str.strstreams]

The header <strstream> defines three types that associate stream buffers with character array objects and assist reading and writing such objects.

D.6.1 Class strstreambuf [depr.strstreambuf]

namespace std {
  class strstreambuf : public basic_streambuf<char> {
  public:
    explicit strstreambuf(streamsize alsize_arg = 0);
    strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));
    strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0);
    strstreambuf(const char* gnext_arg, streamsize n);

    strstreambuf(signed char* gnext_arg, streamsize n,
                 signed char* pbeg_arg = 0);
    strstreambuf(const signed char* gnext_arg, streamsize n);
    strstreambuf(unsigned char* gnext_arg, streamsize n,
                 unsigned char* pbeg_arg = 0);
    strstreambuf(const unsigned char* gnext_arg, streamsize n);

    virtual ~strstreambuf();

    void  freeze(bool freezefl = true);
    char* str();
    int   pcount();

  protected:
    int_type overflow (int_type c = EOF) override;
    int_type pbackfail(int_type c = EOF) override;
    int_type underflow() override;
    pos_type seekoff(off_type off, ios_base::seekdir way,
                     ios_base::openmode which
                      = ios_base::in | ios_base::out) override;
    pos_type seekpos(pos_type sp,
                     ios_base::openmode which
                      = ios_base::in | ios_base::out) override;
    streambuf* setbuf(char* s, streamsize n) override;

  private:
    using strstate = T1;              // exposition only
    static const strstate allocated;  // exposition only
    static const strstate constant;   // exposition only
    static const strstate dynamic;    // exposition only
    static const strstate frozen;     // exposition only
    strstate strmode;                 // exposition only
    streamsize alsize;                // exposition only
    void* (*palloc)(size_t);          // exposition only
    void (*pfree)(void*);             // exposition only
  };
}
The class strstreambuf associates the input sequence, and possibly the output sequence, with an object of some character array type, whose elements store arbitrary values.
The array object has several attributes.
[Note
:
For the sake of exposition, these are represented as elements of a bitmask type (indicated here as T1) called strstate.
The elements are:
  • allocated, set when a dynamic array object has been allocated, and hence should be freed by the destructor for the strstreambuf object;
  • constant, set when the array object has const elements, so the output sequence cannot be written;
  • dynamic, set when the array object is allocated (or reallocated) as necessary to hold a character sequence that can change in length;
  • frozen, set when the program has requested that the array object not be altered, reallocated, or freed.
end note
]
[Note
:
For the sake of exposition, the maintained data is presented here as:
  • strstate strmode, the attributes of the array object associated with the strstreambuf object;
  • int alsize, the suggested minimum size for a dynamic array object;
  • void* (*palloc)(size_­t), points to the function to call to allocate a dynamic array object;
  • void (*pfree)(void*), points to the function to call to free a dynamic array object.
end note
]
Each object of class strstreambuf has a seekable area, delimited by the pointers seeklow and seekhigh.
If gnext is a null pointer, the seekable area is undefined.
Otherwise, seeklow equals gbeg and seekhigh is either pend, if pend is not a null pointer, or gend.

D.6.1.1 strstreambuf constructors [depr.strstreambuf.cons]

explicit strstreambuf(streamsize alsize_arg = 0);
Effects: Constructs an object of class strstreambuf, initializing the base class with streambuf().
The postconditions of this function are indicated in Table 137.
Table 137strstreambuf(streamsize) effects
Element
Value
strmode
dynamic
alsize
alsize_­arg
palloc
a null pointer
pfree
a null pointer
strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));
Effects: Constructs an object of class strstreambuf, initializing the base class with streambuf().
The postconditions of this function are indicated in Table 138.
Table 138strstreambuf(void* (*)(size_­t), void (*)(void*)) effects
Element
Value
strmode
dynamic
alsize
an unspecified value
palloc
palloc_­arg
pfree
pfree_­arg
strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0); strstreambuf(signed char* gnext_arg, streamsize n, signed char* pbeg_arg = 0); strstreambuf(unsigned char* gnext_arg, streamsize n, unsigned char* pbeg_arg = 0);
Effects: Constructs an object of class strstreambuf, initializing the base class with streambuf().
The postconditions of this function are indicated in Table 139.
Table 139strstreambuf(charT*, streamsize, charT*) effects
Element
Value
strmode
0
alsize
an unspecified value
palloc
a null pointer
pfree
a null pointer
gnext_­arg shall point to the first element of an array object whose number of elements N is determined as follows:
  • If n > 0, N is n.
  • If n == 0, N is std​::​strlen(gnext_­arg).
  • If n < 0, N is INT_­MAX.331
If pbeg_­arg is a null pointer, the function executes:
setg(gnext_arg, gnext_arg, gnext_arg + N);
Otherwise, the function executes:
setg(gnext_arg, gnext_arg, pbeg_arg);
setp(pbeg_arg,  pbeg_arg + N);
strstreambuf(const char* gnext_arg, streamsize n); strstreambuf(const signed char* gnext_arg, streamsize n); strstreambuf(const unsigned char* gnext_arg, streamsize n);
Effects: Behaves the same as strstreambuf((char*)gnext_­arg,n), except that the constructor also sets constant in strmode.
virtual ~strstreambuf();
Effects: Destroys an object of class strstreambuf.
The function frees the dynamically allocated array object only if (strmode & allocated) != 0 and (strmode & frozen) == 0.
([depr.strstreambuf.virtuals] describes how a dynamically allocated array object is freed.)
The function signature strlen(const char*) is declared in <cstring> ([cstring.syn]).
The macro INT_­MAX is defined in <climits> ([climits.syn]).

D.6.1.2 Member functions [depr.strstreambuf.members]

void freeze(bool freezefl = true);
Effects: If strmode & dynamic is nonzero, alters the freeze status of the dynamic array object as follows:
  • If freezefl is true, the function sets frozen in strmode.
  • Otherwise, it clears frozen in strmode.
char* str();
Effects: Calls freeze(), then returns the beginning pointer for the input sequence, gbeg.
Remarks: The return value can be a null pointer.
int pcount() const;
Effects: If the next pointer for the output sequence, pnext, is a null pointer, returns zero.
Otherwise, returns the current effective length of the array object as the next pointer minus the beginning pointer for the output sequence, pnext - pbeg.

D.6.1.3 strstreambuf overridden virtual functions [depr.strstreambuf.virtuals]

int_type overflow(int_type c = EOF) override;
Effects: Appends the character designated by c to the output sequence, if possible, in one of two ways:
  • If c != EOF and if either the output sequence has a write position available or the function makes a write position available (as described below), assigns c to *pnext++.
    Returns (unsigned char)c.
  • If c == EOF, there is no character to append.
    Returns a value other than EOF.
Returns EOF to indicate failure.
Remarks: The function can alter the number of write positions available as a result of any call.
To make a write position available, the function reallocates (or initially allocates) an array object with a sufficient number of elements n to hold the current array object (if any), plus at least one additional write position.
How many additional write positions are made available is otherwise unspecified.
332 If palloc is not a null pointer, the function calls (*palloc)(n) to allocate the new dynamic array object.
Otherwise, it evaluates the expression new charT[n].
In either case, if the allocation fails, the function returns EOF.
Otherwise, it sets allocated in strmode.
To free a previously existing dynamic array object whose first element address is p: If pfree is not a null pointer, the function calls (*pfree)(p).
Otherwise, it evaluates the expression delete[]p.
If (strmode & dynamic) == 0, or if (strmode & frozen) != 0, the function cannot extend the array (reallocate it with greater length) to make a write position available.
int_type pbackfail(int_type c = EOF) override;
Puts back the character designated by c to the input sequence, if possible, in one of three ways:
  • If c != EOF, if the input sequence has a putback position available, and if (char)c == gnext[-1], assigns gnext - 1 to gnext.
    Returns c.
  • If c != EOF, if the input sequence has a putback position available, and if strmode & constant is zero, assigns c to *--gnext.
    Returns c.
  • If c == EOF and if the input sequence has a putback position available, assigns gnext - 1 to gnext.
    Returns a value other than EOF.
Returns EOF to indicate failure.
Remarks: If the function can succeed in more than one of these ways, it is unspecified which way is chosen.
The function can alter the number of putback positions available as a result of any call.
int_type underflow() override;
Effects: Reads a character from the input sequence, if possible, without moving the stream position past it, as follows:
  • If the input sequence has a read position available, the function signals success by returning (unsigned char)​*gnext.
  • Otherwise, if the current write next pointer pnext is not a null pointer and is greater than the current read end pointer gend, makes a read position available by assigning to gend a value greater than gnext and no greater than pnext.
    Returns (unsigned char)*gnext.
Returns EOF to indicate failure.
Remarks: The function can alter the number of read positions available as a result of any call.
pos_type seekoff(off_type off, seekdir way, openmode which = in | out) override;
Effects: Alters the stream position within one of the controlled sequences, if possible, as indicated in Table 140.
Table 140seekoff positioning
Conditions
Result
(which & ios​::​in) != 0
positions the input sequence
(which & ios​::​out) != 0
positions the output sequence
(which & (ios​::​in |
ios​::​out)) == (ios​::​in |
ios​::​out)) and
way == either
ios​::​beg or
ios​::​end
positions both the input and the output sequences
Otherwise
the positioning operation fails.
For a sequence to be positioned, if its next pointer is a null pointer, the positioning operation fails.
Otherwise, the function determines newoff as indicated in Table 141.
Table 141newoff values
Condition
newoff Value
way == ios​::​beg
0
way == ios​::​cur
the next pointer minus the beginning pointer (xnext - xbeg).
way == ios​::​end
seekhigh minus the beginning pointer (seekhigh - xbeg).
If (newoff + off) < (seeklow - xbeg) or (seekhigh - xbeg) < (newoff + off), the positioning operation fails.
Otherwise, the function assigns xbeg + newoff + off to the next pointer xnext.
Returns: pos_­type(newoff), constructed from the resultant offset newoff (of type off_­type), that stores the resultant stream position, if possible.
If the positioning operation fails, or if the constructed object cannot represent the resultant stream position, the return value is pos_­type(off_­type(-1)).
pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out) override;
Effects: Alters the stream position within one of the controlled sequences, if possible, to correspond to the stream position stored in sp (as described below).
  • If (which & ios​::​in) != 0, positions the input sequence.
  • If (which & ios​::​out) != 0, positions the output sequence.
  • If the function positions neither sequence, the positioning operation fails.
For a sequence to be positioned, if its next pointer is a null pointer, the positioning operation fails.
Otherwise, the function determines newoff from sp.offset():
  • If newoff is an invalid stream position, has a negative value, or has a value greater than (seekhigh - seeklow), the positioning operation fails
  • Otherwise, the function adds newoff to the beginning pointer xbeg and stores the result in the next pointer xnext.
Returns: pos_­type(newoff), constructed from the resultant offset newoff (of type off_­type), that stores the resultant stream position, if possible.
If the positioning operation fails, or if the constructed object cannot represent the resultant stream position, the return value is pos_­type(off_­type(-1)).
streambuf<char>* setbuf(char* s, streamsize n) override;
Effects: Implementation defined, except that setbuf(0, 0) has no effect.
An implementation should consider alsize in making this decision.

D.6.2 Class istrstream [depr.istrstream]

namespace std {
  class istrstream : public basic_istream<char> {
  public:
    explicit istrstream(const char* s);
    explicit istrstream(char* s);
    istrstream(const char* s, streamsize n);
    istrstream(char* s, streamsize n);
    virtual ~istrstream();

    strstreambuf* rdbuf() const;
    char* str();
  private:
    strstreambuf sb;  // exposition only
  };
}
The class istrstream supports the reading of objects of class strstreambuf.
It supplies a strstreambuf object to control the associated array object.
For the sake of exposition, the maintained data is presented here as:
  • sb, the strstreambuf object.

D.6.2.1 istrstream constructors [depr.istrstream.cons]

explicit istrstream(const char* s); explicit istrstream(char* s);
Effects: Constructs an object of class istrstream, initializing the base class with istream(&sb) and initializing sb with strstreambuf(s,0).
s shall designate the first element of an ntbs.
istrstream(const char* s, streamsize n); istrstream(char* s, streamsize n);
Effects: Constructs an object of class istrstream, initializing the base class with istream(&sb) and initializing sb with strstreambuf(s,n).
s shall designate the first element of an array whose length is n elements, and n shall be greater than zero.

D.6.2.2 Member functions [depr.istrstream.members]

strstreambuf* rdbuf() const;
Returns: const_­cast<strstreambuf*>(&sb).
char* str();
Returns: rdbuf()->str().

D.6.3 Class ostrstream [depr.ostrstream]

namespace std {
  class ostrstream : public basic_ostream<char> {
  public:
    ostrstream();
    ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out);
    virtual ~ostrstream();

    strstreambuf* rdbuf() const;
    void freeze(bool freezefl = true);
    char* str();
    int pcount() const;
  private:
    strstreambuf sb;  // exposition only
  };
}
The class ostrstream supports the writing of objects of class strstreambuf.
It supplies a strstreambuf object to control the associated array object.
For the sake of exposition, the maintained data is presented here as:
  • sb, the strstreambuf object.

D.6.3.1 ostrstream constructors [depr.ostrstream.cons]

ostrstream();
Effects: Constructs an object of class ostrstream, initializing the base class with ostream(&sb) and initializing sb with strstreambuf().
ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out);
Effects: Constructs an object of class ostrstream, initializing the base class with ostream(&sb), and initializing sb with one of two constructors:
  • If (mode & app) == 0, then s shall designate the first element of an array of n elements.
    The constructor is strstreambuf(s, n, s).
  • If (mode & app) != 0, then s shall designate the first element of an array of n elements that contains an ntbs whose first element is designated by s.
    The constructor is strstreambuf(s, n, s + std​::​strlen(s)).333
The function signature strlen(const char*) is declared in <cstring> ([cstring.syn]).

D.6.3.2 Member functions [depr.ostrstream.members]

strstreambuf* rdbuf() const;
Returns: (strstreambuf*)&sb.
void freeze(bool freezefl = true);
Effects: Calls rdbuf()->freeze(freezefl).
char* str();
Returns: rdbuf()->str().
int pcount() const;
Returns: rdbuf()->pcount().

D.6.4 Class strstream [depr.strstream]

namespace std {
  class strstream
    : public basic_iostream<char> {
  public:
    // Types
    using char_type = char;
    using int_type  = char_traits<char>::int_type;
    using pos_type  = char_traits<char>::pos_type;
    using off_type  = char_traits<char>::off_type;

    // constructors/destructor
    strstream();
    strstream(char* s, int n,
              ios_base::openmode mode = ios_base::in|ios_base::out);
    virtual ~strstream();

    // Members:
    strstreambuf* rdbuf() const;
    void freeze(bool freezefl = true);
    int pcount() const;
    char* str();

  private:
  strstreambuf sb;  // exposition only
  };
}
The class strstream supports reading and writing from objects of class strstreambuf.
It supplies a strstreambuf object to control the associated array object.
For the sake of exposition, the maintained data is presented here as:
  • sb, the strstreambuf object.

D.6.4.1 strstream constructors [depr.strstream.cons]

strstream();
Effects: Constructs an object of class strstream, initializing the base class with iostream(&sb).
strstream(char* s, int n, ios_base::openmode mode = ios_base::in|ios_base::out);
Effects: Constructs an object of class strstream, initializing the base class with iostream(&sb) and initializing sb with one of the two constructors:
  • If (mode & app) == 0, then s shall designate the first element of an array of n elements.
    The constructor is strstreambuf(s,n,s).
  • If (mode & app) != 0, then s shall designate the first element of an array of n elements that contains an ntbs whose first element is designated by s.
    The constructor is strstreambuf(s,n,s + std​::​strlen(s)).

D.6.4.2 strstream destructor [depr.strstream.dest]

virtual ~strstream();
Effects: Destroys an object of class strstream.

D.6.4.3 strstream operations [depr.strstream.oper]

strstreambuf* rdbuf() const;
Returns: &sb.
void freeze(bool freezefl = true);
Effects: Calls rdbuf()->freeze(freezefl).
char* str();
Returns: rdbuf()->str().
int pcount() const;
Returns: rdbuf()->pcount().

D.7 uncaught_­exception [depr.uncaught]

The header <exception> has the following addition:
namespace std {
  bool uncaught_exception() noexcept;
}
bool uncaught_exception() noexcept;
Returns: uncaught_­exceptions() > 0.

D.8 Old adaptable function bindings [depr.func.adaptor.binding]

D.8.1 Weak result types [depr.weak.result_type]

A call wrapper ([func.def]) may have a weak result type.
If it does, the type of its member type result_­type is based on the type T of the wrapper's target object:
  • if T is a pointer to function type, result_­type shall be a synonym for the return type of T;
  • if T is a pointer to member function, result_­type shall be a synonym for the return type of T;
  • if T is a class type and the qualified-id T​::​result_­type is valid and denotes a type ([temp.deduct]), then result_­type shall be a synonym for T​::​result_­type;
  • otherwise result_­type shall not be defined.

D.8.2 Typedefs to support function binders [depr.func.adaptor.typedefs]

To enable old function adaptors to manipulate function objects that take one or two arguments, many of the function objects in this International Standard correspondingly provide typedef-names argument_­type and result_­type for function objects that take one argument and first_­argument_­type, second_­argument_­type, and result_­type for function objects that take two arguments.
The following member names are defined in addition to names specified in Clause [function.objects]:
namespace std {
  template<class T> struct owner_less<shared_ptr<T>> {
    using result_type          = bool;
    using first_argument_type  = shared_ptr<T>;
    using second_argument_type = shared_ptr<T>;
  };

  template<class T> struct owner_less<weak_ptr<T>> {
    using result_type          = bool;
    using first_argument_type  = weak_ptr<T>;
    using second_argument_type = weak_ptr<T>;
  };

  template <class T> class reference_wrapper {
  public :
    using result_type          = see below; // not always defined
    using argument_type        = see below; // not always defined
    using first_argument_type  = see below; // not always defined
    using second_argument_type = see below; // not always defined
  };

  template <class T> struct plus {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct minus {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct multiplies {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct divides {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct modulus {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct negate {
    using argument_type = T;
    using result_type   = T;
  };

  template <class T> struct equal_to {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct not_equal_to {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct greater {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct less {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct greater_equal {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct less_equal {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct logical_and {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct logical_or {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct logical_not {
    using argument_type = T;
    using result_type   = bool;
  };

  template <class T> struct bit_and {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct bit_or {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct bit_xor {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct bit_not {
    using argument_type = T;
    using result_type   = T;
  };

  template<class R, class T1>
  class function<R(T1)> {
  public:
    using argument_type = T1;
  };

  template<class R, class T1, class T2>
  class function<R(T1, T2)> {
  public:
    using first_argument_type  = T1;
    using second_argument_type = T2;
  };
}
reference_­wrapper<T> has a weak result type ([depr.weak.result_type]).
If T is a function type, result_­type shall be a synonym for the return type of T.
The template specialization reference_­wrapper<T> shall define a nested type named argument_­type as a synonym for T1 only if the type T is any of the following:
  • a function type or a pointer to function type taking one argument of type T1
  • a pointer to member function R T0​::​f() cv (where cv represents the member function's cv-qualifiers); the type T1 is cv T0*
  • a class type where the qualified-id T​::​argument_­type is valid and denotes a type ([temp.deduct]); the type T1 is T​::​argument_­type.
The template instantiation reference_­wrapper<T> shall define two nested types named first_­argument_­type and second_­argument_­type as synonyms for T1 and T2, respectively, only if the type T is any of the following:
  • a function type or a pointer to function type taking two arguments of types T1 and T2
  • a pointer to member function R T0​::​f(T2) cv (where cv represents the member function's cv-qualifiers); the type T1 is cv T0*
  • a class type where the qualified-ids T​::​first_­argument_­type and T​::​second_­argument_­type are both valid and both denote types ([temp.deduct]); the type T1 is T​::​first_­argument_­type and the type T2 is T​::​second_­argument_­type.
All enabled specializations hash<Key> of hash ([unord.hash]) provide two nested types, result_­type and argument_­type, which shall be synonyms for size_­t and Key, respectively.
The forwarding call wrapper g returned by a call to bind(f, bound_­args...) ([func.bind.bind]) shall have a weak result type ([depr.weak.result_type]).
The forwarding call wrapper g returned by a call to bind<R>(f, bound_­args...) ([func.bind.bind]) shall have a nested type result_­type defined as a synonym for R.
The simple call wrapper returned from a call to mem_­fn(pm) shall have a nested type result_­type that is a synonym for the return type of pm when pm is a pointer to member function.
The simple call wrapper returned from a call to mem_­fn(pm) shall define two nested types named argument_­type and result_­type as synonyms for cv T* and Ret, respectively, when pm is a pointer to member function with cv-qualifier cv and taking no arguments, where Ret is pm's return type.
The simple call wrapper returned from a call to mem_­fn(pm) shall define three nested types named first_­argument_­type, second_­argument_­type, and result_­type as synonyms for cv T*, T1, and Ret, respectively, when pm is a pointer to member function with cv-qualifier cv and taking one argument of type T1, where Ret is pm's return type.
The following member names are defined in addition to names specified in Clause [containers]:
namespace std {
  template <class Key, class T, class Compare, class Allocator>
  class map<Key, T, Compare, Allocator>::value_compare {
  public:
    using result_type          = bool;
    using first_argument_type  = value_type;
    using second_argument_type = value_type;
  };

  template <class Key, class T, class Compare, class Allocator>
  class multimap<Key, T, Compare, Allocator>::value_compare {
  public:
    using result_type          = bool;
    using first_argument_type  = value_type;
    using second_argument_type = value_type;
  };
}

D.8.3 Negators [depr.negators]

The header <functional> has the following additions:
namespace std {
  template <class Predicate> class unary_negate;
  template <class Predicate>
    constexpr unary_negate<Predicate> not1(const Predicate&);
  template <class Predicate> class binary_negate;
  template <class Predicate>
    constexpr binary_negate<Predicate> not2(const Predicate&);
}
Negators not1 and not2 take a unary and a binary predicate, respectively, and return their logical negations ([expr.unary.op]).
template <class Predicate>
class unary_negate {
public:
  constexpr explicit unary_negate(const Predicate& pred);
  constexpr bool operator()(const typename Predicate::argument_type& x) const;
  using argument_type = typename Predicate::argument_type;
  using result_type   = bool;
};
constexpr bool operator()(const typename Predicate::argument_type& x) const;
Returns: !pred(x).
template <class Predicate> constexpr unary_negate<Predicate> not1(const Predicate& pred);
Returns: unary_­negate<Predicate>(pred).
template <class Predicate>
class binary_negate {
public:
  constexpr explicit binary_negate(const Predicate& pred);
  constexpr bool operator()(const typename Predicate::first_argument_type& x,
                            const typename Predicate::second_argument_type& y) const;
  using first_argument_type  = typename Predicate::first_argument_type;
  using second_argument_type = typename Predicate::second_argument_type;
  using result_type          = bool;

};
constexpr bool operator()(const typename Predicate::first_argument_type& x, const typename Predicate::second_argument_type& y) const;
Returns: !pred(x,y).
template <class Predicate> constexpr binary_negate<Predicate> not2(const Predicate& pred);
Returns: binary_­negate<Predicate>(pred).

D.9 The default allocator [depr.default.allocator]

The following members and explicit class template specialization are defined in addition to those specified in [default.allocator]:
namespace std {
  // specialize for void:
  template <> class allocator<void> {
  public:
    using value_type    = void;
    using pointer       = void*;
    using const_pointer = const void*;
    // reference-to-void members are impossible.

    template <class U> struct rebind { using other = allocator<U>; };
  };

  template <class T> class allocator {
   public:
    using size_type       = size_t;
    using difference_type = ptrdiff_t;
    using pointer         = T*;
    using const_pointer   = const T*;
    using reference       = T&;
    using const_reference = const T&;
    template <class U> struct rebind { using other = allocator<U>; };

    T* address(T& x) const noexcept;
    const T* address(const T& x) const noexcept;

    T* allocate(size_t n, const void* hint);

    template<class U, class... Args>
      void construct(U* p, Args&&... args);
    template <class U>
      void destroy(U* p);

    size_t max_size() const noexcept;
  };
}
T* address(T& x) const noexcept; const T* address(const T& x) const noexcept;
Returns: addressof(x).
T* allocate(size_t n, const void* hint);
Returns: A pointer to the initial element of an array of storage of size n * sizeof(T), aligned appropriately for objects of type T.
It is implementation-defined whether over-aligned types are supported ([basic.align]).
Remarks: The storage is obtained by calling ​::​operator new(std​::​size_­t) ([new.delete]), but it is unspecified when or how often this function is called.
Throws: bad_­alloc if the storage cannot be obtained.
template <class U, class... Args> void construct(U* p, Args&&... args);
Effects: As if by: ​::​new((void *)p) U(std​::​forward<Args>(args)...);
template <class U> void destroy(U* p);
Effects: As if by p->~U().
size_t max_size() const noexcept;
Returns: The largest value N for which the call allocate(N, 0) might succeed.

D.10 Raw storage iterator [depr.storage.iterator]

The header <memory> has the following addition:
namespace std {
  template <class OutputIterator, class T>
  class raw_storage_iterator {
  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;

    explicit raw_storage_iterator(OutputIterator x);

    raw_storage_iterator& operator*();
    raw_storage_iterator& operator=(const T& element);
    raw_storage_iterator& operator=(T&& element);
    raw_storage_iterator& operator++();
    raw_storage_iterator  operator++(int);
    OutputIterator base() const;
  };
}
raw_­storage_­iterator is provided to enable algorithms to store their results into uninitialized memory.
The template parameter OutputIterator is required to have its operator* return an object for which operator& is defined and returns a pointer to T, and is also required to satisfy the requirements of an output iterator ([output.iterators]).
explicit raw_storage_iterator(OutputIterator x);
Effects: Initializes the iterator to point to the same value to which x points.
raw_storage_iterator& operator*();
Returns: *this
raw_storage_iterator& operator=(const T& element);
Requires: T shall be CopyConstructible.
Effects: Constructs a value from element at the location to which the iterator points.
Returns: A reference to the iterator.
raw_storage_iterator& operator=(T&& element);
Requires: T shall be MoveConstructible.
Effects: Constructs a value from std​::​move(element) at the location to which the iterator points.
Returns: A reference to the iterator.
raw_storage_iterator& operator++();
Effects: Pre-increment: advances the iterator and returns a reference to the updated iterator.
raw_storage_iterator operator++(int);
Effects: Post-increment: advances the iterator and returns the old value of the iterator.
OutputIterator base() const;
Returns: An iterator of type OutputIterator that points to the same value as *this points to.

D.11 Temporary buffers [depr.temporary.buffer]

The header <memory> has the following additions:
namespace std {
  template <class T>
    pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
  template <class T>
    void return_temporary_buffer(T* p);
}
template <class T> pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
Effects: Obtains a pointer to uninitialized, contiguous storage for N adjacent objects of type T, for some non-negative number N.
It is implementation-defined whether over-aligned types are supported ([basic.align]).
Remarks: Calling get_­temporary_­buffer with a positive number n is a non-binding request to return storage for n objects of type T.
In this case, an implementation is permitted to return instead storage for a non-negative number N of such objects, where N != n (including N == 0).
[Note
:
The request is non-binding to allow latitude for implementation-specific optimizations of its memory management.
end note
]
Returns: If n <= 0 or if no storage could be obtained, returns a pair P such that P.first is a null pointer value and P.second == 0; otherwise returns a pair P such that P.first refers to the address of the uninitialized storage and P.second refers to its capacity N (in the units of sizeof(T)).
template <class T> void return_temporary_buffer(T* p);
Effects: Deallocates the storage referenced by p.
Requires: p shall be a pointer value returned by an earlier call to get_­temporary_­buffer that has not been invalidated by an intervening call to return_­temporary_­buffer(T*).
Throws: Nothing.

D.12 Deprecated type traits [depr.meta.types]

The header <type_­traits> has the following addition:
namespace std {
  template <class T> struct is_literal_type;

  template <class T> constexpr bool is_literal_type_v = is_literal_type<T>::value;

  template <class> struct result_of; // not defined
  template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>;

  template <class T> using result_of_t = typename result_of<T>::type;
}
Requires: For is_­literal_­type, remove_­all_­extents_­t<T> shall be a complete type or cv void.
For result_­of<Fn(ArgTypes...)>, Fn and all types in the parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound.
is_­literal_­type<T> is a UnaryTypeTrait ([meta.rqmts]) with a base characteristic of true_­type if T is a literal type ([basic.types]), and false_­type otherwise.
The partial specialization result_­of<Fn(ArgTypes...)> is a TransformationTrait whose member typedef type is defined if and only if invoke_­result<Fn, ArgTypes...>​::​type is defined.
If type is defined, it names the same type as invoke_­result_­t<Fn, ArgTypes...>.
The behavior of a program that adds specializations for is_­literal_­type or is_­literal_­type_­v is undefined.

D.13 Deprecated iterator primitives [depr.iterator.primitives]

D.13.1 Basic iterator [depr.iterator.basic]

The header <iterator> has the following addition:
namespace std {
  template<class Category, class T, class Distance = ptrdiff_t,
    class Pointer = T*, class Reference = T&>
  struct iterator {
    using iterator_category = Category;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = Pointer;
    using reference         = Reference;
  };
}
The iterator template may be used as a base class to ease the definition of required types for new iterators.
[Note
:
If the new iterator type is a class template, then these aliases will not be visible from within the iterator class's template definition, but only to callers of that class.
end note
]
[Example
:
If a C++ program wants to define a bidirectional iterator for some data structure containing double and such that it works on a large memory model of the implementation, it can do so with:
class MyIterator :
  public iterator<bidirectional_iterator_tag, double, long, T*, T&> {
  // code implementing ++, etc.
};
end example
]

D.14 Deprecated shared_­ptr observers [depr.util.smartptr.shared.obs]

The following member is defined in addition to those members specified in [util.smartptr.shared]:
namespace std {
  template<class T> class shared_ptr {
  public:
    bool unique() const noexcept;
  };
}
bool unique() const noexcept;
Returns: use_­count() == 1.

D.15 Deprecated standard code conversion facets [depr.locale.stdcvt]

The header <codecvt> provides code conversion facets for various character encodings.

D.15.1 Header <codecvt> synopsis [depr.codecvt.syn]

namespace std {
  enum codecvt_mode {
    consume_header = 4,
    generate_header = 2,
    little_endian = 1
  };

  template <class Elem, unsigned long Maxcode = 0x10ffff, codecvt_mode Mode = (codecvt_mode)0>
    class codecvt_utf8 : public codecvt<Elem, char, mbstate_t> {
    public:
      explicit codecvt_utf8(size_t refs = 0);
      ~codecvt_utf8();
    };

  template <class Elem, unsigned long Maxcode = 0x10ffff, codecvt_mode Mode = (codecvt_mode)0>
    class codecvt_utf16 : public codecvt<Elem, char, mbstate_t> {
    public:
      explicit codecvt_utf16(size_t refs = 0);
      ~codecvt_utf16();
    };

  template <class Elem, unsigned long Maxcode = 0x10ffff, codecvt_mode Mode = (codecvt_mode)0>
    class codecvt_utf8_utf16 : public codecvt<Elem, char, mbstate_t> {
    public:
      explicit codecvt_utf8_utf16(size_t refs = 0);
      ~codecvt_utf8_utf16();
    };
}

D.15.2 Requirements [depr.locale.stdcvt.req]

For each of the three code conversion facets codecvt_­utf8, codecvt_­utf16, and codecvt_­utf8_­utf16:
  • Elem is the wide-character type, such as wchar_­t, char16_­t, or char32_­t.
  • Maxcode is the largest wide-character code that the facet will read or write without reporting a conversion error.
  • If (Mode & consume_­header), the facet shall consume an initial header sequence, if present, when reading a multibyte sequence to determine the endianness of the subsequent multibyte sequence to be read.
  • If (Mode & generate_­header), the facet shall generate an initial header sequence when writing a multibyte sequence to advertise the endianness of the subsequent multibyte sequence to be written.
  • If (Mode & little_­endian), the facet shall generate a multibyte sequence in little-endian order, as opposed to the default big-endian order.
For the facet codecvt_­utf8:
  • The facet shall convert between UTF-8 multibyte sequences and UCS2 or UCS4 (depending on the size of Elem) within the program.
  • Endianness shall not affect how multibyte sequences are read or written.
  • The multibyte sequences may be written as either a text or a binary file.
For the facet codecvt_­utf16:
  • The facet shall convert between UTF-16 multibyte sequences and UCS2 or UCS4 (depending on the size of Elem) within the program.
  • Multibyte sequences shall be read or written according to the Mode flag, as set out above.
  • The multibyte sequences may be written only as a binary file.
    Attempting to write to a text file produces undefined behavior.
For the facet codecvt_­utf8_­utf16:
  • The facet shall convert between UTF-8 multibyte sequences and UTF-16 (one or two 16-bit codes) within the program.
  • Endianness shall not affect how multibyte sequences are read or written.
  • The multibyte sequences may be written as either a text or a binary file.
See also: ISO/IEC 10646-1:1993.

D.16 Deprecated convenience conversion interfaces [depr.conversions]

The header <locale> has the following additions:
namespace std {
  template <class Codecvt, class Elem = wchar_t,
            class Wide_alloc = allocator<Elem>,
            class Byte_alloc = allocator<char>>
    class wstring_convert;

  template <class Codecvt, class Elem = wchar_t,
            class Tr = char_traits<Elem>>
    class wbuffer_convert;
}

D.16.1 Class template wstring_­convert [depr.conversions.string]

Class template wstring_­convert performs conversions between a wide string and a byte string.
It lets you specify a code conversion facet (like class template codecvt) to perform the conversions, without affecting any streams or locales.
[Example
:
If you want to use the code conversion facet codecvt_­utf8 to output to cout a UTF-8 multibyte sequence corresponding to a wide string, but you don't want to alter the locale for cout, you can write something like:
wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
std::string mbstring = myconv.to_bytes(L"Hello\n");
std::cout << mbstring;
end example
]
namespace std {
  template <class Codecvt, class Elem = wchar_t,
            class Wide_alloc = allocator<Elem>,
            class Byte_alloc = allocator<char>>
    class wstring_convert {
    public:
      using byte_string = basic_string<char, char_traits<char>, Byte_alloc>;
      using wide_string = basic_string<Elem, char_traits<Elem>, Wide_alloc>;
      using state_type  = typename Codecvt::state_type;
      using int_type    = typename wide_string::traits_type::int_type;

      explicit wstring_convert(Codecvt* pcvt = new Codecvt);
      wstring_convert(Codecvt* pcvt, state_type state);
      explicit wstring_convert(const byte_string& byte_err,
                               const wide_string& wide_err = wide_string());
      ~wstring_convert();

      wstring_convert(const wstring_convert&) = delete;
      wstring_convert& operator=(const wstring_convert&) = delete;

      wide_string from_bytes(char byte);
      wide_string from_bytes(const char* ptr);
      wide_string from_bytes(const byte_string& str);
      wide_string from_bytes(const char* first, const char* last);

      byte_string to_bytes(Elem wchar);
      byte_string to_bytes(const Elem* wptr);
      byte_string to_bytes(const wide_string& wstr);
      byte_string to_bytes(const Elem* first, const Elem* last);

      size_t converted() const noexcept;
      state_type state() const;

    private:
      byte_string byte_err_string;  // exposition only
      wide_string wide_err_string;  // exposition only
      Codecvt* cvtptr;              // exposition only
      state_type cvtstate;          // exposition only
      size_t cvtcount;              // exposition only
    };
}
The class template describes an object that controls conversions between wide string objects of class basic_­string<Elem, char_­traits<Elem>, Wide_­alloc> and byte string objects of class basic_­string<char, char_­traits<char>, Byte_­alloc>.
The class template defines the types wide_­string and byte_­string as synonyms for these two types.
Conversion between a sequence of Elem values (stored in a wide_­string object) and multibyte sequences (stored in a byte_­string object) is performed by an object of class Codecvt, which meets the requirements of the standard code-conversion facet codecvt<Elem, char, mbstate_­t>.
An object of this class template stores:
  • byte_­err_­string — a byte string to display on errors
  • wide_­err_­string — a wide string to display on errors
  • cvtptr — a pointer to the allocated conversion object (which is freed when the wstring_­convert object is destroyed)
  • cvtstate — a conversion state object
  • cvtcount — a conversion count
using byte_string = basic_string<char, char_traits<char>, Byte_alloc>;
The type shall be a synonym for basic_­string<char, char_­traits<char>, Byte_­alloc>.
size_t converted() const noexcept;
Returns: cvtcount.
wide_string from_bytes(char byte); wide_string from_bytes(const char* ptr); wide_string from_bytes(const byte_string& str); wide_string from_bytes(const char* first, const char* last);
Effects: The first member function shall convert the single-element sequence byte to a wide string.
The second member function shall convert the null-terminated sequence beginning at ptr to a wide string.
The third member function shall convert the sequence stored in str to a wide string.
The fourth member function shall convert the sequence defined by the range [first, last) to a wide string.
In all cases:
  • If the cvtstate object was not constructed with an explicit value, it shall be set to its default value (the initial conversion state) before the conversion begins.
    Otherwise it shall be left unchanged.
  • The number of input elements successfully converted shall be stored in cvtcount.
Returns: If no conversion error occurs, the member function shall return the converted wide string.
Otherwise, if the object was constructed with a wide-error string, the member function shall return the wide-error string.
Otherwise, the member function throws an object of class range_­error.
using int_type = typename wide_string::traits_type::int_type;
The type shall be a synonym for wide_­string​::​traits_­type​::​int_­type.
state_type state() const;
returns cvtstate.
using state_type = typename Codecvt::state_type;
The type shall be a synonym for Codecvt​::​state_­type.
byte_string to_bytes(Elem wchar); byte_string to_bytes(const Elem* wptr); byte_string to_bytes(const wide_string& wstr); byte_string to_bytes(const Elem* first, const Elem* last);
Effects: The first member function shall convert the single-element sequence wchar to a byte string.
The second member function shall convert the null-terminated sequence beginning at wptr to a byte string.
The third member function shall convert the sequence stored in wstr to a byte string.
The fourth member function shall convert the sequence defined by the range [first, last) to a byte string.
In all cases:
  • If the cvtstate object was not constructed with an explicit value, it shall be set to its default value (the initial conversion state) before the conversion begins.
    Otherwise it shall be left unchanged.
  • The number of input elements successfully converted shall be stored in cvtcount.
Returns: If no conversion error occurs, the member function shall return the converted byte string.
Otherwise, if the object was constructed with a byte-error string, the member function shall return the byte-error string.
Otherwise, the member function shall throw an object of class range_­error.
using wide_string = basic_string<Elem, char_traits<Elem>, Wide_alloc>;
The type shall be a synonym for basic_­string<Elem, char_­traits<Elem>, Wide_­alloc>.
explicit wstring_convert(Codecvt* pcvt = new Codecvt); wstring_convert(Codecvt* pcvt, state_type state); explicit wstring_convert(const byte_string& byte_err, const wide_string& wide_err = wide_string());
Requires: For the first and second constructors, pcvt != nullptr.
Effects: The first constructor shall store pcvt in cvtptr and default values in cvtstate, byte_­err_­string, and wide_­err_­string.
The second constructor shall store pcvt in cvtptr, state in cvtstate, and default values in byte_­err_­string and wide_­err_­string; moreover the stored state shall be retained between calls to from_­bytes and to_­bytes.
The third constructor shall store new Codecvt in cvtptr, state_­type() in cvtstate, byte_­err in byte_­err_­string, and wide_­err in wide_­err_­string.
~wstring_convert();
Effects: The destructor shall delete cvtptr.

D.16.2 Class template wbuffer_­convert [depr.conversions.buffer]

Class template wbuffer_­convert looks like a wide stream buffer, but performs all its I/O through an underlying byte stream buffer that you specify when you construct it.
Like class template wstring_­convert, it lets you specify a code conversion facet to perform the conversions, without affecting any streams or locales.
namespace std {
  template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
    class wbuffer_convert : public basic_streambuf<Elem, Tr> {
    public:
      using state_type = typename Codecvt::state_type;

      explicit wbuffer_convert(streambuf* bytebuf = 0,
                               Codecvt* pcvt = new Codecvt,
                               state_type state = state_type());

      ~wbuffer_convert();

      wbuffer_convert(const wbuffer_convert&) = delete;
      wbuffer_convert& operator=(const wbuffer_convert&) = delete;

      streambuf* rdbuf() const;
      streambuf* rdbuf(streambuf* bytebuf);

      state_type state() const;

    private:
      streambuf* bufptr;            // exposition only
      Codecvt* cvtptr;              // exposition only
      state_type cvtstate;          // exposition only
  };
}
The class template describes a stream buffer that controls the transmission of elements of type Elem, whose character traits are described by the class Tr, to and from a byte stream buffer of type streambuf.
Conversion between a sequence of Elem values and multibyte sequences is performed by an object of class Codecvt, which shall meet the requirements of the standard code-conversion facet codecvt<Elem, char, mbstate_­t>.
An object of this class template stores:
  • bufptr — a pointer to its underlying byte stream buffer
  • cvtptr — a pointer to the allocated conversion object (which is freed when the wbuffer_­convert object is destroyed)
  • cvtstate — a conversion state object
state_type state() const;
Returns: cvtstate.
streambuf* rdbuf() const;
Returns: bufptr.
streambuf* rdbuf(streambuf* bytebuf);
Effects: Stores bytebuf in bufptr.
Returns: The previous value of bufptr.
using state_type = typename Codecvt::state_type;
The type shall be a synonym for Codecvt​::​state_­type.
explicit wbuffer_convert( streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, state_type state = state_type());
Requires: pcvt != nullptr.
Effects: The constructor constructs a stream buffer object, initializes bufptr to bytebuf, initializes cvtptr to pcvt, and initializes cvtstate to state.
~wbuffer_convert();
Effects: The destructor shall delete cvtptr.