Document Number: N????
Date: 2016-11-13
Revises: N3485
Reply to: Stefanus Du Toit
Intel Corporation
cxxeditor@gmail.com
Working Draft, Standard for Programming
Language C++
Note: this is an early draft. It’s known to be incomplet and incorrekt, and it has lots of bad
formatting.
c
ISO/IEC N????
Contents
Contents ii
List of Tables x
List of Figures xiv
1 General 1
1.1 Scope ................................................ 1
1.2 Normativereferences........................................ 1
1.3 Termsanddenitions........................................ 2
1.4 Implementationcompliance .................................... 5
1.5 Structure of this International Standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6 Syntaxnotation........................................... 6
1.7 The C++ memorymodel...................................... 6
1.8 The C++ objectmodel....................................... 7
1.9 Programexecution ......................................... 8
1.10 Multi-threaded executions and data races . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.11 Acknowledgments.......................................... 15
2 Lexical conventions 16
2.1 Separatetranslation ........................................ 16
2.2 Phasesoftranslation........................................ 16
2.3 Charactersets............................................ 17
2.4 Trigraphsequences......................................... 18
2.5 Preprocessingtokens ........................................ 19
2.6 Alternativetokens ......................................... 20
2.7 Tokens................................................ 20
2.8 Comments.............................................. 20
2.9 Headernames............................................ 20
2.10 Preprocessingnumbers....................................... 21
2.11 Identiers .............................................. 21
2.12 Keywords .............................................. 22
2.13 Operatorsandpunctuators .................................... 22
2.14 Literals ............................................... 23
3 Basic concepts 32
3.1 Declarationsanddenitions .................................... 32
3.2 Onedenitionrule ......................................... 34
3.3 Scope ................................................ 37
3.4 Namelookup ............................................ 42
3.5 Programandlinkage........................................ 56
3.6 Startandtermination ....................................... 58
3.7 Storageduration .......................................... 62
3.8 Objectlifetime ........................................... 66
3.9 Types ................................................ 69
3.10 Lvaluesandrvalues......................................... 74
Contents ii
c
ISO/IEC N????
3.11 Alignment.............................................. 76
4 Standard conversions 77
4.1 Lvalue-to-rvalueconversion .................................... 78
4.2 Array-to-pointerconversion .................................... 78
4.3 Function-to-pointer conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.4 Qualicationconversions...................................... 78
4.5 Integralpromotions......................................... 80
4.6 Floatingpointpromotion ..................................... 80
4.7 Integralconversions......................................... 80
4.8 Floatingpointconversions..................................... 80
4.9 Floating-integralconversions.................................... 81
4.10 Pointerconversions......................................... 81
4.11 Pointer to member conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.12 Booleanconversions ........................................ 82
4.13 Integerconversionrank....................................... 82
5 Expressions 83
5.1 Primaryexpressions ........................................ 86
5.2 Postxexpressions ......................................... 96
5.3 Unaryexpressions..........................................107
5.4 Explicit type conversion (cast notation) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
5.5 Pointer-to-memberoperators ...................................116
5.6 Multiplicativeoperators ......................................116
5.7 Additiveoperators .........................................117
5.8 Shiftoperators ...........................................118
5.9 Relationaloperators ........................................118
5.10 Equalityoperators .........................................119
5.11 BitwiseANDoperator .......................................120
5.12 BitwiseexclusiveORoperator...................................120
5.13 BitwiseinclusiveORoperator...................................120
5.14 LogicalANDoperator .......................................120
5.15 LogicalORoperator ........................................120
5.16 Conditionaloperator........................................121
5.17 Assignment and compound assignment operators . . . . . . . . . . . . . . . . . . . . . . . . 122
5.18 Commaoperator ..........................................123
5.19 Constantexpressions........................................123
6 Statements 127
6.1 Labeledstatement .........................................127
6.2 Expressionstatement........................................127
6.3 Compoundstatementorblock...................................127
6.4 Selectionstatements ........................................128
6.5 Iterationstatements ........................................129
6.6 Jumpstatements ..........................................132
6.7 Declarationstatement .......................................133
6.8 Ambiguityresolution........................................134
7 Declarations 136
7.1 Speciers ..............................................137
7.2 Enumerationdeclarations .....................................154
Contents iii
c
ISO/IEC N????
7.3 Namespaces.............................................157
7.4 The asm declaration ........................................170
7.5 Linkagespecications .......................................170
7.6 Attributes..............................................173
8 Declarators 177
8.1 Typenames.............................................178
8.2 Ambiguityresolution........................................179
8.3 Meaningofdeclarators.......................................180
8.4 Functiondenitions.........................................192
8.5 Initializers..............................................195
9 Classes 210
9.1 Classnames.............................................212
9.2 Classmembers ...........................................214
9.3 Memberfunctions..........................................216
9.4 Staticmembers ...........................................219
9.5 Unions................................................220
9.6 Bit-elds...............................................222
9.7 Nestedclassdeclarations......................................222
9.8 Localclassdeclarations ......................................224
9.9 Nestedtypenames .........................................224
10 Derived classes 225
10.1 Multiplebaseclasses ........................................226
10.2 Membernamelookup .......................................228
10.3 Virtualfunctions ..........................................231
10.4 Abstractclasses...........................................235
11 Member access control 237
11.1 Accessspeciers...........................................238
11.2 Accessibility of base classes and base class members . . . . . . . . . . . . . . . . . . . . . . . 239
11.3 Friends................................................242
11.4 Protectedmemberaccess......................................245
11.5 Accesstovirtualfunctions.....................................246
11.6 Multipleaccess ...........................................246
11.7 Nestedclasses............................................246
12 Special member functions 248
12.1 Constructors ............................................248
12.2 Temporaryobjects .........................................250
12.3 Conversions .............................................252
12.4 Destructors .............................................255
12.5 Freestore ..............................................258
12.6 Initialization.............................................260
12.7 Constructionanddestruction ...................................265
12.8 Copying and moving class objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
12.9 Inheritingconstructors.......................................275
13 Overloading 279
13.1 Overloadabledeclarations .....................................279
Contents iv
c
ISO/IEC N????
13.2 Declarationmatching........................................281
13.3 Overloadresolution.........................................282
13.4 Address of overloaded function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
13.5 Overloadedoperators........................................302
13.6 Built-inoperators..........................................306
14 Templates 310
14.1 Templateparameters........................................311
14.2 Names of template specializations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
14.3 Templatearguments ........................................316
14.4 Typeequivalence ..........................................322
14.5 Templatedeclarations .......................................323
14.6 Nameresolution...........................................339
14.7 Template instantiation and specialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
14.8 Function template specializations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
15 Exception handling 386
15.1 Throwinganexception.......................................387
15.2 Constructors and destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
15.3 Handlinganexception .......................................389
15.4 Exceptionspecications ......................................391
15.5 Specialfunctions ..........................................394
16 Preprocessing directives 397
16.1 Conditionalinclusion........................................398
16.2 Sourceleinclusion.........................................399
16.3 Macroreplacement .........................................400
16.4 Linecontrol.............................................405
16.5 Errordirective ...........................................406
16.6 Pragmadirective ..........................................406
16.7 Nulldirective ............................................406
16.8 Predenedmacronames......................................406
16.9 Pragmaoperator ..........................................407
17 Library introduction 408
17.1 General ...............................................408
17.2 TheCstandardlibrary.......................................409
17.3 Denitions..............................................409
17.4 Additionaldenitions........................................412
17.5 Method of description (Informative) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
17.6 Library-widerequirements.....................................417
18 Language support library 436
18.1 General ...............................................436
18.2 Types ................................................436
18.3 Implementationproperties.....................................437
18.4 Integertypes ............................................446
18.5 Startandtermination .......................................448
18.6 Dynamicmemorymanagement ..................................449
18.7 Typeidentication .........................................455
18.8 Exceptionhandling.........................................457
Contents v
c
ISO/IEC N????
18.9 Initializerlists............................................462
18.10 Otherruntimesupport.......................................463
19 Diagnostics library 466
19.1 General ...............................................466
19.2 Exceptionclasses ..........................................466
19.3 Assertions..............................................470
19.4 Errornumbers ...........................................470
19.5 Systemerrorsupport........................................470
20 General utilities library 482
20.1 General ...............................................482
20.2 Utilitycomponents.........................................482
20.3 Pairs.................................................487
20.4 Tuples ................................................492
20.5 Compile-time integer sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
20.6 Optionalobjects ..........................................503
20.7 Class template bitset .......................................513
20.8 Memory ...............................................520
20.9 Smartpointers ...........................................535
20.10 Functionobjects ..........................................562
20.11 Metaprogramming and type traits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
20.12 Compile-time rational arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
20.13 Timeutilities ............................................606
20.14 Class template scoped_allocator_adaptor ...........................622
20.15 Class type_index ..........................................629
21 Strings library 631
21.1 General ...............................................631
21.2 Charactertraits...........................................631
21.3 Stringclasses ............................................637
21.4 Class template basic_string ...................................641
21.5 Numericconversions ........................................669
21.6 Hashsupport ............................................671
21.7 Suffix for basic_string literals..................................671
21.8 Null-terminated sequence utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671
22 Localization library 675
22.1 General ...............................................675
22.2 Header <locale> synopsis.....................................675
22.3 Locales................................................676
22.4 Standard locale categories ....................................689
22.5 Standard code conversion facets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729
22.6 Clibrarylocales ..........................................731
23 Containers library 732
23.1 General ...............................................732
23.2 Containerrequirements.......................................732
23.3 Sequencecontainers ........................................760
23.4 Associativecontainers .......................................794
23.5 Unordered associative containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812
Contents vi
c
ISO/IEC N????
23.6 Containeradaptors.........................................829
24 Iterators library 839
24.1 General ...............................................839
24.2 Iteratorrequirements........................................839
24.3 Header <iterator> synopsis....................................844
24.4 Iteratorprimitives .........................................847
24.5 Iteratoradaptors ..........................................851
24.6 Streamiterators...........................................864
24.7 rangeaccess.............................................871
25 Algorithms library 873
25.1 General ...............................................873
25.2 Non-modifying sequence operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 884
25.3 Mutating sequence operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 889
25.4 Sorting and related operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 897
25.5 Clibraryalgorithms ........................................910
26 Numerics library 912
26.1 General ...............................................912
26.2 Numerictyperequirements ....................................912
26.3 The floating-point environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
26.4 Complexnumbers..........................................914
26.5 Randomnumbergeneration ....................................924
26.6 Numericarrays ...........................................969
26.7 Generalized numeric operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 990
26.8 Clibrary...............................................993
27 Input/output library 998
27.1 General ...............................................998
27.2 Iostreamsrequirements.......................................998
27.3 Forwarddeclarations........................................999
27.4 Standardiostreamobjects .....................................1001
27.5 Iostreamsbaseclasses .......................................1003
27.6 Streambuers............................................1022
27.7 Formattingandmanipulators ...................................1032
27.8 String-basedstreams........................................1061
27.9 File-basedstreams .........................................1072
28 Regular expressions library 1088
28.1 General ...............................................1088
28.2 Denitions..............................................1088
28.3 Requirements ............................................1089
28.4 Header <regex> synopsis......................................1091
28.5 Namespace std::regex_constants ................................1097
28.6 Class regex_error .........................................1101
28.7 Class template regex_traits ...................................1101
28.8 Class template basic_regex ....................................1104
28.9 Class template sub_match .....................................1109
28.10 Class template match_results ..................................1116
28.11 Regular expression algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1122
Contents vii
c
ISO/IEC N????
28.12 Regularexpressioniterators ....................................1126
28.13 Modified ECMAScript regular expression grammar . . . . . . . . . . . . . . . . . . . . . . . 1132
29 Atomic operations library 1135
29.1 General ...............................................1135
29.2 Header <atomic> synopsis.....................................1135
29.3 Orderandconsistency .......................................1138
29.4 Lock-freeproperty .........................................1141
29.5 Atomictypes ............................................1141
29.6 Operationsonatomictypes ....................................1144
29.7 Flagtypeandoperations......................................1150
29.8 Fences ................................................1151
30 Thread support library 1153
30.1 General ...............................................1153
30.2 Requirements ............................................1153
30.3 Threads ...............................................1156
30.4 Mutualexclusion ..........................................1161
30.5 Conditionvariables.........................................1181
30.6 Futures ...............................................1190
A Grammar summary 1207
A.1 Keywords ..............................................1207
A.2 Lexicalconventions.........................................1207
A.3 Basicconcepts............................................1211
A.4 Expressions .............................................1212
A.5 Statements .............................................1215
A.6 Declarations.............................................1216
A.7 Declarators .............................................1220
A.8 Classes................................................1222
A.9 Derivedclasses ...........................................1222
A.10 Specialmemberfunctions .....................................1223
A.11 Overloading.............................................1223
A.12 Templates..............................................1223
A.13 Exceptionhandling.........................................1224
A.14 Preprocessingdirectives ......................................1225
B Implementation quantities 1227
C Compatibility 1229
C.1 C++ andISOC...........................................1229
C.2 C++ and ISO C++ 2003 ......................................1237
C.3 C++ and ISO C++ 2011 ......................................1244
C.4 Cstandardlibrary .........................................1244
D Compatibility features 1248
D.1 Increment operator with bool operand..............................1248
D.2 register keyword .........................................1248
D.3 Implicit declaration of copy functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1248
D.4 Dynamic exception specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1248
D.5 Cstandardlibraryheaders.....................................1248
Contents viii
c
ISO/IEC N????
D.6 Oldiostreamsmembers ......................................1248
D.7 char* streams............................................1250
D.8 Functionobjects ..........................................1259
D.9 Binders ...............................................1263
D.10 auto_ptr ..............................................1264
D.11 Violating exception-specifications .................................1267
E Universal character names for identifier characters 1268
E.1 Rangesofcharactersallowed....................................1268
E.2 Ranges of characters disallowed initially . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1268
F Cross references 1269
Index 1287
Index of grammar productions 1316
Index of library names 1319
Index of implementation-defined behavior 1356
Contents ix
c
ISO/IEC N????
List of Tables
1 Trigraphsequences............................................ 18
2 Alternativetokens ............................................ 20
3 Identierswithspecialmeaning..................................... 22
4 Keywords ................................................. 22
5 Alternativerepresentations ....................................... 22
6 Typesofintegerconstants........................................ 24
7 Escapesequences............................................. 26
8 Stringliteralconcatenations....................................... 29
9 Relations on const and volatile ................................... 74
10 simple-type-specifiers and the types they specify . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
11 Relationship between operator and function call notation . . . . . . . . . . . . . . . . . . . . . . 287
12 Conversions................................................295
13 Librarycategories ............................................408
14 C++ libraryheaders ...........................................418
15 C++ headersforClibraryfacilities...................................418
16 C++ headers for freestanding implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
17 EqualityComparable requirements...................................420
18 LessThanComparable requirements...................................420
19 DefaultConstructible requirements .................................421
20 MoveConstructible requirements ...................................421
21 CopyConstructible requirements (in addition to MoveConstructible) ..............421
22 MoveAssignable requirements .....................................421
23 CopyAssignable requirements (in addition to MoveAssignable) ..................421
24 Destructible requirements.......................................421
25 NullablePointer requirements.....................................423
26 Hash requirements ............................................424
27 Descriptivevariabledenitions .....................................424
28 Allocatorrequirements..........................................425
29 Language support library summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
30 Header <cstddef> synopsis .......................................436
31 Header <climits> synopsis .......................................446
32 Header <cfloat> synopsis........................................446
33 Header <cstdlib> synopsis .......................................448
34 Header <csetjmp> synopsis .......................................464
35 Header <csignal> synopsis .......................................464
36 Header <cstdalign> synopsis......................................464
37 Header <cstdarg> synopsis .......................................465
38 Header <cstdbool> synopsis ......................................465
39 Header <cstdlib> synopsis .......................................465
40 Header <ctime> synopsis ........................................465
List of Tables x
c
ISO/IEC N????
41 Diagnosticslibrarysummary ......................................466
42 Header <cassert> synopsis .......................................470
43 Header <cerrno> synopsis........................................471
44 General utilities library summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
45 Header <cstdlib> synopsis .......................................535
46 Header <cstring> synopsis .......................................535
47 Primarytypecategorypredicates....................................589
48 Composite type category predicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
49 Typepropertypredicates ........................................590
50 Typepropertyqueries ..........................................596
51 Typerelationshippredicates.......................................596
52 Const-volatilemodications.......................................598
53 Referencemodications .........................................598
54 Signmodications ............................................599
55 Arraymodications ...........................................600
56 Pointermodications...........................................600
57 Othertransformations ..........................................601
58 Expressions used to perform ratio arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605
59 Clockrequirements............................................609
60 Header <ctime> synopsis ........................................622
61 Stringslibrarysummary.........................................631
62 Charactertraitsrequirements......................................632
63 basic_string(const Allocator&) eects ..............................645
64 basic_string(const basic_string&) eects ............................646
65 basic_string(const basic_string&, size_type, size_type, const Allocator&) effects . 646
66 basic_string(const charT*, size_type, const Allocator&) eects..............647
67 basic_string(const charT*, const Allocator&) eects.....................647
68 basic_string(size_t, charT, const Allocator&) eects ....................647
69 basic_string(const basic_string&, const Allocator&) and basic_string(basic_string&&,
const Allocator&) eects .......................................648
70 operator=(const basic_string&) eects ..............................648
71 operator=(basic_string&&) eects..................................649
72 compare() results ............................................663
73 Potential mbstate_t dataraces.....................................673
74 Header <cctype> synopsis........................................673
75 Header <cwctype> synopsis .......................................673
76 Header <cstring> synopsis .......................................673
77 Header <cwchar> synopsis........................................674
78 Header <cstdlib> synopsis .......................................674
79 Header <cuchar> synopsis........................................674
80 Localizationlibrarysummary......................................675
81 Localecategoryfacets ..........................................679
82 Requiredspecializations .........................................679
83 do_in/do_out resultvalues .......................................699
84 do_unshift resultvalues ........................................699
85 Integerconversions............................................703
86 Lengthmodier..............................................703
87 Integerconversions............................................707
List of Tables xi
c
ISO/IEC N????
88 Floating-pointconversions........................................707
89 Lengthmodier..............................................708
90 Numericconversions ...........................................708
91 Fillpadding................................................709
92 do_get_date eects ...........................................716
93 Header <clocale> synopsis .......................................731
94 Potential setlocale dataraces.....................................731
95 Containerslibrarysummary.......................................732
96 Containerrequirements .........................................733
97 Reversible container requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735
98 Optionalcontaineroperations......................................736
99 Allocator-aware container requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737
100 Sequence container requirements (in addition to container) . . . . . . . . . . . . . . . . . . . . . 739
101 Optional sequence container operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742
102 Associative container requirements (in addition to container) . . . . . . . . . . . . . . . . . . . . 744
103 Unordered associative container requirements (in addition to container) . . . . . . . . . . . . . . 751
104 Iteratorslibrarysummary........................................839
105 Relations among iterator categories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839
106 Iteratorrequirements...........................................840
107 Input iterator requirements (in addition to Iterator) . . . . . . . . . . . . . . . . . . . . . . . . . 841
108 Output iterator requirements (in addition to Iterator) . . . . . . . . . . . . . . . . . . . . . . . . 842
109 Forward iterator requirements (in addition to input iterator) . . . . . . . . . . . . . . . . . . . . 843
110 Bidirectional iterator requirements (in addition to forward iterator) . . . . . . . . . . . . . . . . . 843
111 Random access iterator requirements (in addition to bidirectional iterator) . . . . . . . . . . . . 844
112 Algorithmslibrarysummary ......................................873
113 Header <cstdlib> synopsis .......................................910
114 Numericslibrarysummary .......................................912
115 Seedsequencerequirements .......................................926
116 Uniform random number generator requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
117 Random number engine requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 928
118 Random number distribution requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931
119 Header <cmath> synopsis ........................................994
120 Header <cstdlib> synopsis .......................................994
121 Input/outputlibrarysummary .....................................998
122 fmtflags eects .............................................1008
123 fmtflags constants ...........................................1008
124 iostate eects..............................................1008
125 openmode eects .............................................1008
126 seekdir eects..............................................1009
127 Positiontyperequirements .......................................1013
128 basic_ios::init() eects .......................................1015
129 basic_ios::copyfmt() eects .....................................1017
130 seekoff positioning ...........................................1065
131 newoff values...............................................1065
132 Fileopenmodes .............................................1075
133 seekoff eects..............................................1078
List of Tables xii
c
ISO/IEC N????
134 Header <cstdio> synopsis........................................1086
135 Header <cinttypes> synopsis......................................1086
136 Regular expressions library summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1088
137 Regular expression traits class requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1089
138 syntax_option_type eects ......................................1098
139 regex_constants::match_flag_type effects when obtaining a match against a character con-
tainer sequence [first,last). .....................................1099
140 error_type valuesintheClocale ...................................1100
141 match_results assignmentoperatoreects ..............................1118
142 Effects of regex_match algorithm ...................................1122
143 Effects of regex_search algorithm...................................1124
144 Atomicslibrarysummary ........................................1135
145 atomic integraltypedefs.........................................1144
146 atomic <inttypes.h> typedefs.....................................1145
147 Atomic arithmetic computations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1149
148 Threadsupportlibrarysummary....................................1153
149 Standardmacros .............................................1244
150 Standardvalues..............................................1245
151 Standardtypes ..............................................1245
152 Standardstructs .............................................1245
153 Standardfunctions............................................1246
154 Cheaders.................................................1248
155 strstreambuf(streamsize) eects ..................................1252
156 strstreambuf(void* (*)(size_t), void (*)(void*)) eects ..................1252
157 strstreambuf(charT*, streamsize, charT*) eects........................1252
158 seekoff positioning ...........................................1255
159 newoff values...............................................1255
List of Tables xiii
c
ISO/IEC N????
List of Figures
1 Expressioncategorytaxonomy ..................................... 74
2 Directedacyclicgraph..........................................226
3 Non-virtualbase .............................................227
4 Virtualbase................................................228
5 Virtualandnon-virtualbase ......................................228
6 Namelookup ...............................................230
7 Stream position, offset, and size types [non-normative] . . . . . . . . . . . . . . . . . . . . . . . . 998
List of Figures xiv
c
ISO/IEC N????
1 General [intro]
1.1 Scope [intro.scope]
1This International Standard specifies requirements for implementations of the C++ programming language.
The first such requirement is that they implement the language, and so this International Standard also
defines C++. Other requirements and relaxations of the first requirement appear at various places within
this International Standard.
2C++ is a general purpose programming language based on the C programming language as described in
ISO/IEC 9899:1999 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.
1.2 Normative references [intro.refs]
1The following referenced documents are indispensable for the application of this document. For dated refer-
ences, 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:1999, Programming languages — C
ISO/IEC 9899:1999/Cor.1:2001(E), Programming languages — C, Technical Corrigendum 1
ISO/IEC 9899:1999/Cor.2:2004(E), Programming languages — C, Technical Corrigendum 2
ISO/IEC 9899:1999/Cor.3:2007(E), Programming languages — C, Technical Corrigendum 3
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 TR 19769:2004, Information technology — Programming languages, their environments and
system software interfaces — Extensions for the programming language C to support new character
data types
2The library described in Clause 7 of ISO/IEC 9899:1999 and Clause 7 of ISO/IEC 9899:1999/Cor.1:2001
and Clause 7 of ISO/IEC 9899:1999/Cor.2:2003 is hereinafter called the C standard library.1
3The library described in ISO/IEC TR 19769:2004 is hereinafter called the C Unicode TR.
4The operating system interface described in ISO/IEC 9945:2003 is hereinafter called POSIX.
5The ECMAScript Language Specification described in Standard Ecma-262 is hereinafter called ECMA-262 .
1) With the qualifications noted in Clauses 18 through 30 and in C.4, the C standard library is a subset of the C++ standard
library.
§ 1.2 1
c
ISO/IEC N????
1.3 Terms and definitions [intro.defs]
1For the purposes of this document, the following definitions apply.
217.3 defines additional terms that are used only in Clauses 17 through 30 and Annex D.
3Terms that are used only in a small portion of this International Standard are defined where they are used
and italicized where they are defined.
1.3.1 [defns.argument]
argument
actual argument
actual parameter
<function call expression> expression in the comma-separated list bounded by the parentheses
1.3.2 [defns.argument.macro]
argument
actual argument
actual parameter
<function-like macro> sequence of preprocessing tokens in the comma-separated list bounded by the paren-
theses
1.3.3 [defns.argument.throw]
argument
actual argument
actual parameter
<throw expression> the operand of throw
1.3.4 [defns.argument.templ]
argument
actual argument
actual parameter
<template instantiation> expression, type-id or template-name in the comma-separated list bounded by the
angle brackets
1.3.5 [defns.cond.supp]
conditionally-supported
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 ]
1.3.6 [defns.diagnostic]
diagnostic message
message belonging to an implementation-defined subset of the implementation’s output messages
1.3.7 [defns.dynamic.type]
dynamic type
<glvalue> type of the most derived object (1.8) to which the glvalue denoted by a glvalue expression refers
[Example: if a pointer (8.3.1)pwhose static type is “pointer to class B” is pointing to an object of class
D, derived from B(Clause 10), the dynamic type of the expression *p is “D.” References (8.3.2) are treated
similarly. — end example ]
1.3.8 [defns.dynamic.type.prvalue]
§ 1.3 2
c
ISO/IEC N????
dynamic type
<prvalue> static type of the prvalue expression
1.3.9 [defns.ill.formed]
ill-formed program
program that is not well formed
1.3.10 [defns.impl.defined]
implementation-defined behavior
behavior, for a well-formed program construct and correct data, that depends on the implementation and
that each implementation documents
1.3.11 [defns.impl.limits]
implementation limits
restrictions imposed upon programs by the implementation
1.3.12 [defns.locale.specific]
locale-specific behavior
behavior that depends on local conventions of nationality, culture, and language that each implementation
documents
1.3.13 [defns.multibyte]
multibyte character
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 (2.3). — end note ]
1.3.14 [defns.parameter]
parameter
formal argument
formal 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
1.3.15 [defns.parameter.macro]
parameter
formal argument
formal parameter
<function-like macro> identifier from the comma-separated list bounded by the parentheses immediately
following the macro name
1.3.16 [defns.parameter.templ]
parameter
formal argument
formal parameter
<template> template-parameter
1.3.17 [defns.signature]
signature
§ 1.3 3
c
ISO/IEC N????
<function> name, parameter type list (8.3.5), and enclosing namespace (if any)
[Note: Signatures are used as a basis for name mangling and linking. — end note ]
1.3.18 [defns.signature.templ]
signature
<function template> name, parameter type list (8.3.5), enclosing namespace (if any), return type, and
template parameter list
1.3.19 [defns.signature.spec]
signature
<function template specialization> signature of the template of which it is a specialization and its template
arguments (whether explicitly specified or deduced)
1.3.20 [defns.signature.member]
signature
<class member function> name, parameter type list (8.3.5), class of which the function is a member, cv-
qualifiers (if any), and ref-qualifier (if any)
1.3.21 [defns.signature.member.templ]
signature
<class member function template> name, parameter type list (8.3.5), class of which the function is a member,
cv-qualifiers (if any), ref-qualifier (if any), return type, and template parameter list
1.3.22 [defns.signature.member.spec]
signature
<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)
1.3.23 [defns.static.type]
static type
type of an expression (3.9) 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 ]
1.3.24 [defns.undefined]
undefined behavior
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.
— end note ]
1.3.25 [defns.unspecified]
unspecified behavior
behavior, for a well-formed program construct and correct data, that depends on the implementation
§ 1.3 4
c
ISO/IEC N????
[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 ]
1.3.26 [defns.well.formed]
well-formed program
C++ program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition
Rule (3.2).
1.4 Implementation compliance [intro.compliance]
1The 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.
2Although 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 imple-
mentation shall, within its resource limits, accept and correctly execute2that program.
If a program contains a violation of any diagnosable rule or an occurrence of a construct described in
this 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.
3For classes and class templates, the library Clauses specify partial definitions. Private members (Clause 11)
are not specified, but each implementation shall supply them to complete the definitions according to the
description in the library Clauses.
4For functions, function templates, objects, and values, the library Clauses specify declarations. Implemen-
tations shall supply definitions consistent with the descriptions in the library Clauses.
5The names defined in the library have namespace scope (7.3). A C++ translation unit (2.2) obtains access
to these names by including the appropriate standard library header (16.2).
6The templates, classes, functions, and objects in the library have external linkage (3.5). The implementation
provides definitions for standard library entities, as necessary, while combining translation units to form a
complete C++ program (2.2).
7Two 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 (17.6.1.3).
8A 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.
9Each implementation shall include documentation that identifies all conditionally-supported constructs that
it does not support and defines all locale-specific characteristics.3
1.5 Structure of this International Standard [intro.structure]
1Clauses 2through 16 describe the C++ programming language. That description includes detailed syntactic
specifications in a form described in 1.6. For convenience, Annex Arepeats all such syntactic specifications.
2) “Correct execution” can include undefined behavior, depending on the data being processed; see 1.3 and 1.9.
3) This documentation also defines implementation-defined behavior; see 1.9.
§ 1.5 5
c
ISO/IEC N????
2Clauses 18 through 30 and Annex D(the library clauses) describe the Standard C++ library. That description
includes detailed descriptions of the templates, classes, functions, constants, and macros that constitute the
library, in a form described in Clause 17.
3Annex Brecommends lower bounds on the capacity of conforming implementations.
4Annex Csummarizes 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 D
describes those features.
5Throughout this International Standard, 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.
1.6 Syntax notation [syntax]
1In the syntax notation used in this International Standard, 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 “opt ”, so
{expressionopt }
indicates an optional expression enclosed in braces.
2Names 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 declara-
tions).
X-list is one or more X’s separated by intervening commas (e.g., expression-list is a sequence of
expressions separated by commas).
1.7 The C++ memory model [intro.memory]
1The 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 (2.3) and the eight-bit code units of the Unicode UTF-8
encoding form and is composed of a contiguous sequence of bits, 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.
2[Note: The representation of types is described in 3.9.— end note ]
3Amemory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having
non-zero 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 imple-
mentation. — end note ] Two or more threads of execution (1.10) can update and access separate memory
locations without interfering with each other.
4[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 non-zero
width. — end note ]
5[Example: A structure declared as
§ 1.7 6
c
ISO/IEC N????
struct {
char a;
int b:5,
c:11,
:0,
d:8;
struct {int ee:8;} e;
}
contains four separate memory locations: The field aand bit-fields dand e.ee are each separate memory
locations, and can be modified concurrently without interfering with each other. The bit-fields band c
together constitute the fourth memory location. The bit-fields band ccannot be concurrently modified, but
band a, for example, can be. — end example ]
1.8 The C++ object model [intro.object]
1The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is a
region of storage. [ Note: A function is not an object, regardless of whether or not it occupies storage in the
way that objects do. — end note ] An object is created by a definition (3.1), by a new-expression (5.3.4)
or by the implementation (12.2) when needed. The properties of an object are determined when the object
is created. An object can have a name (Clause 3). An object has a storage duration (3.7) which influences
its lifetime (3.8). An object has a type (3.9). The term object type refers to the type with which the object
is created. Some objects are polymorphic (10.3); 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 5)
used to access them.
2Objects can contain other objects, called subobjects. A subobject can be a member subobject (9.2), a base
class subobject (Clause 10), or an array element. An object that is not a subobject of any other object is
called a complete object.
3For every object x, there is some object called the complete object of x, determined as follows:
If xis a complete object, then xis the complete object of x.
Otherwise, the complete object of xis the complete object of the (unique) object that contains x.
4If a complete object, a data member (9.2), 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.
5Unless it is a bit-field (9.6), a most derived object shall have a non-zero 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 (3.9) shall occupy contiguous bytes of storage.
6Unless 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 that are not bit-fields may have the same address if one is a subobject
of the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise,
they shall have distinct addresses.4
[Example:
static const char test1 = ’x’;
static const char test2 = ’x’;
const bool b = &test1 != &test2; // always true
— end example ]
7[Note: C++ provides a variety of fundamental types and several ways of composing new types from existing
types (3.9). — end note ]
4) 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 (1.9).
§ 1.8 7
c
ISO/IEC N????
1.9 Program execution [intro.execution]
1The 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.5
2Certain 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 ma-
chine. Each implementation shall include documentation describing its characteristics and behavior in these
respects.6Such documentation shall define the instance of the abstract machine that corresponds to that
implementation (referred to as the “corresponding instance” below).
3Certain other aspects and operations of the abstract machine are described in this International Standard as
unspecified (for example, order of evaluation of arguments to a function). 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.
4Certain 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 ]
5A 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).
6When the processing of the abstract machine is interrupted by receipt of a signal, the values of objects which
are neither
of type volatile std::sig_atomic_t nor
lock-free atomic objects (29.4)
are unspecified during the execution of the signal handler, and the value of any object not in either of
these two categories that is modified by the handler becomes undefined.
7An instance of each object with automatic storage duration (3.7.3) 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).
8The least requirements on a conforming implementation are:
Access to volatile objects 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.
5) 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.
6) This documentation also includes conditionally-supported constructs and locale-specific behavior. See 1.4.
§ 1.9 8
c
ISO/IEC N????
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 ]
9[Note: Operators can be regrouped according to the usual mathematical rules only where the operators
really are associative or commutative.7For 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 aand bwere, respectively, -32754 and -15, the sum a+bwould 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 aand bmight 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 ]
10 Afull-expression is an expression that is not a subexpression of another expression. [ Note: in some contexts,
such as unevaluated operands, a syntactic subexpression is considered a full-expression (Clause 5). — end
note ] 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. A call to a destructor
generated at the end of the lifetime of an object other than a temporary object is an implicit full-expression.
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.
[Example:
struct S {
S(int i): I(i) { }
int& v() { return I; }
private:
int I;
};
S s1(1); // full-expression is call of S::S(int)
S s2 = 2; // full-expression is call of S::S(int)
void f() {
if (S(3).v()) // full-expression includes lvalue-to-rvalue and
// int to bool conversions, performed before
7) Overloaded operators are never assumed to be associative or commutative.
§ 1.9 9
c
ISO/IEC N????
// temporary is deleted at end of full-expression
{ }
}
— end example ]
11 [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 (8.3.6) are
considered to be created in the expression that calls the function, not the expression that defines the default
argument. — end note ]
12 Accessing an object designated by a volatile glvalue (3.10), 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 sub-expression) 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 to a volatile object 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.
13 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single
thread (1.10), which induces a partial order among those evaluations. Given any two evaluations Aand B, if
Ais sequenced before B, then the execution of Ashall precede the execution of B. If Ais not sequenced before
Band Bis not sequenced before A, then Aand Bare unsequenced. [ Note: The execution of unsequenced
evaluations can overlap. — end note ] Evaluations Aand Bare indeterminately sequenced when either A
is sequenced before Bor Bis sequenced before A, but it is unspecified which. [ Note: Indeterminately
sequenced evaluations cannot overlap, but either could be executed first. — end note ]
14 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.8
15 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 scalar
object is unsequenced relative to either another side effect on the same scalar object or a value computation
using the value of the same scalar object, the behavior is undefined.
[Example:
void f(int, int);
void g(int i, int* v) {
i = v[i++]; // the behavior is undefined
i = 7, i++, i++; // ibecomes 9
i = i++ + 1; // the behavior is undefined
i=i+1; // the value of iis incremented
f(i = -1, i = -1); // the behavior is undefined
}
— 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. [ Note: Value
computations and side effects associated with different argument expressions are unsequenced. — end note ]
8) As specified in 12.2, 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.
§ 1.9 10
c
ISO/IEC N????
Every evaluation in the calling function (including other function calls) that is not otherwise specifically
sequenced before or after the execution of the body of the called function is indeterminately sequenced with
respect to the execution of the called function.9Several contexts in C++ cause evaluation of a function call,
even though no corresponding function call syntax appears in the translation unit. [ Example: Evaluation of
anew expression invokes one or more allocation and constructor functions; see 5.3.4. For another example,
invocation of a conversion function (12.3.2) 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.
1.10 Multi-threaded executions and data races [intro.multithread]
1Athread 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.10 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 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.
2Implementations should ensure that all unblocked threads eventually make progress. [ Note: Standard
library functions may silently block on I/O or locks. Factors in the execution environment, including
externally-imposed thread priorities, may prevent an implementation from making certain guarantees of
forward progress. — end note ]
3The value of an object visible to a thread Tat 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 ]
4Two expression evaluations conflict if one of them modifies a memory location (1.7) and the other one
accesses or modifies the same memory location.
5The library defines a number of atomic operations (Clause 29) and operations on mutexes (Clause 30)
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 Aforces 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 ]
9) In other words, function executions do not interleave with each other.
10) An object with automatic or thread storage duration (3.7) is associated with one specific thread, and can be accessed by
a different thread only indirectly through a pointer or reference (3.9.2).
§ 1.10 11
c
ISO/IEC N????
6All modifications to a particular atomic object Moccur in some particular total order, called the modification
order of M. If Aand Bare modifications of an atomic object Mand Ahappens before (as defined below) B,
then Ashall precede Bin the modification order of M, which is defined below. [ Note: This states that the
modification orders must respect the “happens before” relationship. — end note ] [ 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 ]
7Arelease sequence headed by a release operation Aon an atomic object Mis 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.
8Certain 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 (29.3). [ 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 ]
9An evaluation A carries a dependency to an evaluation Bif
the value of Ais used as an operand of B, unless:
Bis an invocation of any specialization of std::kill_dependency (29.3), or
Ais the left operand of a built-in logical AND (&&, see 5.14) or logical OR (||, see 5.15) operator,
or
Ais the left operand of a conditional (?:, see 5.16) operator, or
Ais the left operand of the built-in comma (,) operator (5.18);
or
Awrites a scalar object or bit-field M,Breads the value written by Afrom M, and Ais sequenced
before B, or
for some evaluation X,Acarries a dependency to X, and Xcarries a dependency to B.
[Note: “Carries a dependency to” is a subset of “is sequenced before”, and is similarly strictly intra-
thread. — end note ]
10 An evaluation Ais dependency-ordered before an evaluation Bif
Aperforms a release operation on an atomic object M, and, in another thread, Bperforms a consume
operation on Mand reads a value written by any side effect in the release sequence headed by A, or
for some evaluation X,Ais dependency-ordered before Xand Xcarries 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 ]
11 An evaluation A inter-thread happens before an evaluation Bif
Asynchronizes with B, or
Ais dependency-ordered before B, or
§ 1.10 12
c
ISO/IEC N????
for some evaluation X
Asynchronizes with Xand Xis sequenced before B, or
Ais sequenced before Xand Xinter-thread happens before B, or
Ainter-thread happens before Xand Xinter-thread happens before B.
[Note: The “inter-thread happens before” relation describes arbitrary concatenations of “sequenced be-
fore”, “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 “se-
quenced 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 op-
eration 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 ]
12 An evaluation A happens before an evaluation Bif:
Ais sequenced before B, or
Ainter-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 ]
13 Avisible side effect A on a scalar object or bit-field Mwith respect to a value computation Bof Msatisfies
the conditions:
Ahappens before Band
there is no other side effect Xto Msuch that Ahappens before Xand Xhappens 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 ]
14 The visible sequence of side effects on an atomic object M, with respect to a value computation Bof M, is
a maximal contiguous sub-sequence of side effects in the modification order of M, where the first side effect
is visible with respect to B, and for every side effect, it is not the case that Bhappens before it. The value
of an atomic object M, as determined by evaluation B, shall be the value stored by some operation in the
visible sequence of Mwith respect to B. [ Note: It can be shown that the visible sequence of side effects of
a value computation is unique given the coherence requirements below. — end note ]
15 If an operation Athat modifies an atomic object Mhappens before an operation Bthat modifies M, then
Ashall be earlier than Bin the modification order of M. [ Note: This requirement is known as write-write
coherence. — end note ]
16 If a value computation Aof an atomic object Mhappens before a value computation Bof M, and Atakes
its value from a side effect Xon M, then the value computed by Bshall either be the value stored by Xor
§ 1.10 13
c
ISO/IEC N????
the value stored by a side effect Yon M, where Yfollows Xin the modification order of M. [ Note: This
requirement is known as read-read coherence. — end note ]
17 If a value computation Aof an atomic object Mhappens before an operation Bthat modifies M, then A
shall take its value from a side effect Xon M, where Xprecedes Bin the modification order of M. [ Note:
This requirement is known as read-write coherence. — end note ]
18 If a side effect Xon an atomic object Mhappens before a value computation Bof M, then the evaluation
Bshall take its value from Xor from a side effect Ythat follows Xin the modification order of M. [ Note:
This requirement is known as write-read coherence. — end note ]
19 [Note: The four preceding coherence requirements effectively disallow compiler reordering of atomic opera-
tions 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 ]
20 [Note: The visible sequence of side effects depends on the “happens before” relation, which depends on the
values observed by loads of atomics, which we are restricting here. 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 ]
21 The execution of a program contains a data race if it contains two conflicting actions in different threads,
at least one of which is not atomic, and neither happens before the other. 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 ]
22 [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 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 assign-
ment 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 “visible
sequence” rules. — end note ]
23 [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 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 ]
24 The implementation may assume that any thread will eventually do one of the following:
— terminate,
make a call to a library I/O function,
access or modify a volatile object, 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 ]
25 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.
§ 1.10 14
c
ISO/IEC N????
1.11 Acknowledgments [intro.ack]
1The C++ programming language as described in this International Standard 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 c
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 c
1978 AT&T).
2Portions of the library Clauses of this International Standard 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 c
1995 P.J.
Plauger).
3POSIX R
is a registered trademark of the Institute of Electrical and Electronic Engineers, Inc.
4All rights in these originals are reserved.
§ 1.11 15
c
ISO/IEC N????
2 Lexical conventions [lex]
2.1 Separate translation [lex.separate]
1The text of the program is kept in units called source files in this International Standard. A source file
together with all the headers (17.6.1.2) and source files included (16.2) via the preprocessing directive
#include, less any source lines skipped by any of the conditional inclusion (16.1) preprocessing directives, is
called a translation unit. [ Note: A C++ program need not all be translated at the same time. — end note ]
2[Note: Previously translated translation units and instantiation units can be preserved individually or in
libraries. The separate translation units of a program communicate (3.5) 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 (3.5). — end note ]
2.2 Phases of translation [lex.phases]
1The precedence among the syntax rules of translation is specified by the following phases.11
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 phys-
ical source file characters accepted is implementation-defined. Trigraph sequences (2.4) are replaced
by corresponding single-character internal representations. Any source file character not in the basic
source character set (2.3) is replaced by the universal-character-name that designates that charac-
ter. (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 (i.e., using the \uXXXX notation), are handled equivalently except where this
replacement is reverted in a raw string literal.)
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. If, as a result, a character sequence that
matches the syntax of a universal-character-name is produced, 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. The source file is decomposed into preprocessing tokens (2.5) and sequences of white-space characters
(including comments). A source file shall not end in a partial preprocessing token or in a partial com-
ment.12 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 to-
kens is context-dependent. [ Example: see the handling of <within a #include preprocessing directive.
— end example ]
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
11) Implementations must behave as if these separate phases occur, although in practice different phases might be folded
together.
12) 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.
§ 2.2 16
c
ISO/IEC N????
is produced by token concatenation (16.3.3), the behavior is undefined. A #include preprocessing di-
rective causes the named header or source file to be processed from phase 1 through phase 4, recursively.
All preprocessing directives are then deleted.
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 (2.14.3,2.14.5); if there is no corresponding
member, it is converted to an implementation-defined member other than the null (wide) character.13
6. Adjacent string literal tokens are concatenated.
7. White-space characters separating tokens are no longer significant. Each preprocessing token is con-
verted into a token. (2.7). The resulting tokens are syntactically and semantically analyzed and trans-
lated 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 (14.2). — 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. 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 (14.7.2). — 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. 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.
2.3 Character sets [lex.charset]
1The basic source character set consists of 96 characters: the space character, the control characters repre-
senting horizontal tab, vertical tab, form feed, and new-line, plus the following 91 graphical characters:14
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
_{}[]#()<>%:;.?*+-/^&|!=,\"’
2The universal-character-name construct provides a way to name other characters.
hex-quad:
hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
13) An implementation need not convert all non-corresponding source characters to the same execution character.
14) 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.
§ 2.3 17
c
ISO/IEC N????
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.15
3The 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 representation has all zero bits. 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 0in 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.
2.4 Trigraph sequences [lex.trigraph]
1Before any other processing takes place, each occurrence of one of the following sequences of three characters
(“trigraph sequences”) is replaced by the single character indicated in Table 1.
Table 1 — Trigraph sequences
Trigraph Replacement Trigraph Replacement Trigraph Replacement
??= # ??( [ ??< {
??/ \ ??) ] ??> }
??’ ˆ ??! | ??-
2[Example:
??=define arraycheck(a,b) a??(b??) ??!??! b??(a??)
becomes
#define arraycheck(a,b) a[b] || b[a]
— end example ]
3No other trigraph sequence exists. Each ?that does not begin one of the trigraphs listed above is not
changed.
15) A sequence of characters resembling a universal-character-name in an r-char-sequence (2.14.5) does not form a universal-
character-name.
§ 2.4 18
c
ISO/IEC N????
2.5 Preprocessing tokens [lex.pptoken]
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
1Each preprocessing token that is converted to a token (2.7) shall have the lexical form of a keyword, an
identifier, a literal, an operator, or a punctuator.
2A 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 (2.8), or white-space
characters (space, horizontal tab, new-line, vertical tab, and form-feed), or both. As described in Clause 16,
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.
3If 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 (trigraphs, 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
encoding-prefixopt Rraw-string
Otherwise, if the next three characters are <:: and the subsequent character is neither :nor >, the <
is treated as a preprocessor 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.
[Example:
#define R "x"
const char* s = R"y"; // ill-formed raw string, not "x" "y"
— end example ]
4[Example: The program fragment 1Ex is parsed as a preprocessing number token (one that is not a valid
floating or integer literal token), even though a parse as the pair of preprocessing tokens 1and Ex might
produce a valid expression (for example, if Ex 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 Eis a
macro name. — end example ]
5[Example: The program fragment x+++++y is parsed as x+++++y, which, if xand yhave integral types,
violates a constraint on increment operators, even though the parse x+++++ymight yield a correct
expression. — end example ]
§ 2.5 19
c
ISO/IEC N????
2.6 Alternative tokens [lex.digraph]
1Alternative token representations are provided for some operators and punctuators.16
2In all respects of the language, each alternative token behaves the same, respectively, as its primary token,
except for its spelling.17 The set of alternative tokens is defined in Table 2.
Table 2 — Alternative tokens
Alternative Primary Alternative Primary Alternative Primary
<% { and && and_eq &=
%> } bitor | or_eq |=
<: [ or || xor_eq ˆ=
:> ] xor ˆ not !
%: # compl not_eq !=
%:%: ## bitand &
2.7 Tokens [lex.token]
token:
identifier
keyword
literal
operator
punctuator
1There are five kinds of tokens: identifiers, keywords, literals,18 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 sepa-
rate otherwise adjacent identifiers, keywords, numeric literals, and alternative tokens containing alphabetic
characters. — end note ]
2.8 Comments [lex.comment]
1The characters /* start a comment, which terminates with the characters */. These comments do not
nest. The characters // start a comment, which terminates with 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 ]
2.9 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 >
16) 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”.
17) Thus the “stringized” values (16.3.2) of [and <: will be different, maintaining the source spelling, but the tokens can
otherwise be freely interchanged.
18) Literals include strings and character and numeric literals.
§ 2.9 20
c
ISO/IEC N????
q-char-sequence:
q-char
q-char-sequence q-char
q-char:
any member of the source character set except new-line and "
1Header name preprocessing tokens shall only appear within a #include preprocessing directive (16.2). 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 16.2.
2The 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.19
2.10 Preprocessing numbers [lex.ppnumber]
pp-number:
digit
.digit
pp-number digit
pp-number identifier-nondigit
pp-number esign
pp-number Esign
pp-number .
1Preprocessing number tokens lexically include all integer literal tokens (2.14.2) and all floating literal to-
kens (2.14.4).
2A 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.
2.11 Identifiers [lex.name]
identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
identifier-nondigit:
nondigit
universal-character-name
other implementation-defined characters
nondigit: one of
abcdefghijklm
nopqrstuvwxyz
ABCDEFGHIJKLM
NOPQRSTUVWXYZ_
digit: one of
0123456789
1An 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 E.1. The initial element shall not be a universal-character-name designating a character whose encoding
falls into one of the ranges specified in E.2. Upper- and lower-case letters are different. All characters are
significant.20
19) 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.
20) 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.
§ 2.11 21
c
ISO/IEC N????
2The identifiers in Table 3have 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 3 — Identifiers with special meaning
override final
3In addition, some identifiers are reserved for use by C++ implementations and standard libraries (17.6.4.3.2)
and shall not be used otherwise; no diagnostic is required.
2.12 Keywords [lex.key]
1The identifiers shown in Table 4are reserved for use as keywords (that is, they are unconditionally treated
as keywords in phase 7) except in an attribute-token (7.6.1) [ Note: The export keyword is unused but is
reserved for future use. — end note ]:
Table 4 — 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
2Furthermore, the alternative representations shown in Table 5for certain operators and punctuators (2.6)
are reserved and shall not be used otherwise:
Table 5 — Alternative representations
and and_eq bitand bitor compl not
not_eq or or_eq xor xor_eq
2.13 Operators and punctuators [lex.operators]
1The 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:
§ 2.13 22
c
ISO/IEC N????
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 (2.2).
2.14 Literals [lex.literal]
2.14.1 Kinds of literals [lex.literal.kinds]
1There are several kinds of literals.21
literal:
integer-literal
character-literal
floating-literal
string-literal
boolean-literal
pointer-literal
user-defined-literal
2.14.2 Integer literals [lex.icon]
integer-literal:
decimal-literal integer-suffixopt
octal-literal integer-suffixopt
hexadecimal-literal integer-suffixopt
binary-literal integer-suffixopt
decimal-literal:
nonzero-digit
decimal-literal digit
octal-literal:
0
octal-literal octal-digit
hexadecimal-literal:
0x hexadecimal-digit
0X hexadecimal-digit
hexadecimal-literal hexadecimal-digit
binary-literal:
0b binary-digit
0B binary-digit
binary-literal binary-digit
nonzero-digit: one of
123456789
octal-digit: one of
01234567
hexadecimal-digit: one of
0123456789
abcdef
ABCDEF
21) The term “literal” generally designates, in this International Standard, those tokens that are called “constants” in ISO C.
§ 2.14.2 23
c
ISO/IEC N????
binary-digit:
0
1
integer-suffix:
unsigned-suffix long-suffixopt
unsigned-suffix long-long-suffixopt
long-suffix unsigned-suffixopt
long-long-suffix unsigned-suffixopt
unsigned-suffix: one of
u U
long-suffix: one of
l L
long-long-suffix: one of
ll LL
1An integer literal is a sequence of digits that has no period or exponent part. 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 decimal integer literal (base ten) begins with a digit other than 0and
consists of a sequence of decimal digits. An octal integer literal (base eight) begins with the digit 0and
consists of a sequence of octal digits.22 Ahexadecimal 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 athrough
fand Athrough Fwith decimal values ten through fifteen. A binary integer literal (base two) begins with
0b or 0B and consists of a sequence of binary digits. [ Example: the number twelve can be written 12,014,
0XC, or 0b1100.— end example ]
2The type of an integer literal is the first of the corresponding list in Table 6in which its value can be
represented.
Table 6 — Types of integer constants
Suffix Decimal constants Octal or hexadecimal constant
none int int
long int unsigned int
long long int long int
unsigned long int
long long int
unsigned long long int
uor U unsigned int unsigned int
unsigned long int unsigned long int
unsigned long long int unsigned long long int
lor L long int long int
long long int unsigned long int
long long int
unsigned long long int
Both uor U unsigned long int unsigned long int
and lor L unsigned long long int unsigned long long int
ll or LL long long int long long int
unsigned long long int
Both uor U unsigned long long int unsigned long long int
and ll or LL
3If an integer literal cannot be represented by any type in its list and an extended integer type (3.9.1) can
represent its value, it may have that extended integer type. If all of the types in the list for the literal are
22) The digits 8and 9are not octal digits.
§ 2.14.2 24
c
ISO/IEC N????
signed, the extended integer type shall be signed. If all of the types in the list for the 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.
2.14.3 Character literals [lex.ccon]
character-literal:
c-char-sequence
uc-char-sequence
Uc-char-sequence
Lc-char-sequence
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
1A character literal is one or more characters enclosed in single quotes, as in ’x’, optionally preceded by
one of the letters u,U, or L, as in u’y’,U’z’, or L’x’, respectively. A character literal that does not begin
with u,U, or Lis an ordinary character literal, also referred to as a narrow-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.
2A character literal that begins with the letter u, such as u’y’, is a character literal of type char16_t. The
value of a char16_t 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
literal containing multiple c-chars is ill-formed. A character literal that begins with the letter U, such as
U’z’, is a character literal of type char32_t. The value of a char32_t literal containing a single c-char is
equal to its ISO 10646 code point value. A char32_t literal containing multiple c-chars is ill-formed. A
character literal that begins with the letter L, such as L’x’, is a wide-character literal. A wide-character
literal has type wchar_t.23 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
23) They are intended for character sets where a character does not fit into a single byte.
§ 2.14.3 25
c
ISO/IEC N????
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 3.9.1).
— end note ]. The value of a wide-character literal containing multiple c-chars is implementation-defined.
3Certain nongraphic characters, the single quote , the double quote ", the question mark ?,24 and the
backslash \, can be represented according to Table 7. 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 7are conditionally-supported, with
implementation-defined semantics. An escape sequence specifies a single character.
Table 7 — 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
4The 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 xfollowed 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
literals with no prefix), char16_t (for literals prefixed by ’u’), char32_t (for literals prefixed by ’U’), or
wchar_t (for literals prefixed by ’L’).
5A 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 ]
2.14.4 Floating literals [lex.fcon]
floating-literal:
fractional-constant exponent-partopt floating-suffixopt
digit-sequence exponent-part floating-suffixopt
fractional-constant:
digit-sequenceopt .digit-sequence
digit-sequence .
24) Using an escape sequence for a question mark can avoid accidentally creating a trigraph.
§ 2.14.4 26
c
ISO/IEC N????
exponent-part:
esignopt digit-sequence
Esignopt digit-sequence
sign: one of
+ -
digit-sequence:
digit
digit-sequence digit
floating-suffix: one of
flFL
1A floating literal consists of an integer part, a decimal point, a fraction part, an eor E, 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. Either the integer part or the fraction part (not both) can be omitted; either the
decimal point or the letter e(or E) and the exponent (not both) can be omitted. The integer part, the
optional decimal point and the optional fraction part form the significant part of the floating literal. The
exponent, if present, indicates the power of 10 by which the significant part is to be scaled. 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 fand Fspecify
float, the suffixes land Lspecify long double. If the scaled value is not in the range of representable
values for its type, the program is ill-formed.
2.14.5 String literals [lex.string]
string-literal:
encoding-prefixopt "s-char-sequenceopt "
encoding-prefixopt Rraw-string
encoding-prefix:
u8
u
U
L
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-sequenceopt (r-char-sequenceopt )d-char-sequenceopt "
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
§ 2.14.5 27
c
ISO/IEC N????
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.
1A string literal is a sequence of characters (as defined in 2.14.3) 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.
2A string literal that has an Rin 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.
3[Note: The characters ’(’ and ’)’ are permitted in a raw-string. Thus, R"delimiter((a|b))delimiter"
is equivalent to "(a|b)".— end note ]
4[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 ]
5[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 ]
6After 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.
7A string literal that begins with u8, such as u8"asdf", is a UTF-8 string literal and is initialized with the
given characters as encoded in UTF-8.
8Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow
string literal has type “array of nconst char”, where nis the size of the string as defined below, and has
static storage duration (3.7).
9A 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 nconst char16_t”, where nis the size of the string as defined below; it has static storage
duration and is initialized with the given characters. A single c-char may produce more than one char16_t
character in the form of surrogate pairs.
10 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 nconst char32_t”, where nis the size of the string as defined below; it has static storage
duration and is initialized with the given characters.
11 A string literal that begins with L, such as L"asdf", is a wide string literal. A wide string literal has type
“array of nconst wchar_t”, where nis the size of the string as defined below; it has static storage duration
and is initialized with the given characters.
§ 2.14.5 28
c
ISO/IEC N????
12 Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-
defined. The effect of attempting to modify a string literal is undefined.
13 In translation phase 6 (2.2), 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 concatena-
tion is an interpretation, not a conversion. Because the interpretation happens in translation phase 6 (after
each character from a 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 8has some examples of valid concatenations.
Table 8 — 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 ]
14 After any necessary concatenation, in translation phase 7 (2.2), ’\0’ is appended to every string literal so
that programs that scan a string can find its end.
15 Escape sequences and universal-character-names in non-raw string literals have the same meaning as in
character literals (2.14.3), except that the single quote is representable either by itself or by the escape
sequence \’, and the double quote "shall be preceded by a \. 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 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’.
2.14.6 Boolean literals [lex.bool]
boolean-literal:
false
true
1The Boolean literals are the keywords false and true. Such literals are prvalues and have type bool.
2.14.7 Pointer literals [lex.nullptr]
pointer-literal:
nullptr
1The 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
§ 2.14.7 29
c
ISO/IEC N????
a null pointer constant and can be converted to a null pointer value or null member pointer value. See 4.10
and 4.11.— end note ]
2.14.8 User-defined literals [lex.ext]
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-partopt ud-suffix
digit-sequence exponent-part ud-suffix
user-defined-string-literal:
string-literal ud-suffix
user-defined-character-literal:
character-literal ud-suffix
ud-suffix:
identifier
1If 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.
2Auser-defined-literal is treated as a call to a literal operator or literal operator template (13.5.8). 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 Xis looked up in the context of Lusing the rules for unqualified name
lookup (3.4.1). Let Sbe the set of declarations found by this lookup. Sshall not be empty.
3If Lis a user-defined-integer-literal, let nbe the literal without its ud-suffix. If Scontains a literal operator
with parameter type unsigned long long, the literal Lis treated as a call of the form
operator "" X(nULL)
Otherwise, Sshall contain a raw literal operator or a literal operator template (13.5.8) but not both. If
Scontains a raw literal operator, the literal L is treated as a call of the form
operator "" X("n")
Otherwise (Scontains a literal operator template), Lis treated as a call of the form
operator "" X<’c1’, ’c2’, ... ’ck’>()
where nis the source character sequence c1c2...ck. [ Note: The sequence c1c2...ckcan only contain
characters from the basic source character set. — end note ]
4If Lis a user-defined-floating-literal, let fbe the literal without its ud-suffix. If Scontains a literal operator
with parameter type long double, the literal Lis treated as a call of the form
operator "" X(fL)
Otherwise, Sshall contain a raw literal operator or a literal operator template (13.5.8) but not both. If
Scontains a raw literal operator, the literal L is treated as a call of the form
operator "" X("f")
Otherwise (Scontains a literal operator template), Lis treated as a call of the form
§ 2.14.8 30
c
ISO/IEC N????
operator "" X<’c1’, ’c2’, ... ’ck’>()
where fis the source character sequence c1c2...ck. [ Note: The sequence c1c2...ckcan only contain
characters from the basic source character set. — end note ]
5If Lis 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 Lis treated as a call
of the form
operator "" X(str ,len )
6If Lis a user-defined-character-literal, let ch be the literal without its ud-suffix.Sshall contain a literal
operator (13.5.8) whose only parameter has the type of ch and the literal Lis treated as a call of the form
operator "" X(ch )
7[Example:
long double operator "" _w(long double);
std::string operator "" _w(const char16_t*, 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 ]
8In translation phase 6 (2.2), 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 2.14.5. 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.
9[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 ]
10 Some identifiers appearing as ud-suffixes are reserved for future standardization (17.6.4.3.5). A program
containing such a ud-suffix is ill-formed, no diagnostic required.
§ 2.14.8 31
c
ISO/IEC N????
3 Basic concepts [basic]
1[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 ]
2[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 ]
3An entity is a value, object, reference, function, enumerator, type, class member, template, template spe-
cialization, namespace, parameter pack, or this.
4Aname is a use of an identifier (2.11), operator-function-id (13.5), literal-operator-id (13.5.8), conversion-
function-id (12.3.2), or template-id (14.2) that denotes an entity or label (6.6.4,6.1).
5Every name that denotes an entity is introduced by a declaration. Every name that denotes a label is
introduced either by a goto statement (6.6.4) or a labeled-statement (6.1).
6Avariable is introduced by the declaration of a reference other than a non-static data member or of an
object. The variable’s name denotes the reference or object.
7Some 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 (3.4).
8Two names are the same if
they are identifiers composed of the same character sequence, or
they are operator-function-ids formed with the same operator, or
they are conversion-function-ids formed with the same type, or
they are template-ids that refer to the same class or function (14.4), or
they are the names of literal operators (13.5.8) formed with the same literal suffix identifier.
9A name used in more than one translation unit can potentially refer to the same entity in these translation
units depending on the linkage (3.5) of the name specified in each translation unit.
3.1 Declarations and definitions [basic.def]
1A declaration (Clause 7) 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 static assertion (Clause 7),
controlling template instantiation (14.7.2),
use of attributes (Clause 7), and
nothing (in the case of an empty-declaration).
§ 3.1 32
c
ISO/IEC N????
2A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it
contains the extern specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a function-
body, it declares a static data member in a class definition (9.2,9.4), it is a class name declaration (9.1), it is
an opaque-enum-declaration (7.2), it is a template-parameter (14.1), it is a parameter-declaration (8.3.5) in a
function declarator that is not the declarator of a function-definition, or it is a typedef declaration (7.1.3),
an alias-declaration (7.1.3), a using-declaration (7.3.3), a static_assert-declaration (Clause 7), an attribute-
declaration (Clause 7), an empty-declaration (Clause 7), or a using-directive (7.3.4).
[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 fand 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 Nand 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 ]
3[Note: In some circumstances, C++ implementations implicitly define the default constructor (12.1), copy
constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move assignment opera-
tor (12.8), or destructor (12.4) member functions. — end note ] [ Example: given
#include <string>
struct C {
std::string s; // std::string is the standard library class (Clause 21)
};
int main() {
C a;
Cb=a;
b = a;
}
the implementation will implicitly define functions to make the definition of Cequivalent to
struct C {
std::string s;
25) Appearing inside the braced-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a
definition.
§ 3.1 33
c
ISO/IEC N????
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 ]
4[Note: A class name can also be implicitly declared by an elaborated-type-specifier (7.1.6.3). — end note ]
5A program is ill-formed if the definition of any object gives the object an incomplete type (3.9).
3.2 One definition rule [basic.def.odr]
1No translation unit shall contain more than one definition of any variable, function, class type, enumeration
type, or template.
2An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression
thereof. The set of potential results of an expression eis defined as follows:
If eis an id-expression (5.1.1), the set contains only e.
— If eis a class member access expression (5.2.5), the set contains the potential results of the object
expression.
If eis a pointer-to-member expression (5.5) whose second operand is a constant expression, the set
contains the potential results of the object expression.
If ehas the form (e1), the set contains the potential results of e1.
If eis a glvalue conditional expression (5.16), the set is the union of the sets of potential results of the
second and third operands.
If eis a comma expression (5.18), the set contains the potential results of the right operand.
Otherwise, the set is empty.
3A variable xwhose name appears as a potentially-evaluated expression ex is odr-used unless xsatisfies
the requirements for appearing in a constant expression (5.19) and, if xis an object, ex is an element of
the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied
to e, or eis a discarded-value expression (Clause 5). 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 (9.3.1)). 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 (3.4,13.3,13.4), unless it is a pure virtual function and its name is not explicitly
qualified. [ Note: This covers calls to named functions (5.2.2), operator overloading (Clause 13), user-defined
conversions (12.3.2), allocation function for placement new (5.3.4), as well as non-default initialization (8.5).
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 (12.8). — 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 5.3.4 and 12.5. A deallocation
function for a class is odr-used by a delete expression appearing in a potentially-evaluated expression as
specified in 5.3.5 and 12.5. 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
§ 3.2 34
c
ISO/IEC N????
a virtual destructor (12.4).26 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 12.8. A default constructor
for a class is odr-used by default initialization or value initialization as specified in 8.5. A constructor for a
class is odr-used as specified in 8.5. A destructor for a class is odr-used as specified in 12.4.
4Every program shall contain exactly one definition of every non-inline function or variable that is odr-used
in that program; 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 12.1,12.4 and
12.8). An inline function shall be defined in every translation unit in which it is odr-used.
5Exactly 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 Xas a struct type
struct X* x1; // use Xin pointer formation
X* x2; // use Xin pointer formation
— end example ] [ Note: The rules for declarations and expressions describe in which contexts complete class
types are required. A class type Tmust be complete if:
an object of type Tis defined (3.1), or
a non-static class data member of type Tis declared (9.2), or
Tis used as the object type or array element type in a new-expression (5.3.4), or
an lvalue-to-rvalue conversion is applied to a glvalue referring to an object of type T(4.1), or
an expression is converted (either implicitly or explicitly) to type T(Clause 4,5.2.3,5.2.7,5.2.9,5.4),
or
an expression that is not a null pointer constant, and has type other than cv void*, is converted to
the type pointer to Tor reference to Tusing a standard conversion (Clause 4), a dynamic_cast (5.2.7)
or a static_cast (5.2.9), or
a class member access operator is applied to an expression of type T(5.2.5), or
the typeid operator (5.2.8) or the sizeof operator (5.3.3) is applied to an operand of type T, or
a function with a return type or argument type of type Tis defined (3.1) or called (5.2.2), or
a class with a base class of type Tis defined (Clause 10), or
an lvalue of type Tis assigned to (5.17), or
the type Tis the subject of an alignof expression (5.3.6), or
an exception-declaration has type T, reference to T, or pointer to T(15.3).
— end note ]
6There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with
external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member
of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for
which some template parameters are not specified (14.7,14.5.5) 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 Ddefined in more than one translation unit, then
26) An implementation is not required to call allocation and deallocation functions from constructors or destructors; however,
this is a permissible implementation technique.
§ 3.2 35
c
ISO/IEC N????
each definition of Dshall consist of the same sequence of tokens; and
in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined
within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after
matching of partial template specialization (14.8.3), except that a name can refer to a non-volatile
const object with internal or no linkage if the object has the same literal type in all definitions of D,
and the object is initialized with a constant expression (5.19), and the object is not odr-used, and the
object has the same value 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 three requirements described above (and, if the default argument has sub-expressions with default
arguments, this requirement applies recursively).27
if Dis a class with an implicitly-declared constructor (12.1), 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 base class or a class member of D. [ Example:
//translation unit 1:
struct X {
X(int);
X(int, int);
};
X::X(int = 0) { }
class D: public X { };
D d2; // X(int) called by D()
//translation unit 2:
struct X {
X(int);
X(int, int);
};
X::X(int = 0, int = 0) { }
class D: public X { }; // X(int, int) called by D();
// D()’s implicit definition
// violates the ODR
— end example ]
If Dis 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 (14.6.3), and also to
dependent names at the point of instantiation (14.6.2). If the definitions of Dsatisfy all these requirements,
then the program shall behave as if there were a single definition of D. If the definitions of Ddo not satisfy
these requirements, then the behavior is undefined.
27) 8.3.6 describes how default argument names are looked up.
§ 3.2 36
c
ISO/IEC N????
3.3 Scope [basic.scope]
3.3.1 Declarative regions and scopes [basic.scope.declarative]
1Every 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.
2[Example: in
int j = 24;
int main() {
int i = j, j;
j = 42;
}
the identifier jis declared twice as a name (and used twice). The declarative region of the first jincludes
the entire example. The potential scope of the first jbegins immediately after that jand 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 jimmediately 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 jis the same
as its potential scope. — end example ]
3The names declared by a declaration are introduced into the scope in which the declaration occurs, except
that the presence of a friend specifier (11.3), certain uses of the elaborated-type-specifier (7.1.6.3), and
using-directives (7.3.4) alter this general behavior.
4Given 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 or enumerator, or all refer to functions
and function templates; in this case the class name or enumeration name is hidden (3.3.10). [ Note: A
namespace name or a class template name must be unique in its declarative region (7.3.2, Clause 14).
— end note ]
[Note: These restrictions apply to the declarative region into which a name is introduced, which is not neces-
sarily the same as the region in which the declaration occurs. In particular, elaborated-type-specifiers (7.1.6.3)
and friend declarations (11.3) may introduce a (possibly not visible) name into an enclosing namespace; these
restrictions apply to that region. Local extern declarations (3.5) 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 ]
5[Note: The name lookup rules are summarized in 3.4.— end note ]
3.3.2 Point of declaration [basic.scope.pdecl]
1The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its
initializer (if any), except as noted below. [ Example:
int x = 12;
{intx=x;}
Here the second xis initialized with its own (indeterminate) value. — end example ]
2[Note: a name from an outer scope remains visible up to the point of declaration of the name that hides
it.[ Example:
§ 3.3.2 37
c
ISO/IEC N????
const int i = 2;
{ int i[i]; }
declares a block-scope array of two integers. — end example ]— end note ]
3The 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 (Clause 9). The point of declaration
for an enumeration is immediately after the identifier (if any) in either its enum-specifier (7.2) or its first
opaque-enum-declaration (7.2), whichever comes first. The point of declaration of an alias or alias template
immediately follows the type-id to which the alias refers.
4The point of declaration for an enumerator is immediately after its enumerator-definition.[ Example:
const int x = 12;
{enum{x=x};}
Here, the enumerator xis initialized with the value of the constant x, namely 12. — end example ]
5After 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 ]
6The point of declaration of a class first declared in an elaborated-type-specifier is as follows:
for a declaration of the form
class-key attribute-specifier-seqopt identifier ;
the identifier is declared to be a class-name in the scope that contains the declaration, otherwise
for an elaborated-type-specifier of the form
class-key identifier
if the elaborated-type-specifier is used in the decl-specifier-seq or parameter-declaration-clause of a
function defined in namespace scope, the identifier is declared as a class-name in the namespace that
contains the declaration; otherwise, except as a friend declaration, the identifier is declared in the
smallest namespace or block scope that contains the declaration. [ Note: These rules also apply within
templates. — end note ] [ Note: Other forms of elaborated-type-specifier do not declare a new name,
and therefore must refer to an existing type-name. See 3.4.4 and 7.1.6.3.— end note ]
7The point of declaration for an injected-class-name (Clause 9) is immediately following the opening brace of
the class definition.
8The point of declaration for a function-local predefined variable (8.4) is immediately before the function-body
of a function definition.
9The 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 ]
10 [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 (7.3.1.2). Function declarations at block scope
§ 3.3.2 38
c
ISO/IEC N????
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 ]
11 [Note: For point of instantiation of a template, see 14.6.4.1.— end note ]
3.3.3 Block scope [basic.scope.block]
1A name declared in a block (6.3) is local to that block; it has block scope. Its potential scope begins at its
point of declaration (3.3.2) and ends at the end of its block. A variable declared at block scope is a local
variable.
2The 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 (8.4) 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.
3The name declared in an exception-declaration is local to the handler and shall not be redeclared in the
outermost block of the handler.
4Names declared in the for-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 6.4.
3.3.4 Function prototype scope [basic.scope.proto]
1In a function declaration, or in any function declarator except the declarator of a function definition (8.4),
names of parameters (if supplied) have function prototype scope, which terminates at the end of the nearest
enclosing function declarator.
3.3.5 Function scope [basic.funscope]
1Labels (6.1) have function scope and may be used anywhere in the function in which they are declared. Only
labels have function scope.
3.3.6 Namespace scope [basic.scope.namespace]
1The declarative region of a namespace-definition is its namespace-body. The potential scope denoted by
an original-namespace-name is the concatenation of the declarative regions established by each of the
namespace-definitions in the same declarative region with that original-namespace-name. 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 (3.3.2) onwards; and for each using-directive (7.3.4) 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 lis 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; // lis from unnamed namespace
§ 3.3.6 39
c
ISO/IEC N????
}
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 ]
2A namespace member can also be referred to after the :: scope resolution operator (5.1) applied to the name
of its namespace or the name of a namespace which nominates the member’s namespace in a using-directive;
see 3.4.3.2.
3The 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 (3.3.2) and ends at the end of the translation unit
that is its declarative region. Names with global namespace scope are said to be global name.
3.3.7 Class scope [basic.scope.class]
1The following rules describe the scope of names declared in classes.
1) 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, exception-specifications,
and brace-or-equal-initializers of non-static data members in that class (including such things in nested
classes).
2) A name Nused in a class Sshall 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.
3) If reordering member declarations in a class yields an alternate valid program under (1) and (2), the
program is ill-formed, no diagnostic is required.
4) 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.
5) 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 func-
tion 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 (8.3.6)).[ Example:
typedef int c;
enum { i = 1 };
class X {
char v[i]; // error: irefers 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 {
§ 3.3.7 40
c
ISO/IEC N????
T a; // error: Trefers 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 ]
2The 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 10) from its class,
after the .operator applied to an expression of the type of its class (5.2.5) or a class derived from its
class,
after the -> operator applied to a pointer to an object of its class (5.2.5) or a class derived from its
class,
after the :: scope resolution operator (5.1) applied to the name of its class or a class derived from its
class.
3.3.8 Enumeration scope [basic.scope.enum]
1The name of a scoped enumerator (7.2) has enumeration scope. Its potential scope begins at its point of
declaration and terminates at the end of the enum-specifier.
3.3.9 Template parameter scope [basic.scope.temp]
1The 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.
2The 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,Uand Vare the template-declarations on lines #1,#2 and #3, respectively.
But the names A,f,gand Call belong to the same declarative region — namely, the namespace-body of
N. (gis still considered to belong to this declarative region in spite of its being hidden during qualified and
unqualified name lookup.) — end example ]
3The potential scope of a template parameter name begins at its point of declaration (3.3.2) 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,
§ 3.3.9 41
c
ISO/IEC N????
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 ]
4The 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 (3.3.10). [ Example:
typedef int N;
template<N X, typename N, template<N Y> class T> struct A;
Here, Xis a non-type template parameter of type int and Yis a non-type template parameter of the
same type as the second template parameter of A.— end example ]— end note ]
5[Note: Because the name of a template parameter cannot be redeclared within its potential scope (14.6.1), a
template parameter’s scope is often its potential scope. However, it is still possible for a template parameter
name to be hidden; see 14.6.1.— end note ]
3.3.10 Name hiding [basic.scope.hiding]
1A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived
class (10.2).
2A class name (9.1) or enumeration name (7.2) 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.
3In 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 3.3.7. The declaration of a member in a derived class (Clause 10) hides
the declaration of a member of a base class of the same name; see 10.2.
4During 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 (3.4.3.2).
5If a name is in scope and is not hidden it is said to be visible.
3.4 Name lookup [basic.lookup]
1The name lookup rules apply uniformly to all names (including typedef-names (7.1.3), namespace-names (7.3),
and class-names (9.1)) wherever the grammar allows such names in the context discussed by a particular
rule. Name lookup associates the use of a name with a declaration (3.1) of that name. Name lookup shall
find an unambiguous declaration for the name (see 10.2). Name lookup may associate more than one dec-
laration with a name if it finds the name to be a function name; the declarations are said to form a set
of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded.
The access rules (Clause 11) 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 5).
2A name “looked up in the context of an expression” is looked up as an unqualified name in the scope where
the expression is found.
3The injected-class-name of a class (Clause 9) is also considered to be a member of that class for the purposes
of name hiding and lookup.
§ 3.4 42
c
ISO/IEC N????
4[Note: 3.5 discusses linkage issues. The notions of scope, point of declaration and name hiding are discussed
in 3.3.— end note ]
3.4.1 Unqualified name lookup [basic.lookup.unqual]
1In all the cases listed in 3.4.1, 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.
2The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing
the using-directive; see 7.3.4. For the purpose of the unqualified name lookup rules described in 3.4.1, the
declarations from the namespace nominated by the using-directive are considered members of that enclosing
namespace.
3The lookup for an unqualified name used as the postfix-expression of a function call is described in 3.4.2.
[Note: For purposes of determining (during parsing) whether an expression is a postfix-expression for a func-
tion call, the usual name lookup rules apply. The rules in 3.4.2 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); // fis the typedef, not the friend
// function: equivalent to int(a)
}
};
}
Because the expression is not a function call, the argument-dependent name lookup (3.4.2) does not
apply and the friend function fis not found. — end note ]
4A name used in global scope, outside of any function, class or user-declared namespace, shall be declared
before its use in global scope.
5A 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.
6A name used in the definition of a function following the function’s declarator-id28 that is a member of
namespace N(where, only for the purpose of exposition, Ncould represent the global scope) shall be declared
before its use in the block in which it is used or in one of its enclosing blocks (6.3) or, shall be declared
before its use in namespace Nor, if Nis 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
}
28) 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.
§ 3.4.1 43
c
ISO/IEC N????
— end example ]
7A name used in the definition of a class Xoutside of a member function body, default argument, exception-
specification,brace-or-equal-initializer of a non-static data member, or nested class definition29 shall be
declared in one of the following ways:
before its use in class Xor be a member of a base class of X(10.2), or
if Xis a nested class of class Y(9.7), before the definition of Xin 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),30 or
if Xis a local class (9.8) or is a nested class of a local class, before the definition of class Xin a block
enclosing the definition of class X, or
if Xis 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
Xin namespace Nor 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 7.3.1.2.
end note ] [ Note: 3.3.7 further describes the restrictions on the use of names in a class definition. 9.7 further
describes the restrictions on the use of names in nested class definitions. 9.8 further describes the restrictions
on the use of names in local class definitions. — end note ]
8For the members of a class X, a name used in a member function body, in a default argument, in an exception-
specification, in the brace-or-equal-initializer of a non-static data member (9.2), or in the definition of a class
member outside of the definition of X, following the member’s declarator-id31, 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 (6.3), or
29) 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.
30) This lookup applies whether the definition of Xis nested within Y’s definition or whether X’s definition appears in a
namespace scope enclosing Y’s definition (9.7).
31) That is, an unqualified name that occurs, for instance, in a type in the parameter-declaration-clause or in the exception-
specification.
§ 3.4.1 44
c
ISO/IEC N????
shall be a member of class Xor be a member of a base class of X(10.2), or
if Xis a nested class of class Y(9.7), 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),32 or
if Xis a local class (9.8) or is a nested class of a local class, before the definition of class Xin a block
enclosing the definition of class X, or
if Xis 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 Nor 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: 9.3 and 9.4 further describe the restrictions on the use of names in member function
definitions. 9.7 further describes the restrictions on the use of names in the scope of nested classes. 9.8
further describes the restrictions on the use of names in local class definitions. — end note ]
9Name lookup for a name used in the definition of a friend function (11.3) 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.
10 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 (10.2). 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 {
32) This lookup applies whether the member function is defined within the definition of class Xor whether the member function
is defined in a namespace scope enclosing X’s definition.
§ 3.4.1 45
c
ISO/IEC N????
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 ]
11 During the lookup for a name used as a default argument (8.3.6) in a function parameter-declaration-clause
or used in the expression of a mem-initializer for a constructor (12.6.2), 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: 8.3.6 further describes the restrictions on the use of names in default arguments. 12.6.2
further describes the restrictions on the use of names in a ctor-initializer.— end note ]
12 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.
13 A name used in the definition of a static data member of class X(9.4.2) (after the qualified-id of the static
member) is looked up as if the name was used in a member function of X. [ Note: 9.4.2 further describes the
restrictions on the use of names in the definition of a static data member. — end note ]
14 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 ]
15 A name used in the handler for a function-try-block (Clause 15) 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 ]
16 [Note: The rules for name lookup in template definitions are described in 14.6.— end note ]
3.4.2 Argument-dependent name lookup [basic.lookup.argdep]
1When the postfix-expression in a function call (5.2.2) is an unqualified-id, other namespaces not considered
during the usual unqualified lookup (3.4.1) may be searched, and in those namespaces, namespace-scope
friend function or function template declarations (11.3) not otherwise visible may be found. These mod-
ifications 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;
§ 3.4.2 46
c
ISO/IEC N????
f(s); // OK: calls N::f
(f)(s); // error: N::f not considered; parentheses
// prevent argument-dependent lookup
}
— end example ]
2For each argument type Tin 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 is 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 Tis a fundamental type, its associated sets of namespaces and classes are both empty.
If Tis 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 namespaces
of which its associated classes are members. Furthermore, if Tis 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 Tis an enumeration type, its associated namespace is the namespace in which it is defined. If it is
class member, its associated class is the member’s class; else it has no associated class.
If Tis a pointer to Uor an array of U, its associated namespaces and classes are those associated with
U.
If Tis a function type, its associated namespaces and classes are those associated with the function
parameter types and those associated with the return type.
— If Tis 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 Tis 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 (7.3.1), 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.
3Let Xbe the lookup set produced by unqualified lookup (3.4.1) and let Ybe the lookup set produced by
argument dependent lookup (defined as follows). If Xcontains
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 or a function template
§ 3.4.2 47
c
ISO/IEC N????
then Yis empty. Otherwise Yis 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
Xand 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 ]
4When considering an associated namespace, the lookup is the same as the lookup performed when the
associated namespace is used as a qualifier (3.4.3.2) 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 (11.3).
All names except those of (possibly overloaded) functions and function templates are ignored.
3.4.3 Qualified name lookup [basic.lookup.qual]
1The name of a class or namespace member or enumerator can be referred to after the :: scope resolution
operator (5.1) 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: Adoes not name a type
}
— end example ]
2[Note: Multiply qualified names, such as N1::N2::N3::n, can be used to refer to members of nested
classes (9.7) or members of nested namespaces. — end note ]
3In 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 {
§ 3.4.3 48
c
ISO/IEC N????
class X { };
static const int number = 50;
static X arr[number];
};
X C::arr[number]; // ill-formed:
// equivalent to: ::X C::arr[C::number];
// not to: C::X C::arr[C::number];
— end example ]
4A name prefixed by the unary scope operator :: (5.1) 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 (3.4.3.2). The use of :: allows a global name to be
referred to even if its identifier has been hidden (3.3.10).
5A name prefixed by a nested-name-specifier that nominates an enumeration type shall represent an enumer-
ator of that enumeration.
6If a pseudo-destructor-name (5.2.4) 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-specifieropt 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(); // Iis 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: 3.4.5 describes how name lookup proceeds after the .and -> operators. — end
note ]
3.4.3.1 Class members [class.qual]
1If 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 (10.2), 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 10). [ Note: A class member
can be referred to using a qualified-id at any point in its potential scope (3.3.7). — end note ] The exceptions
to the name lookup rule above are the following:
a destructor name is looked up as specified in 3.4.3;
a conversion-type-id of a conversion-function-id is looked up in the same manner as a conversion-type-id
in a class member access (see 3.4.5);
the names in a template-argument of a template-id are looked up in the context in which the entire
postfix-expression occurs.
§ 3.4.3.1 49
c
ISO/IEC N????
the lookup for a name specified in a using-declaration (7.3.3) also finds class or enumeration names
hidden within the same scope (3.3.10).
2In a lookup in which function names are not ignored33 and the nested-name-specifier nominates a class C:
if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name
of C(Clause 9), or
in a using-declaration (7.3.3) that is a member-declaration, if the name specified after the nested-name-
specifier is the same as the identifier or the simple-template-id’s template-name in the last component
of the nested-name-specifier,
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 ]
3A 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.
3.4.3.2 Namespace members [namespace.qual]
1If the nested-name-specifier of a qualified-id nominates a namespace, the name specified after the nested-
name-specifier is looked up in the scope of the namespace. If a qualified-id starts with ::, the name after the
:: is looked up in the global namespace. In either case, the names in a template-argument of a template-id
are looked up in the context in which the entire postfix-expression occurs.
2For a namespace Xand name m, the namespace-qualified lookup set S(X, m)is defined as follows: Let
S0(X, m)be the set of all declarations of min Xand the inline namespace set of X(7.3.1). If S0(X, m)is not
empty, S(X, m)is S0(X, m); otherwise, S(X, m)is the union of S(Ni, m)for all namespaces Ninominated
by using-directives in Xand its inline namespace set.
3Given X::m (where Xis a user-declared namespace), or given ::m (where X is the global namespace), if
S(X, m)is the empty set, the program is ill-formed. Otherwise, if S(X, m)has exactly one member, or if
the context of the reference is a using-declaration (7.3.3), S(X, m)is the required set of declarations of m.
Otherwise if the use of mis not one that allows a unique declaration to be chosen from S(X, m), the program
is ill-formed. [ Example:
int x;
namespace Y {
void f(float);
void h(int);
}
33) Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-
specifier, or a base-specifier.
§ 3.4.3.2 50
c
ISO/IEC N????
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(); // gis declared directly in AB,
// therefore Sis { AB::g() } and AB::g() is chosen
AB::f(1); // fis not declared directly in AB so the rules are
// applied recursively to Aand B;
// namespace Yis not searched and Y::f(float)
// is not considered;
// Sis { A::f(int),B::f(char) } and overload
// resolution chooses A::f(int)
AB::f(’c’); // as above but resolution chooses B::f(char)
AB::x++; // xis not declared directly in AB, and
// is not declared in Aor B, so the rules are
// applied recursively to Yand Z,
// Sis { } so the program is ill-formed
AB::i++; // iis not declared directly in AB so the rules are
// applied recursively to Aand B,
// Sis { A::i ,B::i } so the use is ambiguous
// and the program is ill-formed
AB::h(16.8); // his not declared directly in AB and
// not declared directly in Aor Bso the rules are
// applied recursively to Yand Z,
// Sis { Y::h(int),Z::h(double) } and overload
// resolution chooses Z::h(double)
}
4The same declaration found more than once is not an ambiguity (because it is still a unique declaration).
For example:
namespace A {
int a;
}
§ 3.4.3.2 51
c
ISO/IEC N????
namespace B {
using namespace A;
}
namespace C {
using namespace A;
}
namespace BC {
using namespace B;
using namespace C;
}
void f()
{
BC::a++; // OK: Sis { A::a,A::a }
}
namespace D {
using A::a;
}
namespace BD {
using namespace B;
using namespace D;
}
void g()
{
BD::a++; // OK: S is { A::a,A::a }
}
5Because 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: adeclared directly in A,Sis { A::a}
B::a++; // OK: both Aand Bsearched (once), Sis { A::a}
A::b++; // OK: both Aand Bsearched (once), Sis { B::b}
B::b++; // OK: bdeclared directly in B,Sis { B::b}
}
— end example ]
§ 3.4.3.2 52
c
ISO/IEC N????
6During 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 ]
7In 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 (7.3.1) 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)
§ 3.4.3.2 53
c
ISO/IEC N????
— end example ]
3.4.4 Elaborated type specifiers [basic.lookup.elab]
1An elaborated-type-specifier (7.1.6.3) 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 (3.3.10).
2If 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-seqopt identifier ;
the identifier is looked up according to 3.4.1 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:
class-key attribute-specifier-seqopt identifier ;
the elaborated-type-specifier is a declaration that introduces the class-name as described in 3.3.2.
3If the elaborated-type-specifier has a nested-name-specifier, qualified name lookup is performed, as described
in 3.4.3, 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 (7.1.6.3)
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 (7.1.6.3)
struct Base::Data; // error: cannot introduce a qualified type (7.1.6.3)
struct Base::Datum; // error: Datum undefined
struct Base::Data* pBase; // OK: refers to nested Data
— end example ]
3.4.5 Class member access [basic.lookup.classref]
1In a class member access expression (5.2.5), 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 (14.2) or a less-than operator. The identifier is first looked up in the class of the object
§ 3.4.5 54
c
ISO/IEC N????
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.
2If the id-expression in a class member access (5.2.5) 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 (5.2.4),
the unqualified-id is looked up in the context of the complete postfix-expression.
3If the unqualified-id is ~type-name, the type-name is looked up in the context of the entire postfix-expression.
If the type Tof 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 (possibly cv-qualified) 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 ]
4If 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 3.4.3, which describes the lookup of a name before ::, which will only find a
type or namespace name. — end note ]
5If 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.
6If the nested-name-specifier contains a simple-template-id (14.2), the names in its template-arguments are
looked up in the context in which the entire postfix-expression occurs.
7If 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 ]
§ 3.4.5 55
c
ISO/IEC N????
3.4.6 Using-directives and namespace aliases [basic.lookup.udir]
1In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in
anested-name-specifier only namespace names are considered.
3.5 Program and linkage [basic.link]
1Aprogram consists of one or more translation units (Clause 2) linked together. A translation unit consists
of a sequence of declarations.
translation-unit:
declaration-seqopt
2A name is said to have linkage when it might denote the same object, reference, function, type, template,
namespace or value as a name introduced by a declaration in another scope:
When a name has external linkage , the entity it denotes can be referred to by names from scopes of
other translation units or from other scopes of the same translation unit.
When a name has internal linkage , the entity it denotes can be referred to by names from other scopes
in the same translation unit.
When a name has no linkage , the entity it denotes cannot be referred to by names from other scopes.
3A name having namespace scope (3.3.6) has internal linkage if it is the name of
a variable, function or function template that is explicitly declared static; or,
a non-volatile variable that is explicitly declared const or constexpr and neither explicitly declared
extern nor previously declared to have external linkage; or
a data member of an anonymous union.
4An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has
internal linkage. All other namespaces have external linkage. A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
a variable; or
a function; or
a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has
the typedef name for linkage purposes (7.1.3); or
a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the
enumeration has the typedef name for linkage purposes (7.1.3); or
an enumerator belonging to an enumeration with linkage; or
a template.
5In addition, a member function, static data member, a named class or enumeration of class scope, or an
unnamed class or enumeration defined in a class-scope typedef declaration such that the class or enumeration
has the typedef name for linkage purposes (7.1.3), has external linkage if the name of the class has external
linkage.
6The name of a function declared in block scope and the name of a variable declared by a block scope extern
declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and
type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration
declares that same entity and receives the linkage of the previous declaration. If there is more than one such
matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity
receives external linkage.[ Example:
§ 3.5 56
c
ISO/IEC N????
static void f();
static int i = 0; // #1
void g() {
extern void f(); // internal linkage
int i; // #2 ihas no linkage
{
extern void f(); // internal linkage
extern int i; // #3 external linkage
}
}
There are three objects named iin this program. The object with internal linkage introduced by the
declaration in global scope (line #1 ), the object with automatic storage duration and no linkage introduced
by the declaration on line #2, and the object with static storage duration and external linkage introduced
by the declaration on line #3.— end example ]
7When a block scope declaration of an entity with linkage is not found to refer to some other declaration,
then that entity is a member of the innermost enclosing namespace. However such a declaration does not
introduce the member name in its namespace scope. [ Example:
namespace X {
void p() {
q(); // error: qnot yet declared
extern void q(); // qis a member of namespace X
}
void middle() {
q(); // error: qnot yet declared
}
void q() { /* ... */ } // definition of X::q
}
void q() { /* ... */ } // some other, unrelated q
— end example ]
8Names not covered by these rules have no linkage. Moreover, except as noted, a name declared at block
scope (3.3.3) has no linkage. A type is said to have linkage if and only if:
it is a class or enumeration type that is named (or has a name for linkage purposes (7.1.3)) and the
name has linkage; or
it is an unnamed class or enumeration member of a class with linkage; or
it is a specialization of a class template (Clause 14)34; or
it is a fundamental type (3.9.1); or
it is a compound type (3.9.2) other than a class or enumeration, compounded exclusively from types
that have linkage; or
it is a cv-qualified (3.9.3) version of a type that has linkage.
A type without linkage shall not be used as the type of a variable or function with external linkage unless
34) A class template always has external linkage, and the requirements of 14.3.1 and 14.3.2 ensure that the template arguments
will also have appropriate linkage.
§ 3.5 57
c
ISO/IEC N????
the entity has C language linkage (7.5), or
the entity is declared within an unnamed namespace (7.3.1), or
the entity is not odr-used (3.2) or is defined in the same translation unit.
[Note: In other words, a type without linkage contains a class or enumeration that cannot be named outside
its translation unit. An entity with external linkage declared using such a type could not correspond to any
other entity in another translation unit of the program and thus must be defined in the translation unit if
it is odr-used. Also note that classes with linkage may contain members whose types do not have linkage,
and that typedef names are ignored in the determination of whether a type has linkage. — end note ]
[Example:
template <class T> struct B {
void g(T) { }
void h(T);
friend void i(B, T) { }
};
void f() {
struct A { int x; }; // no linkage
Aa={1};
B<A> ba; // declares B<A>::g(A) and B<A>::h(A)
ba.g(a); // OK
ba.h(a); // error: B<A>::h(A) not defined in the translation unit
i(ba, a); // OK
}
— end example ]
9Two names that are the same (Clause 3) and that are declared in different scopes shall denote the same
variable, function, type, enumerator, template or namespace if
both names have external linkage or else both names have internal linkage and are declared in the
same translation unit; and
both names refer to members of the same namespace or to members, not by inheritance, of the same
class; and
when both names denote functions, the parameter-type-lists of the functions (8.3.5) are identical; and
when both names denote function templates, the signatures (14.5.6.1) are the same.
10 After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types
specified by all declarations referring to a given variable or function shall be identical, except that decla-
rations for an array object can specify array types that differ by the presence or absence of a major array
bound (8.3.4). A violation of this rule on type identity does not require a diagnostic.
11 [Note: Linkage to non-C++ declarations can be achieved using a linkage-specification (7.5). — end note ]
3.6 Start and termination [basic.start]
3.6.1 Main function [basic.start.main]
1A program shall contain a global function called main, which is the designated start of the program. 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 ]
§ 3.6.1 58
c
ISO/IEC N????
2An implementation shall not predefine the main function. This function shall not be overloaded. It shall
have a return type of type int, but otherwise its type is implementation-defined. All implementations 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 (8.3.5). 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) (17.5.2.1.4.2) 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 ]
3The function main shall not be used within a program. The linkage (3.5) 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 name main is not otherwise reserved. [ Example: member functions, classes, and enumerations
can be called main, as can entities in other namespaces. — end example ]
4Terminating the program without leaving the current block (e.g., by calling the function std::exit(int)
(18.5)) does not destroy any objects with automatic storage duration (12.4). 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.
5A 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 reaches the end
of main without encountering a return statement, the effect is that of executing
return 0;
3.6.2 Initialization of non-local variables [basic.start.init]
1There are two broad classes of named non-local variables: those with static storage duration (3.7.1) and
those with thread storage duration (3.7.2). Non-local variables with static storage duration are initialized
as a consequence of program initiation. Non-local variables with thread storage duration are initialized as a
consequence of thread execution. Within each of these phases of initiation, initialization occurs as follows.
2Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5)
before any other initialization takes place. A constant initializer for an object ois an expression that is a
constant expression, except that it may also invoke constexpr constructors for oand 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 each full-expression (including implicit conversions) that appears in the initializer of a reference with
static or thread storage duration is a constant expression (5.19) and the reference is bound to an lvalue
designating an object with static storage duration or to a temporary (see 12.2);
— if an object with static or thread storage duration is initialized by a constructor call, and if the
initialization full-expression is a constant initializer for the object;
if an object with static or thread storage duration is not initialized by a constructor call and if either the
object is value-initialized or every full-expression that appears in its initializer is a constant expression.
Together, zero-initialization and constant initialization are called static initialization; all other initial-
ization is dynamic initialization. Static initialization shall be performed before any dynamic initialization
takes place. Dynamic initialization of a non-local variable with static storage duration is either ordered or
§ 3.6.2 59
c
ISO/IEC N????
unordered. Definitions of explicitly specialized class template static data members have ordered initializa-
tion. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have
unordered initialization. Other non-local variables with static storage duration have ordered initialization.
Variables with ordered initialization defined within a single translation unit shall be initialized in the order
of their definitions in the translation unit. If a program starts a thread (30.3), the subsequent initialization
of a variable is unsequenced with respect to the initialization of a variable defined in a different translation
unit. Otherwise, the initialization of a variable is indeterminately sequenced with respect to the initialization
of a variable defined in a different translation unit. If a program starts a thread, the subsequent unordered
initialization of a variable is unsequenced with respect to every other dynamic initialization. Otherwise,
the unordered initialization of a variable is indeterminately sequenced with respect to every other dynamic
initialization. [ Note: This definition permits initialization of a sequence of ordered variables concurrently
with another sequence. — end note ] [ Note: The initialization of local static variables is described in 6.7.
— end note ]
3An implementation is permitted to perform the initialization of a non-local variable with static 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 namespace
scope 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 ]
4It is implementation-defined whether the dynamic initialization of a non-local variable with static storage
duration is done before the first statement of main. If the initialization is deferred to some point in time
after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable
defined in the same translation unit as the variable to be initialized.35 [Example:
// - File 1 -
#include "a.h"
#include "b.h"
B b;
A::A(){
b.Use();
}
// - File 2 -
35) A non-local variable with static storage duration having initialization with side-effects must be initialized even if it is not
odr-used (3.2,3.7.1).
§ 3.6.2 60
c
ISO/IEC N????
#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 aor bis initialized before main is entered or whether the
initializations are delayed until ais first odr-used in main. In particular, if ais initialized before main is
entered, it is not guaranteed that bwill be initialized before it is odr-used by the initialization of a, that is,
before A::A is called. If, however, ais initialized at some point after the first statement of main,bwill be
initialized prior to its use in A::A.— end example ]
5It is implementation-defined whether the dynamic initialization of a non-local variable with static or thread
storage duration is done before the first statement of the initial function of the thread. If the initialization
is deferred to some point in time after the first statement of the initial function of the thread, it shall occur
before the first odr-use (3.2) of any variable with thread storage duration defined in the same translation
unit as the variable to be initialized.
6If the initialization of a non-local variable with static or thread storage duration exits via an exception,
std::terminate is called (15.5.1).
3.6.3 Termination [basic.start.term]
1Destructors (12.4) for initialized objects (that is, objects whose lifetime (3.8) has begun) with static storage
duration are called as a result of returning from main and as a result of calling std::exit (18.5). 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 are sequenced
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 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 the completion of the constructor or dynamic initialization of an object with static 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. [ Note: This definition permits concurrent destruction.
— end note ] 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 (15.5.1).
2If 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.
3If the completion of the initialization of an object with static storage duration is sequenced before a call
to std::atexit (see <cstdlib>,18.5), 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 is sequenced before the completion of the
§ 3.6.3 61
c
ISO/IEC N????
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 is sequenced 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.
4If there is a use of a standard library object or function not permitted within signal handlers (18.10) that
does not happen before (1.10) completion of destruction of objects with static storage duration and execution
of std::atexit registered functions (18.5), 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 ]
5Calling 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().
3.7 Storage duration [basic.stc]
1Storage 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
2Static, thread, and automatic storage durations are associated with objects introduced by declarations (3.1)
and implicitly created by the implementation (12.2). The dynamic storage duration is associated with objects
created with operator new (5.3.4).
3The storage duration categories apply to references as well. The lifetime of a reference is its storage duration.
3.7.1 Static storage duration [basic.stc.static]
1All 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 (3.6.2,3.6.3).
2If 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 12.8.
3The keyword static can be used to declare a local variable with static storage duration. [ Note: 6.7 describes
the initialization of local static variables; 3.6.3 describes the destruction of local static variables. — end
note ]
4The keyword static applied to a class data member in a class definition gives the data member static
storage duration.
3.7.2 Thread storage duration [basic.stc.thread]
1All 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.
§ 3.7.2 62
c
ISO/IEC N????
2A variable with thread storage duration shall be initialized before its first odr-use (3.2) and, if constructed,
shall be destroyed on thread exit.
3.7.3 Automatic storage duration [basic.stc.auto]
1Block-scope variables explicitly declared register or not explicitly declared static or extern have au-
tomatic storage duration. The storage for these entities lasts until the block in which they are created
exits.
2[Note: These variables are initialized and destroyed as described in 6.7.— end note ]
3If a variable with automatic storage duration has initialization or a destructor with side effects, it shall not
be destroyed before the end of its block, nor shall it be eliminated 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 12.8.
3.7.4 Dynamic storage duration [basic.stc.dynamic]
1Objects can be created dynamically during program execution (1.9), using new-expressions (5.3.4), and
destroyed using delete-expressions (5.3.5). 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[].
2The library provides default definitions for the global allocation and deallocation functions. Some global
allocation and deallocation functions are replaceable (18.6.1). 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 (17.6.4.6). The following allocation and deallocation functions (18.6)
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);
void operator delete(void*);
void operator delete[](void*);
These implicit declarations introduce only the function names operator new,operator new[],opera-
tor delete, and operator delete[]. [ Note: The implicit declarations do not introduce the names std,
std::size_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 is ill-formed unless the name has been declared
by including the appropriate header. — end note ] Allocation and/or deallocation functions can also be
declared and defined for any class (12.5).
3Any allocation and/or deallocation functions defined in a C++ program, including the default versions in
the library, shall conform to the semantics specified in 3.7.4.1 and 3.7.4.2.
3.7.4.1 Allocation functions [basic.stc.dynamic.allocation]
1An 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 (18.2). The first
parameter shall not have an associated default argument (8.3.6). 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.
2The 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 of any complete object type with a fundamental alignment requirement (3.11) and then used
to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to
§ 3.7.4.1 63
c
ISO/IEC N????
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 (4.10)p0 different from any
previously returned value p1, unless that value p1 was subsequently passed to an operator delete. The
effect of indirecting through a pointer returned as a request for zero size is undefined.36
3An allocation function that fails to allocate storage can invoke the currently installed new-handler func-
tion (18.6.2.4), 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 (18.6.2.5). — end note ] If an allocation
function declared with a non-throwing exception-specification (15.4) 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 (15.1) of a type that would match a handler (15.3) of type std::bad_alloc (18.6.2.1).
4A global allocation function is only called as the result of a new expression (5.3.4), or called directly using the
function call syntax (5.2.2), 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 (3.7.1), for objects or references with thread storage duration (3.7.2), for objects of type
std::type_info (5.2.8), or for an exception object (15.1). — end note ]
3.7.4.2 Deallocation functions [basic.stc.dynamic.deallocation]
1Deallocation functions shall be class member functions or global functions; a program is ill-formed if deal-
location functions are declared in a namespace scope other than global scope or declared static in global
scope.
2Each deallocation function shall return void and its first parameter shall be void*. A deallocation function
can have more than one parameter. If a class Thas a member deallocation function named operator delete
with exactly one parameter, then that function is a usual (non-placement) deallocation function. If class T
does not declare such an operator delete but does declare a member deallocation function named operator
delete with exactly two parameters, the second of which has type std::size_t (18.2), then this function
is a usual deallocation function. Similarly, if a class Thas a member deallocation function named operator
delete[] with exactly one parameter, then that function is a usual (non-placement) deallocation function.
If class Tdoes not declare such an operator delete[] but does declare a member deallocation function
named operator delete[] with exactly two parameters, the second of which has type std::size_t, then
this function is a usual deallocation function. A deallocation function can 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.
3If 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. Otherwise, the behavior is undefined
if the value supplied to operator delete(void*) in the standard library is not one of the values returned
by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const
std::nothrow_t&) in the standard library, and the behavior is undefined if the value supplied to operator
delete[](void*) in the standard library is not one of the values returned by a previous invocation of
either operator new[](std::size_t) or operator new[](std::size_t, const std::nothrow_t&) in the
standard library.
4If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer
value (4.10), the deallocation function shall deallocate the storage referenced by the pointer, rendering invalid
all pointers referring to any part of the deallocated storage. Indirection through an invalid pointer value and
passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an
36) The intent is to have operator new() implementable by calling std::malloc() or std::calloc(), so the rules are sub-
stantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.
§ 3.7.4.2 64
c
ISO/IEC N????
invalid pointer value has implementation-defined behavior.37
3.7.4.3 Safely-derived pointers [basic.stc.dynamic.safety]
1Atraceable pointer object is
an object of an object pointer type (3.9.2), 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 (3.9.1), where the size and alignment of
the sequence match those of some object pointer type.
2A 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);38
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 (5.7) using a safely-derived pointer value;
the result of a well-defined pointer conversion (4.10,5.4) 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.
3An 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).
4An 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 that is not a safely-derived pointer value is an invalid pointer
value unless the referenced complete object is of dynamic storage duration and has previously been declared
reachable (20.8.4). [ Note: the effect of using an invalid pointer value (including passing it to a deallocation
function) is undefined, see 3.7.4.2. 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.
37) Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault.
38) 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.
§ 3.7.4.3 65
c
ISO/IEC N????
3.7.5 Duration of subobjects [basic.stc.inherit]
1The storage duration of member subobjects, base class subobjects and array elements is that of their complete
object (1.8).
3.8 Object lifetime [basic.life]
1The lifetime of an object is a runtime property of the object. An object is said to have non-trivial initialization
if it is of a class or aggregate type and it or one of its members is initialized by a constructor other than a trivial
default constructor. [ Note: initialization by a trivial copy/move constructor is non-trivial initialization.
end note ] The lifetime of an object of type Tbegins when:
storage with the proper alignment and size for type Tis obtained, and
if the object has non-trivial initialization, its initialization is complete.
The lifetime of an object of type Tends when:
if Tis a class type with a non-trivial destructor (12.4), the destructor call starts, or
the storage which the object occupies is reused or released.
2[Note: The lifetime of an array object starts as soon as storage with proper size and alignment is obtained,
and its lifetime ends when the storage which the array occupies is reused or released. 12.6.2 describes the
lifetime of base and member subobjects. — end note ]
3The properties ascribed to objects throughout this International Standard apply for a given object 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 12.6.2 and in 12.7. 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. 12.6.2 and 12.7 describe the behavior of objects during the
construction and destruction phases. — end note ]
4A 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 (5.3.5) 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.
5Before the lifetime of an object has started but after the storage which the object will occupy has been
allocated39 or, after the lifetime of an object has ended and before the storage which the object occupied is
reused or released, any pointer that refers to 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 12.7. Otherwise,
such a pointer refers to allocated storage (3.7.4.2), 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 (4.10) to a pointer to a virtual base class, or
the pointer is used as the operand of a static_cast (5.2.9), except when the conversion is to pointer
to cv void, or to pointer to cv void and subsequently to pointer to either cv char or cv unsigned
char, or
39) For example, before the construction of a global object of non-POD class type (12.7).
§ 3.8 66
c
ISO/IEC N????
the pointer is used as the operand of a dynamic_cast (5.2.7). [ 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 ]
6Similarly, 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 12.7. Otherwise, such a glvalue refers to allocated
storage (3.7.4.2), and using the properties of the glvalue that do not depend on its value is well-defined. The
program has undefined behavior if:
an lvalue-to-rvalue conversion (4.1) is applied to such a glvalue,
the glvalue is used to access a non-static data member or call a non-static member function of the
object, or
the glvalue is bound to a reference to a virtual base class (8.5.3), or
the glvalue is used as the operand of a dynamic_cast (5.2.7) or as the operand of typeid.
7If, 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
§ 3.8 67
c
ISO/IEC N????
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 (1.8) of type Tand 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 Ccreated
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 ]
8If a program ends the lifetime of an object of type Twith static (3.7.1), thread (3.7.2), or automatic (3.7.3)
storage duration and if Thas a non-trivial destructor,40 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 ]
9Creating a new object at the storage location that a const object with static, thread, or automatic storage
duration occupies or, at the storage location that such a const object used to occupy before its lifetime
ended results in undefined behavior. [ Example:
struct B {
B();
~B();
};
40) 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.
§ 3.8 68
c
ISO/IEC N????
const B b;
void h() {
b.~B();
new (const_cast<B*>(&b)) const B; // undefined behavior
}
— end example ]
10 In this section, “before” and “after” refer to the “happens before” relation (1.10). [ 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 ]
3.9 Types [basic.types]
1[Note: 3.9 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
(1.8), references (8.3.2), or functions (8.3.5). — end note ]
2For 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 (1.7) making up the object can be copied into an array
of char or unsigned char.41 If the content of the array of char or unsigned char 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 ]
3For any trivially copyable type T, if two pointers to Tpoint to distinct Tobjects obj1 and obj2, where
neither obj1 nor obj2 is a base-class subobject, if the underlying bytes (1.7) making up obj1 are copied
into obj2,42 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 ]
4The object representation of an object of type Tis the sequence of Nunsigned char objects taken up by
the object of type T, where Nequals 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.43
5A class that has been declared but not defined, an enumeration type in certain contexts (7.2), or an array
of unknown size or of incomplete element type, is an incompletely-defined object type.44 Incompletely-
defined object types and the void types are incomplete types (3.9.1). Objects shall not be defined to have
an incomplete type.
41) By using, for example, the library functions (17.6.1.2)std::memcpy or std::memmove.
42) By using, for example, the library functions (17.6.1.2)std::memcpy or std::memmove.
43) The intent is that the memory model of C++ is compatible with that of ISO/IEC 9899 Programming Language C.
44) The size and layout of an instance of an incompletely-defined object type is unknown.
§ 3.9 69
c
ISO/IEC N????
6A 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 size 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 size, or of a type
defined by a typedef declaration to be an array of unknown size, cannot be completed. [ Example:
class X; // Xis 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: Xis incomplete
arrp++; // ill-formed: incomplete type
arrpp++; // OK: sizeof UNKA* is known
}
struct X { int i; }; // now Xis 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: Xis complete
arrp++; // ill-formed: UNKA can’t be completed
}
— end example ]
7[Note: The rules for declarations and expressions describe in which contexts incomplete types are prohibited.
— end note ]
8An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a
void type.
9Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), std::nullptr_-
t, and cv-qualified versions of these types (3.9.3) are collectively called scalar types. Scalar types, POD classes
(Clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called POD
types. Scalar types, trivially copyable class types (Clause 9), arrays of such types, and non-volatile const-
qualified versions of these types (3.9.3) are collectively called trivially copyable types. Scalar types, trivial
class types (Clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively
called trivial types. Scalar types, standard-layout class types (Clause 9), arrays of such types and cv-qualified
versions of these types (3.9.3) are collectively called standard-layout types.
10 A type is a literal type if it is:
void; or
a scalar type; or
a reference type; or
an array of literal type other than an array of runtime bound; or
§ 3.9 70
c
ISO/IEC N????
a class type (Clause 9) that has all of the following properties:
it has a trivial destructor,
it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template
that is not a copy or move constructor, and
all of its non-static data members and base classes are of non-volatile literal types.
11 If two types T1 and T2 are the same type, then T1 and T2 are layout-compatible types. [ Note: Layout-
compatible enumerations are described in 7.2. Layout-compatible standard-layout structs and standard-
layout unions are described in 9.2.— end note ]
3.9.1 Fundamental types [basic.fundamental]
1Objects 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 (3.11); that is, they have the same object representation. For narrow character types,
all bits of the object representation participate in the value representation. For unsigned narrow character
types, all possible bit patterns of the value representation represent numbers. 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.
2There 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 environment45; the other signed integer types are provided to meet special
needs.
3For each of the standard signed integer types, there exists a corresponding (but different) standard un-
signed 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 (3.11) as the corresponding signed integer type46; 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, 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.
4Unsigned integers shall obey the laws of arithmetic modulo 2nwhere nis the number of bits in the value
representation of that particular size of integer.47
5Type 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 (22.3.1). Type wchar_t shall have the same
45) that is, large enough to contain any value in the range of INT_MIN and INT_MAX, as defined in the header <climits>.
46) See 7.1.6.2 regarding the correspondence between types and the sequences of type-specifiers that designate them.
47) 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.
§ 3.9.1 71
c
ISO/IEC N????
size, signedness, and alignment requirements (3.11) 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.
6Values of type bool are either true or false.48 [Note: There are no signed,unsigned,short, or long
bool types or values. — end note ] Values of type bool participate in integral promotions (4.5).
7Types bool,char,char16_t,char32_t,wchar_t, and the signed and unsigned integer types are collectively
called integral types.49 A synonym for integral type is integer type. The representations of integral types
shall define values by use of a pure binary numeration system.50 [Example: this International Standard
permits 2’s complement, 1’s complement and signed magnitude representations for integral types. — end
example ]
8There 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. Integral and floating types are collectively called arithmetic
types. Specializations of the standard template std::numeric_limits (18.3) shall specify the maximum
and minimum values of each arithmetic type for an implementation.
9The void type has an empty set of values. The void type is an incomplete type that cannot be completed. 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 (5.4). An expression of type void shall be used only as an expression statement (6.2), as an
operand of a comma expression (5.18), as a second or third operand of ?: (5.16), as the operand of typeid,
noexcept, or decltype, as the expression in a return statement (6.6.3) for a function with the return type
void, or as the operand of an explicit conversion to type cv void.
10 A value of type std::nullptr_t is a null pointer constant (4.10). Such values participate in the pointer and
the pointer to member conversions (4.10,4.11). sizeof(std::nullptr_t) shall be equal to sizeof(void*).
11 [Note: Even if the implementation defines two or more basic types to have the same value representation,
they are nevertheless different types. — end note ]
3.9.2 Compound types [basic.compound]
1Compound types can be constructed in the following ways:
arrays of objects of a given type, 8.3.4;
functions, which have parameters of given types and return void or references or objects of a given
type, 8.3.5;
pointers to void or objects or functions (including static members of classes) of a given type, 8.3.1;
references to objects or functions of a given type, 8.3.2. There are two types of references:
lvalue reference
rvalue reference
classes containing a sequence of objects of various types (Clause 9), a set of types, enumerations and
functions for manipulating these objects (9.3), and a set of restrictions on the access to these entities
(Clause 11);
unions, which are classes capable of containing objects of different types at different times, 9.5;
48) 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.
49) Therefore, enumerations (7.2) are not integral; however, enumerations can be promoted to integral types as specified in 4.5.
50) 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.)
§ 3.9.2 72
c
ISO/IEC N????
enumerations, which comprise a set of named constant values. Each distinct enumeration constitutes
a different enumerated type,7.2;
pointers to non-static 51 class members, which identify members of a given type within objects of a
given class, 8.3.3.
2These methods of constructing types can be applied recursively; restrictions are mentioned in 8.3.1,8.3.4,
8.3.5, and 8.3.2. Constructing a type such that the number of bytes in its object representation exceeds the
maximum value representable in the type std::size_t (18.2) is ill-formed.
3The type of a pointer to 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 Tis 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 Xis 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 (3.11).
A valid value of an object pointer type represents either the address of a byte in memory (1.7) or a null
pointer (4.10). If an object of type Tis located at an address A, a pointer of type cv T* whose value is the
address Ais said to point to that object, regardless of how the value was obtained. [ Note: For instance,
the address one past the end of an array (5.7) would be considered to point to an unrelated object of the
array’s element type that might be located at that address. There are further restrictions on pointers to
objects with dynamic storage duration; see 3.7.4.3.— end note ] The value representation of pointer types
is implementation-defined. Pointers to cv-qualified and cv-unqualified versions (3.9.3) of layout-compatible
types shall have the same value representation and alignment requirements (3.11). [ Note: Pointers to
over-aligned types (3.11) have no special representation, but their range of valid values is restricted by the
extended alignment requirement. This International Standard specifies only two ways of obtaining such a
pointer: taking the address of a valid object with an over-aligned type, and using one of the runtime pointer
alignment functions. An implementation may provide other means of obtaining a valid pointer value for an
over-aligned type. — end note ]
4A pointer to cv-qualified (3.9.3) 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*.
3.9.3 CV-qualifiers [basic.type.qualifier]
1A type mentioned in 3.9.1 and 3.9.2 is a cv-unqualified type. Each type which is a cv-unqualified complete
or incomplete object type or is void (3.9) has three corresponding cv-qualified versions of its type: a const-
qualified version, a volatile-qualified version, and a const-volatile-qualified version. The term object type (1.8)
includes the cv-qualifiers specified in the decl-specifier-seq (7.1), declarator (Clause 8), type-id (8.1), or new-
type-id (5.3.4) 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 (3.11).52
51) Static class members are objects or functions, and pointers to them are ordinary pointers to objects or functions.
52) 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.
§ 3.9.3 73
c
ISO/IEC N????
2A compound type (3.9.2) is not cv-qualified by the cv-qualifiers (if any) of the types from which it is com-
pounded. Any cv-qualifiers applied to an array type affect the array element type, not the array type (8.3.4).
3See 8.3.5 and 9.3.2 regarding function types that have cv-qualifiers.
4There is a partial ordering on cv-qualifiers, so that a type can be said to be more cv-qualified than another.
Table 9shows the relations that constitute this ordering.
Table 9 — Relations on const and volatile
no cv-qualifier <const
no cv-qualifier <volatile
no cv-qualifier <const volatile
const <const volatile
volatile <const volatile
5In 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.
Cv-qualifiers applied to an array type attach to the underlying element type, so the notation “cv T,” where
Tis 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 ]
3.10 Lvalues and rvalues [basic.lval]
1Expressions are categorized according to the taxonomy in Figure 1.
expression
glvalue rvalue
lvalue xvalue prvalue
Figure 1 — Expression category taxonomy
An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment
expression) designates a function or an object. [ Example: If Eis an expression of pointer type, then
*E is an lvalue expression referring to the object or function to which Epoints. As another example,
the result of calling a function whose return type is an lvalue reference is an lvalue. — end example ]
An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its
resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving
rvalue references (8.3.2). [ Example: The result of calling a function whose return type is an rvalue
reference is an xvalue. — end example ]
§ 3.10 74
c
ISO/IEC N????
A glvalue (“generalized” lvalue) is an lvalue or an xvalue.
An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment
expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated
with an object.
A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [ Example: The result of calling a function
whose return type is not a reference is a prvalue. The value of a literal such as 12,7.3e5, or true is
also a prvalue. — end example ]
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 5indicates 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 ]
2Whenever a glvalue appears in a context where a prvalue is expected, the glvalue is converted to a prvalue;
see 4.1,4.2, and 4.3. [ Note: An attempt to bind an rvalue reference to an lvalue is not such a context;
see 8.5.3.— end note ]
3The discussion of reference initialization in 8.5.3 and of temporaries in 12.2 indicates the behavior of lvalues
and rvalues in other significant contexts.
4Unless otherwise indicated (5.2.2), prvalues shall always have complete types or the void type; in addition to
these types, glvalues can also have incomplete types. [ Note: class and array prvalues can have cv-qualified
types; other prvalues always have cv-unqualified types. See Clause 5.— end note ]
5An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can
also be used to modify its referent under certain circumstances. [ Example: a member function called for an
object (9.3) can modify the object. — end example ]
6Functions cannot be modified, but pointers to functions can be modifiable.
7A pointer to an incomplete type can be modifiable. At some point in the program when the pointed to type
is complete, the object at which the pointer points can also be modified.
8The referent of a const-qualified expression shall not be modified (through that expression), except that if
it is of class type and has a mutable component, that component can be modified (7.1.6.1).
9If an expression can be used to modify the object to which it refers, the expression is called modifiable. A
program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is ill-formed.
10 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:53
the dynamic type of the object,
a cv-qualified version of the dynamic type of the object,
a type similar (as defined in 4.4) 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),
53) The intent of this list is to specify those circumstances in which an object may or may not be aliased.
§ 3.10 75
c
ISO/IEC N????
a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
a char or unsigned char type.
3.11 Alignment [basic.align]
1Object types have alignment requirements (3.9.1,3.9.2) 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 (7.6.2).
2Afundamental alignment is represented by an alignment less than or equal to the greatest alignment sup-
ported by the implementation in all contexts, which is equal to alignof(std::max_align_t) (18.2). 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 Dis 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 Dappears as a subobject of another object that also has Bas a virtual
base class, the Bsubobject might be part of a different subobject, reducing the alignment requirements on
the Dsubobject. — end example ] The result of the alignof operator reflects the alignment requirement of
the type in the complete-object case.
3An 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 (7.6.2). 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 ]
4Alignments 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.
5Alignments 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.
6The alignment requirement of a complete type can be queried using an alignof expression (5.3.6). Further-
more, the narrow character types (3.9.1) 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 (7.6.2). — end
note ]
7Comparing 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.
8[Note: The runtime pointer alignment function (20.8.5) can be used to obtain an aligned pointer within a
buffer; the aligned-storage templates in the library (20.11.7.6) can be used to obtain aligned storage. — end
note ]
9If a request for a specific extended alignment in a specific context is not supported by an implementation,
the program is ill-formed. Additionally, a request for runtime allocation of dynamic storage for which the
requested alignment cannot be honored shall be treated as an allocation failure.
§ 3.11 76
c
ISO/IEC N????
4 Standard conversions [conv]
1Standard conversions are implicit conversions with built-in meaning. Clause 4enumerates 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 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.
2[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 desti-
nation type (Clause 5).
When used in the condition of an if statement or iteration statement (6.4,6.5). The destination type
is bool.
When used in the expression of a switch statement. The destination type is integral (6.4).
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. See 8.5,8.5.3.
— end note ]
3An expression ecan be implicitly converted to a type Tif and only if the declaration T t=e; is well-formed,
for some invented temporary variable t(8.5).
4Certain 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(8.5).
5Certain language constructs require conversion to a value having one of a specified set of types appropriate
to the construct. An expression eof class type Eappearing in such a context is said to be contextually
implicitly converted to a specified type Tand is well-formed if and only if ecan be implicitly converted to
a type Tthat is determined as follows: Eis searched for conversion functions whose return type is cv Tor
reference to cv Tsuch that Tis allowed by the context. There shall be exactly one such T.
6The effect of any implicit conversion is the same as performing the corresponding declaration and initializa-
tion and then using the temporary variable as the result of the conversion. The result is an lvalue if Tis an
lvalue reference type or an rvalue reference to function type (8.3.2), an xvalue if Tis an rvalue reference to
object type, and a prvalue otherwise. The expression eis used as a glvalue if and only if the initialization
uses it as a glvalue.
7[Note: For class types, user-defined conversions are considered as well; see 12.3. In general, an implicit con-
version sequence (13.3.3.1) consists of a standard conversion sequence followed by a user-defined conversion
followed by another standard conversion sequence. — end note ]
Standard conversions 77
c
ISO/IEC N????
8[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 ]
4.1 Lvalue-to-rvalue conversion [conv.lval]
1A glvalue (3.10) of a non-function, non-array type Tcan be converted to a prvalue.54 If Tis an incomplete
type, a program that necessitates this conversion is ill-formed. If Tis a non-class type, the type of the
prvalue is the cv-unqualified version of T. Otherwise, the type of the prvalue is T.55
2When an lvalue-to-rvalue conversion occurs in an unevaluated operand or a subexpression thereof (Clause 5)
the value contained in the referenced object is not accessed. In all other cases, the result of the conversion
is determined according to the following rules:
If Tis (possibly cv-qualified) std::nullptr_t, the result is a null pointer constant (4.10).
Otherwise, if Thas a class type, the conversion copy-initializes a temporary of type Tfrom the glvalue
and the result of the conversion is a prvalue for the temporary.
Otherwise, if the object to which the glvalue refers contains an invalid pointer value (3.7.4.2,3.7.4.3),
the behavior is implementation-defined.
Otherwise, if Tis a (possibly cv-qualified) unsigned character type (3.9.1), and the object to which
the glvalue refers contains an indeterminate value (5.3.4,8.5,12.6.2), and that object does not have
automatic storage duration or the glvalue was the operand of a unary &operator or it was bound to a
reference, the result is an unspecified value.56
Otherwise, if the object to which the glvalue refers contains an indeterminate value, the behavior is
undefined.
Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.
3[Note: See also 3.10.— end note ]
4.2 Array-to-pointer conversion [conv.array]
1An expression of type “array of N T”, “array of runtime bound of T”, or “array of unknown bound of T” can
be converted to a prvalue of type “pointer to T. The result is a pointer to the first element of the array.
4.3 Function-to-pointer conversion [conv.func]
1An lvalue of function type Tcan be converted to a prvalue of type “pointer to T.” The result is a pointer to
the function.57
2[Note: See 13.4 for additional rules for the case where the function is overloaded. — end note ]
4.4 Qualification conversions [conv.qual]
1A 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.
2A prvalue of type “pointer to member of Xof type cv1 T” can be converted to a prvalue of type “pointer to
member of Xof type cv2 T” if “cv2 T” is more cv-qualified than “cv1 T.
54) 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 3.10.
55) In C++ class prvalues can have cv-qualified types (because they are objects). This differs from ISO C, in which non-lvalues
never have cv-qualified types.
56) The value may be different each time the lvalue-to-rvalue conversion is applied to the object. An unsigned char object
with indeterminate value allocated to a register might trap.
57) This conversion never applies to non-static member functions because an lvalue that refers to a non-static member function
cannot be obtained.
§ 4.4 78
c
ISO/IEC N????
3[Note: Function types (including those used in pointer to member function types) are never cv-qualified (8.3.5).
— end note ]
4A conversion can add cv-qualifiers at levels other than the first in multi-level pointers, subject to the following
rules:58
Two pointer types T1 and T2 are similar if there exists a type Tand integer n > 0such that:
T1 is cv1,0pointer to cv1,1pointer to ··· cv1,n1pointer to cv1,n T
and
T2 is cv2,0pointer to cv2,1pointer to ··· cv2,n1pointer to cv2,n T
where each cvi,j is const,volatile,const volatile, or nothing. The n-tuple of cv-qualifiers after the
first in a pointer type, e.g., cv1,1,cv1,2,···,cv1,n in the pointer type T1 , is called the cv-qualification
signature of the pointer type. An expression of type T1 can be converted to type T2 if and only if the
following conditions are satisfied:
the pointer types are similar.
for every j > 0, if const is in cv1,j then const is in cv2,j , and similarly for volatile.
if the cv1,j and cv2,j are different, then const is in every cv2,k for 0< k < j.
[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 ]
5Amulti-level pointer to member type, or a multi-level mixed pointer and pointer to member type has the
form:
cv0P0to cv1P1to ··· cvn1Pn1to cvnT
where Piis either a pointer or pointer to member and where Tis not a pointer type or pointer to member
type.
6Two multi-level pointer to member types or two multi-level mixed pointer and pointer to member types T1
and T2 are similar if there exists a type Tand integer n > 0such that:
T1 is cv1,0P0to cv1,1P1to ··· cv1,n1Pn1to cv1,n T
and
T2 is cv2,0P0to cv2,1P1to ··· cv2,n1Pn1to cv2,n T
7For similar multi-level pointer to member types and similar multi-level mixed pointer and pointer to member
types, the rules for adding cv-qualifiers are the same as those used for similar pointer types.
58) These rules ensure that const-safety is preserved by the conversion.
§ 4.4 79
c
ISO/IEC N????
4.5 Integral promotions [conv.prom]
1A prvalue of an integer type other than bool,char16_t,char32_t, or wchar_t whose integer conversion
rank (4.13) 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.
2A prvalue of type char16_t,char32_t, or wchar_t (3.9.1) 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.
3A prvalue of an unscoped enumeration type whose underlying type is not fixed (7.2) 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 bmin to bmax as described in 7.2): 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 (4.13) 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.
4A prvalue of an unscoped enumeration type whose underlying type is fixed (7.2) 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.
5A prvalue for an integral bit-field (9.6) 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.
6A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true
becoming one.
7These conversions are called integral promotions.
4.6 Floating point promotion [conv.fpprom]
1A prvalue of type float can be converted to a prvalue of type double. The value is unchanged.
2This conversion is called floating point promotion.
4.7 Integral conversions [conv.integral]
1A 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.
2If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source
integer (modulo 2nwhere nis 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 ]
3If the destination type is signed, the value is unchanged if it can be represented in the destination type (and
bit-field width); otherwise, the value is implementation-defined.
4If the destination type is bool, see 4.12. If the source type is bool, the value false is converted to zero and
the value true is converted to one.
5The conversions allowed as integral promotions are excluded from the set of integral conversions.
4.8 Floating point conversions [conv.double]
1A 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.
§ 4.8 80
c
ISO/IEC N????
2The conversions allowed as floating point promotions are excluded from the set of floating point conversions.
4.9 Floating-integral conversions [conv.fpint]
1A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion trun-
cates; 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 4.12.— end note ]
2A 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.
4.10 Pointer conversions [conv.ptr]
1Anull pointer constant is an integer literal (2.14.2) 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 (4.4). 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 ]
2A prvalue of type “pointer to cv T,” where Tis an object type, can be converted to a prvalue of type “pointer
to cv void. The result of converting a non-null pointer value of a pointer to object type to a “pointer to
cv void” represents the address of the same byte in memory as the original pointer value. The null pointer
value is converted to the null pointer value of the destination type.
3A prvalue of type “pointer to cv D”, where Dis a class type, can be converted to a prvalue of type “pointer
to cv B”, where Bis a base class (Clause 10) of D. If Bis an inaccessible (Clause 11) or ambiguous (10.2)
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.
4.11 Pointer to member conversions [conv.mem]
1A null pointer constant (4.10) 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 (4.4).
2A prvalue of type “pointer to member of Bof type cv T”, where Bis a class type, can be converted to a
prvalue of type “pointer to member of Dof type cv T”, where Dis a derived class (Clause 10) of B. If Bis an
inaccessible (Clause 11), ambiguous (10.2), or virtual (10.1) 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 Dof type cv T”, indirection through it with a Dobject is
valid. The result is the same as if indirecting through the pointer to member of Bwith the Bsubobject of
§ 4.11 81
c
ISO/IEC N????
D. The null member pointer value is converted to the null member pointer value of the destination type.59
4.12 Boolean conversions [conv.bool]
1A 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 (8.5), a prvalue of type std::nullptr_t can
be converted to a prvalue of type bool; the resulting value is false.
4.13 Integer conversion rank [conv.rank]
1Every 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 (3.9.1).
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 (4.5) and the
usual arithmetic conversions (Clause 5). — end note ]
59) 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) (4.10, Clause 10). 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*.
§ 4.13 82
c
ISO/IEC N????
5 Expressions [expr]
1[Note: Clause 5defines the syntax, order of evaluation, and meaning of expressions.60 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 ]
2[Note: Operators can be overloaded, that is, given meaning when applied to expressions of class type (Clause
9) or enumeration type (7.2). Uses of overloaded operators are transformed into function calls as described
in 13.5. Overloaded operators obey the rules for syntax specified in Clause 5, but the requirements of
operand type, value category, and evaluation order are replaced by the rules for function call. Relations
between operators, such as ++a meaning a+=1, are not guaranteed for overloaded operators (13.5), and are
not guaranteed for operands of type bool.— end note ]
3Clause 5defines 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 5;
see 13.3.1.2,13.6.
4If 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: most existing implementations of C++
ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all
floating point exceptions vary among machines, and is usually adjustable by a library function. — end note ]
5If an expression initially has the type “reference to T” (8.3.2,8.5.3), the type is adjusted to Tprior 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.
6If a prvalue initially has the type “cv T,” where Tis a cv-unqualified non-class, non-array type, the type of
the expression is adjusted to Tprior to any further analysis.
7[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);
60) The precedence of operators is not directly specified, but it can be derived from the syntax.
Expressions 83
c
ISO/IEC N????
A&& f();
A a;
A&& ar = static_cast<A&&>(a);
The expressions f(),f().m,static_cast<A&&>(a), and a+aare xvalues. The expression ar is an
lvalue. — end example ]
8In some contexts, unevaluated operands appear (5.2.8,5.3.3,5.3.7,7.1.6.2). An unevaluated operand is not
evaluated. An unevaluated operand is considered a full-expression. [ Note: In an unevaluated operand, a
non-static class member may be named (5.1) and naming of objects or functions does not, by itself, require
that a definition be provided (3.2). — end note ]
9Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand,
the lvalue-to-rvalue (4.1), array-to-pointer (4.2), or function-to-pointer (4.3) 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 ]
10 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 (7.2), 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 (4.5) shall be performed on both operands.61 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.
11 In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value
expression. The expression is evaluated and its value is discarded. The array-to-pointer (4.2) and function-
to-pointer (4.3) standard conversions are not applied. The lvalue-to-rvalue conversion (4.1) is applied if and
only if the expression is an lvalue of volatile-qualified type and it is one of the following:
61) As a consequence, operands of type bool,char16_t,char32_t,wchar_t, or an enumerated type are converted to some
integral type.
Expressions 84
c
ISO/IEC N????
(expression ), where expression is one of these expressions,
id-expression (5.1.1),
subscripting (5.2.1),
class member access (5.2.5),
indirection (5.3.1),
pointer-to-member operation (5.5),
conditional expression (5.16) where both the second and the third operands are one of these expressions,
or
comma expression (5.18) where the right operand is one of these expressions.
[Note: Using an overloaded operator causes a function call; the above covers only operators with built-in
meaning. If the lvalue is of class type, it must have a volatile copy constructor to initialize the temporary
that is the result of the lvalue-to-rvalue conversion. — end note ]
12 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.62
13 The cv-combined type of two types T1 and T2 is a type T3 similar to T1 whose cv-qualification signature (4.4)
is:
for every j > 0,cv3,j is the union of cv1,j and cv2,j ;
if the resulting cv3,j is different from cv1,j or cv2,j , then const is added to every cv3,k for 0< k < j.
[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”, “pointer to cv12 void”,
where cv12 is the union of cv1 and cv2 ;
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 (8.5.3), 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 (8.5.3), the cv-combined type of T2
and T1 or the cv-combined type of T1 and T2, respectively;
if T1 and T2 are similar multi-level mixed pointer and pointer to member types (4.4), the cv-combined
type of T1 and T2;
otherwise, a program that necessitates the determination of a composite pointer type is ill-formed.
[Example:
62) The cast and assignment operators must still perform their specific conversions as described in 5.4,5.2.9 and 5.17.
Expressions 85
c
ISO/IEC N????
typedef void *p;
typedef const int *q;
typedef int **pi;
typedef const int **pci;
The composite pointer type of pand qis “pointer to const void”; the composite pointer type of pi and
pci is “pointer to const pointer to const int. — end example ]
5.1 Primary expressions [expr.prim]
5.1.1 General [expr.prim.general]
primary-expression:
literal
this
(expression )
id-expression
lambda-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
1Aliteral is a primary expression. Its type depends on its form (2.14). A string literal is an lvalue; all other
literals are prvalues.
2The keyword this names a pointer to the object for which a non-static member function (9.3.2) is invoked
or a non-static data member’s initializer (9.2) is evaluated.
3If 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-qualifer-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 (5.2.5) 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 ]
4Otherwise, if a member-declarator declares a non-static data member (9.2) of a class X, the expression this
is a prvalue of type “pointer to X” within the optional brace-or-equal-initializer. It shall not appear elsewhere
in the member-declarator.
5The expression this shall not appear in any other context. [ Example:
§ 5.1.1 86
c
ISO/IEC N????
class Outer {
int a[sizeof(*this)]; // error: not inside a member function
unsigned int sz = sizeof(*this); // OK: in brace-or-equal-initializer
void f() {
int b[sizeof(*this)]; // OK
struct Inner {
int c[sizeof(*this)]; // error: not inside a member function of Inner
};
}
};
— end example ]
6A parenthesized expression is a primary expression whose type and value are identical to those of the
enclosed expression. The presence of parentheses does not affect whether the expression is an lvalue. The
parenthesized expression can be used in exactly the same contexts as those where the enclosed expression
can be used, and with the same meaning, except as otherwise indicated.
7An id-expression is a restricted form of a primary-expression. [ Note: an id-expression can appear after .
and -> operators (5.2.5). — end note ]
8An identifier is an id-expression provided it has been suitably declared (Clause 7). [ Note: for operator-
function-ids, see 13.5; for conversion-function-ids, see 12.3.2; for literal-operator-ids, see 13.5.8; for template-
ids, see 14.2. A class-name or decltype-specifier prefixed by ~denotes a destructor; see 12.4. 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 (9.3.1). — end note ] The type of the expression is the type of the identifier.
The result is the entity denoted by the identifier. The result is an lvalue if the entity is a function, variable,
or data member and a prvalue otherwise.
§ 5.1.1 87
c
ISO/IEC N????
qualified-id:
nested-name-specifier templateopt unqualified-id
nested-name-specifier:
::
type-name ::
namespace-name ::
decltype-specifier ::
nested-name-specifier identifier ::
nested-name-specifier templateopt simple-template-id ::
The type denoted by a decltype-specifier in a nested-name-specifier shall be a class or enumeration type.
9Anested-name-specifier that denotes a class, optionally followed by the keyword template (14.2), and then
followed by the name of a member of either that class (9.2) or one of its base classes (Clause 10), is a
qualified-id;3.4.3.1 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
aqualified-id at any point in its potential scope (3.3.7). — end note ] Where class-name ::~class-name is
used, the two class-names shall refer to the same class; this notation names the destructor (12.4). The form
~decltype-specifier also denotes the destructor, but it shall not be used as the unqualified-id in a qualified-id.
[Note: atypedef-name that names a class is a class-name (9.1). — end note ]
10 A::, or a nested-name-specifier that names a namespace (7.3), in either case 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;3.4.3.2 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.
11 Anested-name-specifier that denotes an enumeration (7.2), 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.
12 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.
13 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 (5.2.5) in which the object expression refers to the member’s class63
or a class derived from that class, or
to form a pointer to member (5.3.1), 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 ]
5.1.2 Lambda expressions [expr.prim.lambda]
1Lambda expressions provide a concise way to create simple function objects. [ Example:
63) This also applies when the object expression is an implicit (*this) (9.3.1).
§ 5.1.2 88
c
ISO/IEC N????
#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 ]
lambda-expression:
lambda-introducer lambda-declaratoropt compound-statement
lambda-introducer:
[lambda-captureopt ]
lambda-capture:
capture-default
capture-list
capture-default ,capture-list
capture-default:
&
=
capture-list:
capture ...opt
capture-list ,capture ...opt
capture:
simple-capture
init-capture
simple-capture:
identifier
&identifier
this
init-capture:
identifier initializer
&identifier initializer
lambda-declarator:
(parameter-declaration-clause ) mutableopt
exception-specificationopt attribute-specifier-seqopt trailing-return-typeopt
2The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the
closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A closure
object behaves like a function object (20.10). — end note ]
3The type of the 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. This class type is not
an aggregate (8.5.1). 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 (3.4.2). The parameter types of a lambda-declarator do not
affect these associated namespaces and classes. — end note ] 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 9),
whether the closure type is a standard-layout class (Clause 9), or
§ 5.1.2 89
c
ISO/IEC N????
whether the closure type is a POD class (Clause 9).
An implementation shall not add members of rvalue reference type to the closure type.
4If 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 trailing-return-type if provided and/or deduced from
return statements as described in 7.1.6.4. [ 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 ]
5The closure type for a non-generic lambda-expression has a public inline function call operator (13.5.4)
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 (14.5.2) 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 de-
clares a function parameter pack (8.3.5). 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 ] This function call operator or operator template is declared const (9.3.1) if and only if
the lambda-expression’s parameter-declaration-clause is not followed by mutable. It is neither virtual nor
declared volatile. Any exception-specification 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. [ Note: Names referenced in the
lambda-declarator are looked up in the context in which the lambda-expression appears. — end note ]
6The closure type for a non-generic lambda-expression with no lambda-capture has a public non-virtual non-
explicit const conversion function to pointer to function with C++ language linkage (7.5) having the same
parameter and return types as the closure type’s function call operator. The value returned by this conversion
function shall be the address of a function that, when invoked, has the same effect as invoking the closure
type’s function call operator. For a generic lambda with no lambda-capture, the closure type has a public
non-virtual non-explicit const 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
§ 5.1.2 90
c
ISO/IEC N????
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 func-
tion:
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 shall
be the address of a function that, when invoked, has the same effect as invoking the generic lambda’s corre-
sponding function call operator template specialization. [ 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 ]
7The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator,
but for purposes of name lookup (3.4), determining the type and value of this (9.3.2) and transforming id-
expressions referring to non-static class members into class member access expressions using (*this) (9.3.1),
the compound-statement is considered in the context of the lambda-expression. [ Example:
§ 5.1.2 91
c
ISO/IEC N????
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 ]
8If 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. 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: ipreceded by &when &is the default
[=, this]{ }; // error: this when =is the default
[i, i]{ }; // error: irepeated
}
— end example ]
9Alambda-expression whose smallest enclosing scope is a block scope (3.3.3) 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 ]
10 The identifier in a simple-capture is looked up using the usual rules for unqualified name lookup (3.4.1);
each such lookup shall find a variable with automatic storage duration declared in the reaching scope of the
local lambda expression. An entity (i.e. a variable or this) is said to be explicitly captured if it is found by
this process.
11 For every init-capture a non-static data member named by the identifier of the init-capture is declared in
the closure type. This member is not a bit-field and not mutable. The type of that member corresponds to
the type of a hypothetical variable declaration of the form “auto init-capture ;”, except that the variable
name (i.e., the identifier of the init-capture) is replaced by a unique identifier. [ 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 ] No entity is captured by an init-capture. Within the lambda-expressionslambda-declarator and
compound-statement, the identifier in the init-capture hides any declaration of the same name in scopes
enclosing the lambda-expression. [ Example:
int x = 4;
auto y = [&r = x, x = x+1]()->int {
r += 2;
return x+2;
}(); // Updates ::x to 6, and initializes yto 7.
— end example ]
12 Alambda-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:
§ 5.1.2 92
c
ISO/IEC N????
odr-uses (3.2) the entity, or
names the entity in a potentially-evaluated expression (3.2) where the enclosing full-expression depends
on a generic lambda parameter declared within the reaching scope of the lambda-expression.
[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 ]
13 An entity is captured if it is captured explicitly or implicitly. An entity captured by a lambda-expression
is odr-used (3.2) 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 (3.2)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: Nand Mare not odr-used
x[0][0] = i; // OK: iis 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: jnot captured by m3
int x = n; // error: nimplicitly captured by m4
// but not captured by m3
x += m; // OK: mimplicitly captured by m4
// and explicitly captured by m3
x += i; // error: iis outside of the reaching scope
x += f; // OK: this captured implicitly by m4
§ 5.1.2 93
c
ISO/IEC N????
// and explicitly by m3
};
};
}
};
}
— end example ]
14 Alambda-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 ]
15 An entity is captured by copy if it is implicitly captured and the capture-default is =or if it is explicitly
captured with a capture that does not include an &. 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 type of the corresponding captured entity if the entity is not a
reference to an object, or the referenced type otherwise. [ Note: If the captured entity is a reference to a
function, the corresponding data member is also a reference to a function. — end note ] An array of runtime
bound (8.3.4) shall not be captured by copy.
16 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. [ Note: Capturing by reference an array of runtime bound also implicitly captures
the value of the bound to support the range-based for statement (6.5.4). — end note ]
17 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.
inta=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;
§ 5.1.2 94
c
ISO/IEC N????
— end example ]
18 Every id-expression that is an odr-use (3.2) 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, each odr-use of this
is transformed into an access to the corresponding unnamed data member of the closure type, cast (5.4)
to the type of this. [ Note: The cast ensures that the transformed expression is a prvalue. — 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 Nto be captured; &N points to the
// corresponding member of the closure type
};
}
— end example ]
19 Every occurrence of decltype((x)) where xis a possibly parenthesized id-expression that names an entity
of automatic storage duration is treated as if xwere transformed into an access to a corresponding data
member of the closure type that would have been declared if xwere an odr-use of the denoted entity.
[Example:
void f3() {
float x, &r = x;
[=] { // xand rare 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 xis an lvalue
decltype(r) r1 = y1; // r1 has type float& (transformation not considered)
decltype((r)) r2 = y2; // r2 has type float const&
};
}
— end example ]
20 The closure type associated with a lambda-expression has a deleted (8.4.3) default constructor and a deleted
copy assignment operator. It has an implicitly-declared copy constructor (12.8) and may have an implicitly-
declared move constructor (12.8). [ Note: The copy/move constructor is implicitly defined in the same way
as any other implicitly declared copy/move constructor would be implicitly defined. — end note ]
21 The closure type associated with a lambda-expression has an implicitly-declared destructor (12.4).
22 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 ]
23 [Note: If an 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 ]
24 Asimple-capture followed by an ellipsis is a pack expansion (14.5.3). An init-capture followed by an ellipsis
is ill-formed. [ Example:
§ 5.1.2 95
c
ISO/IEC N????
template<class... Args>
void f(Args... args) {
auto lm = [&, args...] { return g(args...); };
lm();
}
— end example ]
5.2 Postfix expressions [expr.post]
1Postfix expressions group left-to-right.
postfix-expression:
primary-expression
postfix-expression [expression ]
postfix-expression [braced-init-list ]
postfix-expression (expression-listopt )
simple-type-specifier (expression-listopt )
typename-specifier (expression-listopt )
simple-type-specifier braced-init-list
typename-specifier braced-init-list
postfix-expression . templateopt id-expression
postfix-expression -> templateopt 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-specifieropt type-name :: ~type-name
nested-name-specifier template simple-template-id :: ~type-name
nested-name-specifieropt ~type-name
~decltype-specifier
2[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 (14.2). — end note ]
5.2.1 Subscripting [expr.sub]
1A postfix expression followed by an expression in square brackets is a postfix expression. One of the ex-
pressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration
or integral type. The result is of type “T.” The type “T” shall be a completely-defined object type.64 The
expression E1[E2] is identical (by definition) to *((E1)+(E2)) [Note: see 5.3 and 5.7 for details of *and
+and 8.3.4 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.
2Abraced-init-list shall not be used with the built-in subscript operator.
5.2.2 Function call [expr.call]
1There are two kinds of function call: ordinary function call and member function65 (9.3) call. A function
call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of
64) This is true even if the subscript operator is used in the following common idiom: &x[0].
65) A static member function (9.4) is an ordinary function.
§ 5.2.2 96
c
ISO/IEC N????
initializer-clauses which constitute the arguments to the function. For an ordinary function call, the postfix
expression shall be either an lvalue that refers to a function (in which case the function-to-pointer standard
conversion (4.3) is suppressed on the postfix expression), or it shall have pointer to function type. Calling
a function through an expression whose function type has a language linkage that is different from the
language linkage of the function type of the called function’s definition is undefined (7.5). For a member
function call, the postfix expression shall be an implicit (9.3.1,9.4) or explicit class member access (5.2.5)
whose id-expression is a function member name, or a pointer-to-member expression (5.5) 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 9.3.1). — end note ] If a function or member function
name is used, the name can be overloaded (Clause 13), in which case the appropriate function shall be
selected according to the rules in 13.3. 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 (10.3)
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.
12.7 describes the behavior of virtual function calls when the object expression refers to an object under
construction or destruction. — end note ]
2[Note: If a function or member function name is used, and name lookup (3.4) does not find a declaration of
that name, the program is ill-formed. No function is implicitly declared by such a call. — end note ]
3If the postfix-expression designates a destructor (12.4), 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.
4When a function is called, each parameter (8.3.5) shall be initialized (8.5,12.8,12.1) with its corresponding
argument. [ Note: Such initializations are indeterminately sequenced with respect to each other (1.9)
end note ] If the function is a non-static member function, the this parameter of the function (9.3.2) shall
be initialized with a pointer to the object of the call, converted as if by an explicit type conversion (5.4).
[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. See 10.2,11.2, and 5.2.5.
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 ] During
the initialization of a parameter, an implementation may avoid the construction of extra temporaries by
combining the conversions on the associated argument and/or the construction of temporaries with the
initialization of the parameter (see 12.2). The lifetime of a parameter ends when the function in which it
is defined returns. 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 15) with a handler that could handle the exception, this handler is
not considered. — end example ] The value of a function call is the value returned by the called function
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.
5[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 (8.3.2); 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 (7.1.6,2.14,2.14.5,8.3.4,12.2). In addition, it is possible to modify the values of nonconstant objects
through pointer parameters. — end note ]
6A function can be declared to accept fewer arguments (by declaring default arguments (8.3.6)) or more
§ 5.2.2 97
c
ISO/IEC N????
arguments (by using the ellipsis, ..., or a function parameter pack (8.3.5)) than the number of parameters
in the function definition (8.4). [ Note: this implies that, except where the ellipsis (...) or a function
parameter pack is used, a parameter is available for each argument. — end note ]
7When 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 (18.10). [ Note: This paragraph does not
apply to arguments passed to a function parameter pack. Function parameter packs are expanded during
template instantiation (14.5.3), thus each such argument has a corresponding parameter when a function
template specialization is actually called. — end note ] The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and
function-to-pointer (4.3) standard conversions are performed on the argument expression. An argument that
has (possibly cv-qualified) type std::nullptr_t is converted to type void* (4.10). 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 9) 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 (4.5), or a floating point type that is subject
to the floating point promotion (4.6), the value of the argument is converted to the promoted type before
the call. These promotions are referred to as the default argument promotions.
8[Note: The evaluations of the postfix expression and of the arguments are all unsequenced relative to one
another. All side effects of argument evaluations are sequenced before the function is entered (see 1.9).
— end note ]
9Recursive calls are permitted, except to the function named main (3.6.1).
10 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.
11 If a function call is a prvalue of object type:
if the function call is either
the operand of a decltype-specifier or
the right operand of a comma operator that is the operand of a decltype-specifier,
a temporary object is not introduced 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. This is true regardless of
whether the expression uses function call notation or operator notation (13.3.1.2). — end note ] [ Note:
unlike the rule for a decltype-specifier that considers whether an id-expression is parenthesized (7.1.6.2),
parentheses have no special meaning in this context. — end note ]
otherwise, the type of the prvalue shall be complete.
5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
1Asimple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list
constructs a value of the specified type given the expression list. If the expression list is a single expression,
the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding
cast expression (5.4). If the type specified is a class type, the class type shall be complete. If the expression
list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5,12.1),
and the expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some
invented temporary variable t, with the result being the value of tas a prvalue.
2The expression T(), where Tis a simple-type-specifier or typename-specifier for a non-array complete object
type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, whose value is that
produced by value-initializing (8.5) an object of type T; no initialization is done for the void() case. [ Note:
if Tis a non-class type that is cv-qualified, the cv-qualifiers are discarded when determining the type of the
resulting prvalue (Clause 5). — end note ]
§ 5.2.3 98
c
ISO/IEC N????
3Similarly, a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary
object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list, and its value is
that temporary object as a prvalue.
5.2.4 Pseudo destructor call [expr.pseudo]
1The 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.
2The 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-specifieropt type-name :: ~type-name
shall designate the same scalar type.
5.2.5 Class member access [expr.ref]
1A postfix expression followed by a dot .or an arrow ->, optionally followed by the keyword template (14.2),
and then followed by an id-expression, is a postfix expression. The postfix expression before the dot or arrow
is evaluated;66 the result of that evaluation, together with the id-expression, determines the result of the
entire postfix expression.
2For the first option (dot) the first expression shall have complete class type. For the second option (arrow)
the first expression shall have pointer to complete class type. The expression E1->E2 is converted to the
equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot).67 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 9), the name of a class is also considered a nested member
of that class. — end note ] [ Note: 3.4.5 describes how names are looked up after the .and -> operators.
— end note ]
3Abbreviating postfix-expression.id-expression as E1.E2,E1 is called the object expression. The type and
value category of E1.E2 are determined as follows. In the remainder of 5.2.5,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 3.9.3.
4If 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 (13.3) is used to deter-
mine 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
66) 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.
67) Note that (*(E1)) is an lvalue.
§ 5.2.5 99
c
ISO/IEC N????
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-qualifieropt 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 (9.3). [ Note: Any redundant set of parentheses surrounding
the expression is ignored (5.1). — 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.
5If 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 (10.2) of the naming class (11.2) 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 11.2.— end note ]
5.2.6 Increment and decrement [expr.post.incr]
1The 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 or a pointer to a complete object type. The value of the operand object is modified by
adding 1to it, unless the object is of type bool, in which case it is set to true. [ Note: this use is deprecated,
see Annex D.— end note ] 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. See also 5.7 and 5.17.
2The operand of postfix -- is decremented analogously to the postfix ++ operator, except that the operand
shall not be of type bool. [ Note: For prefix increment and decrement, see 5.3.2.— end note ]
5.2.7 Dynamic cast [expr.dynamic.cast]
1The result of the expression dynamic_cast<T>(v) is the result of converting the expression vto 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 (5.2.11).
2If Tis a pointer type, vshall be a prvalue of a pointer to complete class type, and the result is a prvalue
of type T. If Tis an lvalue reference type, vshall be an lvalue of a complete class type, and the result is
an lvalue of the type referred to by T. If Tis an rvalue reference type, vshall be an expression having a
complete class type, and the result is an xvalue of the type referred to by T.
3If the type of vis the same as T, or it is the same as Texcept that the class object type in Tis more
cv-qualified than the class object type in v, the result is v(converted if necessary).
4If the value of vis a null pointer value in the pointer case, the result is the null pointer value of type T.
5If Tis “pointer to cv1 B” and vhas type “pointer to cv2 D” such that Bis a base class of D, the result is a
pointer to the unique Bsubobject of the Dobject pointed to by v. Similarly, if Tis “reference to cv1 B” and
vhas type cv2 Dsuch that Bis a base class of D, the result is the unique Bsubobject of the Dobject referred
to by v.68 The result is an lvalue if Tis an lvalue reference, or an xvalue if Tis an rvalue reference. In
both the pointer and reference cases, the program is ill-formed if cv2 has greater cv-qualification than cv1
or if Bis an inaccessible or ambiguous base class of D. [ Example:
68) The most derived object (1.8) pointed or referred to by vcan contain other Bobjects as base classes, but these are ignored.
§ 5.2.7 100
c
ISO/IEC N????
struct B { };
struct D : B { };
void foo(D* dp) {
B* bp = dynamic_cast<B*>(dp); // equivalent to B* bp = dp;
}
— end example ]
6Otherwise, vshall be a pointer to or a glvalue of a polymorphic type (10.3).
7If Tis “pointer to cv void,” then the result is a pointer to the most derived object pointed to by v. Otherwise,
a run-time check is applied to see if the object pointed or referred to by vcan be converted to the type
pointed or referred to by T.
8If Cis the class type to which Tpoints or refers, the run-time check logically executes as follows:
If, in the most derived object pointed (referred) to by v,vpoints (refers) to a public base class
subobject of a Cobject, and if only one object of type Cis derived from the subobject pointed (referred)
to by vthe result points (refers) to that Cobject.
Otherwise, if vpoints (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 Csubobject of the most derived object.
Otherwise, the run-time check fails.
9The 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 (15.1) of a type that would match a handler (15.3) of type
std::bad_cast (18.7.2).
[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 run-time 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 0
// fhas two Dsubobjects
E* ep = (E*)ap; // ill-formed: cast from virtual base
E* ep1 = dynamic_cast<E*>(ap); // succeeds
}
— end example ] [ Note: 12.7 describes the behavior of a dynamic_cast applied to an object under construc-
tion or destruction. — end note ]
§ 5.2.7 101
c
ISO/IEC N????
5.2.8 Type identification [expr.typeid]
1The result of a typeid expression is an lvalue of static type const std::type_info (18.7.1) 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 18.7.1.69 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.
2The typeid operator shall not be applied to an array of runtime bound.
3When typeid is applied to a glvalue expression whose type is a polymorphic class type (10.3), the result refers
to a std::type_info object representing the type of the most derived object (1.8) (that is, the dynamic
type) to which the glvalue refers. If the glvalue expression is obtained by applying the unary *operator to
a pointer70 and the pointer is a null pointer value (4.10), the typeid expression throws an exception (15.1)
of a type that would match a handler of type std::bad_typeid exception (18.7.3).
4When 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 (4.1), array-to-
pointer (4.2), and function-to-pointer (4.3) conversions are not applied to the expression. If the type of the
expression is a class type, the class shall be completely-defined. The expression is an unevaluated operand
(Clause 5).
5When 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.
6If 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 ]
7If the header <typeinfo> (18.7.1) is not included prior to a use of typeid, the program is ill-formed.
8[Note: 12.7 describes the behavior of typeid applied to an object under construction or destruction. — end
note ]
5.2.9 Static cast [expr.static.cast]
1The result of the expression static_cast<T>(v) is the result of converting the expression vto type T. If T
is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if Tis 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 (5.2.11).
2An lvalue of type “cv1 B,” where Bis a class type, can be cast to type “reference to cv2 D,” where Dis a class
derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10),
cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and Bis neither a virtual base class
of Dnor a base class of a virtual base class of D. The result has type “cv2 D.” An xvalue of type “cv1 B
may 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 subobject of an object of type D, the result refers to the enclosing
object of type D. Otherwise, the behavior is undefined. [ Example:
69) The recommended name for such a class is extended_type_info.
70) If pis an expression of pointer type, then *p,(*p),*(p),((*p)),*((p)), and so on all meet this requirement.
§ 5.2.9 102
c
ISO/IEC N????
struct B { };
struct D : public B { };
D d;
B &br = d;
static_cast<D&>(br); // produces lvalue to the original dobject
— end example ]
3A glvalue of type “cv1 T1” can be cast to type “rvalue reference to cv2 T2” if “cv2 T2” is reference-compatible
with “cv1 T1” (8.5.3). If the glvalue is not a bit-field, the result refers to the object or the specified base
class subobject thereof; otherwise, the lvalue-to-rvalue conversion (4.1) 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 11) or ambiguous (10.2) base class of T1, a program that necessitates such a cast is
ill-formed.
4An expression ecan be explicitly converted to a type Tusing a static_cast of the form static_cast<T>(e)
if the declaration T t(e); is well-formed, for some invented temporary variable t(8.5). The effect of such an
explicit conversion is the same as performing the declaration and initialization and then using the temporary
variable as the result of the conversion. The expression eis used as a glvalue if and only if the initialization
uses it as a glvalue.
5Otherwise, the static_cast shall perform one of the conversions listed below. No other conversion shall be
performed explicitly using a static_cast.
6Any expression can be explicitly converted to type cv void, in which case it becomes a discarded-value
expression (Clause 5). [ Note: however, if the value is in a temporary object (12.2), 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 ]
7The inverse of any standard conversion sequence (Clause 4) not containing an lvalue-to-rvalue (4.1), array-
to-pointer (4.2), function-to-pointer (4.3), null pointer (4.10), null member pointer (4.11), or boolean (4.12)
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 ]
8The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) conversions are applied to
the operand. Such a static_cast is subject to the restriction that the explicit conversion does not cast
away constness (5.2.11), and the following additional rules for specific cases:
9A value of a scoped enumeration type (7.2) 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.
10 A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is
unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resulting
value is unspecified (and might not be in that range). A value of floating-point type can also be converted
to an enumeration type. The resulting value is the same as converting the original value to the underlying
type of the enumeration (4.9), and subsequently to the enumeration type.
§ 5.2.9 103
c
ISO/IEC N????
11 A prvalue of type “pointer to cv1 B,” where Bis a class type, can be converted to a prvalue of type “pointer
to cv2 D,” where Dis a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D
to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and
Bis neither a virtual base class of Dnor a base class of a virtual base class of D. The null pointer value (4.10)
is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1 B” points
to a Bthat 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.
12 A prvalue of type “pointer to member of Dof type cv1 T” can be converted to a prvalue of type “pointer to
member of B” of type cv2 T, where Bis a base class (Clause 10) of D, if a valid standard conversion from
“pointer to member of Bof type T” to “pointer to member of Dof type T” exists (4.11), and cv2 is the same
cv-qualification as, or greater cv-qualification than, cv1.71 The null member pointer value (4.11) is converted
to the null member pointer value of the destination type. If class Bcontains 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 Bneed 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 5.5.— end note ]
13 A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T,” where Tis
an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. The null pointer
value is converted to the null pointer value of the destination type. If the original pointer value represents
the address Aof a byte in memory and Asatisfies the alignment requirement of T, then the resulting pointer
value represents the same address as the original pointer value, that is, A. The result of any other such
pointer conversion is unspecified. A value of type pointer to object converted to “pointer to cv void” and
back, possibly with different cv-qualification, shall have its original value. [ Example:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
bool b = p1 == p2; // bwill have the value true.
— end example ]
5.2.10 Reinterpret cast [expr.reinterpret.cast]
1The result of the expression reinterpret_cast<T>(v) is the result of converting the expression vto type
T. If Tis an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if Tis an
rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-
rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) 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.
2The reinterpret_cast operator shall not cast away constness (5.2.11). An expression of integral, enumer-
ation, pointer, or pointer-to-member type can be explicitly converted to its own type; such a cast yields the
value of its operand.
3[Note: The mapping performed by reinterpret_cast might, or might not, produce a representation dif-
ferent from the original value. — end note ]
4A 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: Areinterpret_cast cannot be used to convert a value of any type to the type std::nullptr_t.
— end note ]
5A 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.
71) Function types (including those used in pointer to member function types) are never cv-qualified; see 8.3.5.
§ 5.2.10 104
c
ISO/IEC N????
[Note: Except as described in 3.7.4.3, the result of such a conversion will not be a safely-derived pointer
value. — end note ]
6A function pointer can be explicitly converted to a function pointer of a different type. The effect of calling
a function through a pointer to a function type (8.3.5) that is not the same as the type used in the definition
of the function is undefined. 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 4.10 for more details of pointer conversions.
— end note ]
7An object pointer can be explicitly converted to an object pointer of a different type.72 When a prvalue vof
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)). 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.
8Converting 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.
9The null pointer value (4.10) 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 ]
10 A prvalue of type “pointer to member of Xof type T1” can be explicitly converted to a prvalue of a different
type “pointer to member of Yof type T2” if T1 and T2 are both function types or both object types.73 The
null member pointer value (4.11) 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 Xof type T1” to the type “pointer to data
member of Yof 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.
11 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 (12.1) or conversion functions (12.3) are not called.74
5.2.11 Const cast [expr.const.cast]
1The result of the expression const_cast<T>(v) is of type T. If Tis an lvalue reference to object type, the
result is an lvalue; if Tis an rvalue reference to object type, the result is an xvalue; otherwise, the result
is a prvalue and the lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) 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.
2[Note: Subject to the restrictions in this section, an expression may be cast to its own type using a const_-
cast operator. — end note ]
72) The types may have different cv-qualifiers, subject to the overall restriction that a reinterpret_cast cannot cast away
constness.
73) T1 and T2 may have different cv-qualifiers, subject to the overall restriction that a reinterpret_cast cannot cast away
constness.
74) This is sometimes referred to as a type pun.
§ 5.2.11 105
c
ISO/IEC N????
3For two pointer types T1 and T2 where
T1 is cv1,0pointer to cv1,1pointer to ···cv1,n1pointer to cv1,n T
and
T2 is cv2,0pointer to cv2,1pointer to ···cv2,n1pointer to cv2,n T
where Tis any object type or the void type and where cv1,k and cv2,k may be different cv-qualifications,
a prvalue of type T1 may be explicitly converted to the type T2 using a const_cast. The result of a pointer
const_cast refers to the original object.
4For 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.
5For a const_cast involving pointers to data members, multi-level pointers to data members and multi-level
mixed pointers and pointers to data members (4.4), the rules for const_cast are the same as those used for
pointers; the “member” aspect of a pointer to member is ignored when determining where the cv-qualifiers
are added or removed by the const_cast. The result of a pointer to data member const_cast refers to the
same member as the original (uncast) pointer to data member.
6A null pointer value (4.10) is converted to the null pointer value of the destination type. The null member
pointer value (4.11) is converted to the null member pointer value of the destination type.
7[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-qualifier75 may produce undefined
behavior (7.1.6.1). — end note ]
8The following rules define the process known as casting away constness. In these rules Tnand Xnrepresent
types. For two pointer types:
X1 is T1cv1,1*··· cv1,N *where T1 is not a pointer type
X2 is T2cv2,1*··· cv2,M *where T2 is not a pointer type
Kis min(N, M)
casting from X1 to X2 casts away constness if, for a non-pointer type Tthere does not exist an implicit
conversion (Clause 4) from:
Tcv1,(NK+1) *cv1,(NK+2) *··· cv1,N *
to
Tcv2,(MK+1) *cv2,(MK+2) *··· cv2,M *
75) const_cast is not limited to conversions that cast away a const-qualifier.
§ 5.2.11 106
c
ISO/IEC N????
9Casting 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.
10 Casting from a prvalue of type “pointer to data member of Xof type T1” to the type “pointer to data member
of Yof type T2” casts away constness if a cast from a prvalue of type “pointer to T1” to the type “pointer
to T2” casts away constness.
11 For multi-level pointer to members and multi-level mixed pointers and pointer to members (4.4), the “mem-
ber” aspect of a pointer to member level is ignored when determining if a const cv-qualifier has been cast
away.
12 [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 ]
5.3 Unary expressions [expr.unary]
1Expressions with unary operators group right-to-left.
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
*&+-! ~
5.3.1 Unary operators [expr.unary.op]
1The 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 4.1.— end note ]
2The result of each of the following unary operators is a prvalue.
3The result of the unary &operator is a pointer to its operand. The operand shall be either an lvalue of type
other than “array of runtime bound” or a qualified-id. If the operand is a qualified-id naming a non-static
member mof some class Cwith type T, the result has type “pointer to member of class Cof 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 (1.7) 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 ] [ Example:
struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*
§ 5.3.1 107
c
ISO/IEC N????
— end example ] [ Note: a pointer to member formed from a mutable non-static data member (7.1.1) does
not reflect the mutable specifier associated with the non-static data member. — end note ]
4A 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” (4.3). Nor is
&unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. — end note ]
5If &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.
6The address of an overloaded function (Clause 13) can be taken only in a context that uniquely determines
which version of the overloaded function is referred to (see 13.4). [ 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 ]
7The 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.
8The 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 2n, where nis the number of
bits in the promoted operand. The type of the result is the type of the promoted operand.
9The operand of the logical negation operator !is contextually converted to bool (Clause 4); its value is
true if the converted operand is false and false otherwise. The type of the result is bool.
10 The operand of ˜shall have integral or unscoped enumeration type; the result is the one’s 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 unary-expression ˜X(), where Xis a class-name or decltype-specifier. The
ambiguity is resolved in favor of treating ˜as a unary complement rather than treating ˜X as referring to a
destructor.
5.3.2 Increment and decrement [expr.pre.incr]
1The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The
operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type 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. If xis not of type bool, the expression ++x is equivalent to x+=1 [Note: See the
discussions of addition (5.7) and assignment operators (5.17) for information on conversions. — end note ]
2The operand of prefix -- is modified by subtracting 1. The operand shall not be of type bool. 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 5.2.6.— end note ]
5.3.3 Sizeof [expr.sizeof]
1The 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 5), or a parenthesized type-id. The sizeof
operator shall not be applied to an expression that has function or incomplete type, to an enumeration type
whose underlying type is not fixed before all its enumerators have been declared, to an array of runtime
bound, 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 (3.9.1) is implementation-defined. [ Note: in particular, sizeof(bool),sizeof(char16_-
t),sizeof(char32_t), and sizeof(wchar_t) are implementation-defined.76 — end note ] [ Note: See 1.7
for the definition of byte and 3.9 for the definition of object representation.— end note ]
76) sizeof(bool) is not required to be 1.
§ 5.3.3 108
c
ISO/IEC N????
2When 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 (1.8).
The result of applying sizeof to a base class subobject is the size of the base class type.77 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 ntimes the size of an element.
3The sizeof operator can be applied to a pointer to a function, but shall not be applied directly to a function.
4The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are not
applied to the operand of sizeof.
5The 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 (14.5.3). [ Example:
template<class... Types>
struct count {
static const std::size_t value = sizeof...(Types);
};
— end example ]
6The result of sizeof and sizeof... is a constant of type std::size_t. [ Note: std::size_t is defined in
the standard header <cstddef> (18.2). — end note ]
5.3.4 New [expr.new]
1The new-expression attempts to create an object of the type-id (8.1) 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 (1.8,3.9,10.4). It is implementation-defined whether over-aligned types
are supported (3.11). [ 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 ]
new-expression:
::opt new new-placementopt new-type-id new-initializeropt
::opt new new-placementopt (type-id )new-initializeropt
new-placement:
(expression-list )
new-type-id:
type-specifier-seq new-declaratoropt
new-declarator:
ptr-operator new-declaratoropt
noptr-new-declarator
noptr-new-declarator:
[expression ]attribute-specifier-seqopt
noptr-new-declarator [constant-expression ]attribute-specifier-seqopt
new-initializer:
(expression-listopt )
braced-init-list
Entities created by a new-expression have dynamic storage duration (3.7.4). [ 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.
2If the auto type-specifier appears in the type-specifier-seq of a new-type-id or type-id of a new-expression, the
new-expression shall contain a new-initializer of the form
77) 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.
§ 5.3.4 109
c
ISO/IEC N????
(assignment-expression )
The allocated type is deduced from the new-initializer as follows: Let ebe the assignment-expression in
the new-initializer and Tbe the new-type-id or type-id of the new-expression, then the allocated type is the type
deduced for the variable xin the invented declaration (7.1.6.4):
T x(e);
[Example:
new auto(1); // allocated type is int
auto x = new auto(’a’); // allocated type is char,xis of type char*
— end example ]
3The 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 ]
4[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 (3.9.2):
new (int (*[10])());
allocates an array of 10 pointers to functions (taking no argument and returning int.— end example ]
— end note ]
5When 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.
6Every constant-expression in a noptr-new-declarator shall be a converted constant expression (5.19) 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 nis the expression of a noptr-new-declarator), but new float[5][n] is ill-formed
(because nis not a constant expression). — end example ]
7The 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 (13.3.3.1.2)78
is less than zero;
its value is such that the size of the allocated object would exceed the implementation-defined limit
(annex B); 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 (2.14.5)) exceeds the number of elements
to initialize.
78) 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.
§ 5.3.4 110
c
ISO/IEC N????
If the expression, after converting to std::size_t, is a core constant expression and the expression is
erroneous, the program is ill-formed. Otherwise, a new-expression with an erroneous expression does not call
an allocation function and terminates by throwing an exception of a type that would match a handler (15.3)
of type std::bad_array_new_length (18.6.2.3). When the value of the expression is zero, the allocation
function is called to allocate an array with no elements.
8Anew-expression may obtain storage for the object by calling an allocation function (3.7.4.1). If the
new-expression terminates by throwing an exception, it may release storage by calling a deallocation func-
tion (3.7.4.2). 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 (3.7.4,18.6.1.1,18.6.1.2).
A C++ program can provide alternative definitions of these functions (17.6.4.6) and/or class-specific ver-
sions (12.5). — end note ]
9If 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 Tor 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.
10 An implementation is allowed to omit a call to a replaceable global allocation function (18.6.1.1,18.6.1.2).
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 lifetime of the object allocated by e1 strictly contains
the lifetime of the object allocated by e2,e1 and e2 would invoke the same replaceable global allocation
function, and, for a throwing allocation function, exceptions in e1 and e2 would be first caught in the same
handler.
11 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 and unsigned
char, 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 (3.11) 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 ]
12 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.
13 The new-placement syntax is used to supply additional arguments to an allocation function. If used, overload
resolution is performed on a function call created by assembling an argument list consisting of the amount of
space requested (the first argument) and the expressions in the new-placement part of the new-expression (the
second and succeeding arguments). The first of these arguments has type std::size_t and the remaining
arguments have the corresponding types of the expressions in the new-placement.
14 [Example:
new T results in a call of operator new(sizeof(T)),
new(2,f) T results in a call of operator new(sizeof(T),2,f),
new T[5] results in a call of operator new[](sizeof(T)*5+x), and
new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+y,2,f).
§ 5.3.4 111
c
ISO/IEC N????
Here, xand yare non-negative unspecified values 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 ]
15 [Note: unless an allocation function is declared with a non-throwing exception-specification (15.4), it indi-
cates failure to allocate storage by throwing a std::bad_alloc exception (Clause 15,18.6.2.1); it returns a
non-null pointer otherwise. If the allocation function is declared with 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 returns null, initialization shall not be done, the deallocation function shall not be called,
and the value of the new-expression shall be null.
16 [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 ]
17 Anew-expression that creates an object of type Tinitializes that object as follows:
If the new-initializer is omitted, the object is default-initialized (8.5); if no initialization is performed,
the object has indeterminate value.
— Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-
initialization.
18 The invocation of the allocation function is indeterminately sequenced with respect to the evaluations of
expressions in the new-initializer. Initialization of the allocated object is sequenced before the value com-
putation of the new-expression. It is unspecified whether expressions in the new-initializer are evaluated if
the allocation function returns the null pointer or exits using an exception.
19 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 (12.5), and the constructor (12.1). If the
new expression creates an array of objects of class type, access and ambiguity control are done for the
destructor (12.4).
20 If any part of the object initialization described above79 terminates by throwing an exception, storage has
been obtained for the object, 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 ]
21 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 Tor 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.
22 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 (8.3.5), all parameter types
except the first are identical. Any non-placement deallocation function matches a non-placement allocation
function. 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 the two-parameter form of a usual deallocation
function (3.7.4.2) 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. [ Example:
79) This may include evaluating a new-initializer and/or calling a constructor.
§ 5.3.4 112
c
ISO/IEC N????
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 ]
23 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.
5.3.5 Delete [expr.delete]
1The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.
delete-expression:
::opt delete cast-expression
::opt 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.80 The
operand shall be of pointer to object type or of class type. If of class type, the operand is contextually
implicitly converted (Clause 4) to a pointer to object type. The delete-expression’s result has type void.81
2If 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 (1.8)
representing a base class of such an object (Clause 10). 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.82 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 (5.2.11) of the pointer expression before it
is used as the operand of the delete-expression.— end note ]
3In 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.
4The cast-expression in a delete-expression shall be evaluated exactly once.
5If 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.
80) 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.
81) This implies that an object cannot be deleted using a pointer of type void* because void is not an object type.
82) For non-zero-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.
§ 5.3.5 113
c
ISO/IEC N????
6If 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 12.6.2).
7If the value of the operand of the delete-expression is not a null pointer value, then:
If the allocation call for the new-expression for the object to be deleted was not omitted (5.3.4), the
delete-expression shall call a deallocation function (3.7.4.2). The value returned from the allocation
call of the new-expression shall be passed as the first argument to the deallocation function.
Otherwise, the delete-expression will not call a deallocation function (3.7.4.2).
Otherwise, it is unspecified whether the deallocation function will be called. [ 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 ]
8[Note: An implementation provides default definitions of the global deallocation functions operator delete()
for non-arrays (18.6.1.1) and operator delete[]() for arrays (18.6.1.2). A C++ program can provide al-
ternative definitions of these functions (17.6.4.6), and/or class-specific versions (12.5). — end note ]
9When the keyword delete in a delete-expression is preceded by the unary :: operator, the global dealloca-
tion function is used to deallocate the storage.
10 Access and ambiguity control are done for both the deallocation function and the destructor (12.4,12.5).
5.3.6 Alignof [expr.alignof]
1An 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.
2The result is an integral constant of type std::size_t.
3When alignof is applied to a reference type, the result shall be the alignment of the referenced type. When
alignof is applied to an array type, the result shall be the alignment of the element type.
5.3.7 noexcept operator [expr.unary.noexcept]
1The noexcept operator determines whether the evaluation of its operand, which is an unevaluated operand
(Clause 5), can throw an exception (15.1).
noexcept-expression:
noexcept ( expression )
2The result of the noexcept operator is a constant of type bool and is an rvalue.
3The result of the noexcept operator is false if in a potentially-evaluated context the expression would
contain
a potentially-evaluated call83 to a function, member function, function pointer, or member function
pointer that does not have a non-throwing exception-specification (15.4), unless the call is a constant
expression (5.19),
a potentially-evaluated throw-expression (15.1),
a potentially-evaluated dynamic_cast expression dynamic_cast<T>(v), where Tis a reference type,
that requires a run-time check (5.2.7), or
— a potentially-evaluated typeid expression (5.2.8) applied to a glvalue expression whose type is a
polymorphic class type (10.3).
Otherwise, the result is true.
83) This includes implicit calls such as the call to an allocation function in a new-expression.
§ 5.3.7 114
c
ISO/IEC N????
5.4 Explicit type conversion (cast notation) [expr.cast]
1The result of the expression (T) cast-expression is of type T. The result is an lvalue if Tis an lvalue reference
type or an rvalue reference to function type and an xvalue if Tis an rvalue reference to object type; otherwise
the result is a prvalue. [ Note: if Tis a non-class type that is cv-qualified, the cv-qualifiers are discarded
when determining the type of the resulting prvalue; see Clause 5.— end note ]
2An explicit type conversion can be expressed using functional notation (5.2.3), a type conversion operator
(dynamic_cast,static_cast,reinterpret_cast,const_cast), or the cast notation.
cast-expression:
unary-expression
(type-id )cast-expression
3Any type conversion not mentioned below and not explicitly defined by the user (12.3) is ill-formed.
4The conversions performed by
a const_cast (5.2.11),
a static_cast (5.2.9),
a static_cast followed by a const_cast,
a reinterpret_cast (5.2.10), or
a reinterpret_cast followed by a const_cast,
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 ]
5The 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
§ 5.4 115
c
ISO/IEC N????
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 ]
5.5 Pointer-to-member operators [expr.mptr.oper]
1The pointer-to-member operators ->* and .* group left-to-right.
pm-expression:
cast-expression
pm-expression .* cast-expression
pm-expression ->* cast-expression
2The binary operator .* binds its second operand, which shall be of type “pointer to member of T” to its
first operand, which shall be of class Tor of a class of which Tis an unambiguous and accessible base class.
The result is an object or a function of the type specified by the second operand.
3The 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 T” or “pointer to a class of which Tis an unambiguous and
accessible base class. The expression E1->*E2 is converted into the equivalent form (*(E1)).*E2.
4Abbreviating 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.
5The 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 5.2.5. [ 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 ]
6If 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 pointer to member value (4.11),
the behavior is undefined.
5.6 Multiplicative operators [expr.mul]
1The multiplicative operators *,/, and %group left-to-right.
multiplicative-expression:
pm-expression
multiplicative-expression *pm-expression
multiplicative-expression /pm-expression
multiplicative-expression %pm-expression
§ 5.6 116
c
ISO/IEC N????
2The 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.
3The binary *operator indicates multiplication.
4The 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;84 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.
5.7 Additive operators [expr.add]
1The 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 enumer-
ation type.
2For 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.
3The 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.
4For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the
first element of an array of length one with the type of the object as its element type.
5When 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 pointer operand points to an element of an array object, and the array is
large enough, the result points to an element offset from the original element such that the difference of
the subscripts of the resulting and original array elements equals the integral expression. In other words, if
the expression Ppoints to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P))
and (P)-N (where Nhas the value n) point to, respectively, the i+n-th and in-th elements of the array
object, provided they exist. Moreover, if the expression Ppoints to the last element of an array object,
the expression (P)+1 points one past the last element of the array object, and if the expression Qpoints
one past the last element of an array object, the expression (Q)-1 points to the last element of the array
object. If both the pointer operand and the result point to elements of the same array object, or one past
the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is
undefined.
6When two pointers to elements of the same array object are subtracted, the result is the difference of the
subscripts of the two array elements. 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 (18.2). As
with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined.
In other words, if the expressions Pand Qpoint to, respectively, the i-th and j-th elements of an array object,
the expression (P)-(Q) has the value ijprovided the value fits in an object of type std::ptrdiff_t.
84) This is often called truncation towards zero.
§ 5.7 117
c
ISO/IEC N????
Moreover, if the expression Ppoints either to an element of an array object or one past the last element of
an array object, and the expression Qpoints to the last element of the same array object, the expression
((Q)+1)-(P) has the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)), and has the value zero if the
expression Ppoints one past the last element of the array object, even though the expression (Q)+1 does not
point to an element of the array object. Unless both pointers point to elements of the same array object, or
one past the last element of the array object, the behavior is undefined.85
7For addition or subtraction, if the expressions Por Qhave type “pointer to cv T”, where Tis different from
the cv-unqualified array element type, 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 ]
8If the value 0 is added to or subtracted from a pointer value, the result compares equal to the original pointer
value. If two pointers point to the same object or both point one past the end of the same array or both
are null, and the two pointers are subtracted, the result compares equal to the value 0 converted to the type
std::ptrdiff_t.
5.8 Shift operators [expr.shift]
1The 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.
2The 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 E1 ×2E2, 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 E1 ×2E2 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.
3The 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 E1/2E2. If E1
has a signed type and a negative value, the resulting value is implementation-defined.
5.9 Relational operators [expr.rel]
1The relational operators group left-to-right. [ Example: a<b<c means (a<b)<c and not (a<b)&&(b<c).
— end example ]
relational-expression:
shift-expression
relational-expression <shift-expression
relational-expression >shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
The operands shall have arithmetic, enumeration, or pointer type. 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.
85) Another way to approach pointer arithmetic is first to convert the pointer(s) to character pointer(s): In this scheme the
integral value of the expression added to or subtracted from the converted pointer is first multiplied by the size of the object
originally pointed to, and the resulting pointer is converted back to the original type. For pointer subtraction, the result of the
difference between the character pointers is similarly divided by the size of the object originally pointed to.
When viewed in this way, an implementation need only provide one extra byte (which might overlap another object in the
program) just after the end of the object in order to satisfy the “one past the last element” requirements.
§ 5.9 118
c
ISO/IEC N????
2The usual arithmetic conversions are performed on operands of arithmetic or enumeration type. If both
operands are pointers, pointer conversions (4.10) and qualification conversions (4.4) are performed to bring
them to their composite pointer type (Clause 5). After conversions, the operands shall have the same type.
3Comparing pointers to objects 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 one pointer points to an element of an array, or to a subobject thereof, and another pointer points
one past the last element of the array, the latter pointer 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 11) and provided their class is not a union.
4If two operands pand qcompare equal (5.10), p<=q and p>=q both yield true and p<q and p>q both yield
false. Otherwise, if a pointer pcompares 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.
5If 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.
5.10 Equality operators [expr.eq]
equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
1The == (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.
2If at least one of the operands is a pointer, pointer conversions (4.10) and qualification conversions (4.4) are
performed on both operands to bring them to their composite pointer type (Clause 5). Comparing pointers
is defined as follows: Two pointers compare equal if they are both null, both point to the same function, or
both represent the same address (3.9.2), otherwise they compare unequal.
3If at least one of the operands is a pointer to member, pointer to member conversions (4.11) and qualification
conversions (4.4) are performed on both operands to bring them to their composite pointer type (Clause 5).
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.
Two pointers to members compare equal if they would refer to the same member of the same most
derived object (1.8) 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;
§ 5.10 119
c
ISO/IEC N????
int (L::*pl)() = pb;
int (R::*pr)() = pb;
int (D::*pdl)() = pl;
int (D::*pdr)() = pr;
bool x = (pdl == pdr); // false
— end example ]
4Two operands of type std::nullptr_t or one operand of type std::nullptr_t and the other a null pointer
constant compare equal.
5If 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.
6If 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.
5.11 Bitwise AND operator [expr.bit.and]
and-expression:
equality-expression
and-expression &equality-expression
1The 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.
5.12 Bitwise exclusive OR operator [expr.xor]
exclusive-or-expression:
and-expression
exclusive-or-expression ˆand-expression
1The 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.
5.13 Bitwise inclusive OR operator [expr.or]
inclusive-or-expression:
exclusive-or-expression
inclusive-or-expression |exclusive-or-expression
1The 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.
5.14 Logical AND operator [expr.log.and]
logical-and-expression:
inclusive-or-expression
logical-and-expression && inclusive-or-expression
1The && operator groups left-to-right. The operands are both contextually converted to bool (Clause 4).
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.
2The 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.
5.15 Logical OR operator [expr.log.or]
logical-or-expression:
logical-and-expression
logical-or-expression || logical-and-expression
§ 5.15 120
c
ISO/IEC N????
1The || operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). 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.
2The 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.
5.16 Conditional operator [expr.cond]
conditional-expression:
logical-or-expression
logical-or-expression ?expression :assignment-expression
1Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4).
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.
2If 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 (15.1);
the result is of the type and value category of the other.
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 ]
3Otherwise, 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 convert each of those operands to the type of the other. The process for determining
whether an operand expression E1 of type T1 can be converted to match an operand expression E2 of type
T2 is defined as follows:
If E2 is an lvalue: E1 can be converted to match E2 if E1 can be implicitly converted (Clause 4) to the
type “lvalue reference to T2”, subject to the constraint that in the conversion the reference must bind
directly (8.5.3) to an lvalue.
— If E2 is an xvalue: E1 can be converted to match E2 if E1 can be implicitly converted to the type
“rvalue reference to T2”, subject to the constraint that the reference must bind directly.
If E2 is a prvalue or if neither of the conversions above can be done and at least one of the operands
has (possibly cv-qualified) class type:
if E1 and E2 have class type, and the underlying class types are the same or one is a base class
of the other: E1 can be converted to match E2 if the class of T2 is the same type as, or a base
class of, the class of T1, and the cv-qualification of T2 is the same cv-qualification as, or a greater
cv-qualification than, the cv-qualification of T1. If the conversion is applied, E1 is changed to a
prvalue of type T2 by copy-initializing a temporary of type T2 from E1 and using that temporary
as the converted operand.
Otherwise (i.e., if E1 or E2 has a nonclass type, or if they both have class types but the underlying
classes are not either the same or one a base class of the other): E1 can be converted to match E2
if E1 can be implicitly converted to the type that expression E2 would have if E2 were converted
to a prvalue (or the type it has, if E2 is a prvalue).
Using this process, it is determined whether the second operand can be converted to match the third
operand, and whether the third operand can be converted to match the second operand. If both can be
converted, or one can be converted but the conversion is ambiguous, the program is ill-formed. If neither
§ 5.16 121
c
ISO/IEC N????
can be converted, the operands are left unchanged and further checking is performed as described below.
If exactly one conversion is possible, 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.
4If 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.
5Otherwise, 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 (13.3.1.2,13.6). 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.
6Lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are per-
formed 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. If the operands have
class type, the result is a prvalue temporary of the result type, which is copy-initialized from either
the second operand or the third operand depending on the value of the first 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 (4.10) and
qualification conversions (4.4) are performed to bring them to their composite pointer type (Clause 5).
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 (4.11) and qualification conversions (4.4) are performed to bring them to their composite
pointer type (Clause 5). 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.
5.17 Assignment and compound assignment operators [expr.ass]
1The 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.
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 ]
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
assignment-operator: one of
= *= /= %= += -= >>= <<= &= ˆ= |=
2In simple assignment (=), the value of the expression replaces that of the object referred to by the left
operand.
3If the left operand is not of class type, the expression is implicitly converted (Clause 4) to the cv-unqualified
type of the left operand.
4If 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 (12.8,13.5.3).
§ 5.17 122
c
ISO/IEC N????
5[Note: For class objects, assignment is not in general the same as initialization (8.5,12.1,12.6,12.8). — end
note ]
6When the left operand of an assignment operator denotes a reference to T, the operation assigns to the object
of type Tdenoted by the reference.
7The 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.
8If the value being stored in an object is accessed from 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. See 3.10.— end note ]
9Abraced-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 Tis 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 (13.5.3,13.3).
[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 ]
5.18 Comma operator [expr.comma]
1The 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 5).86 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 glvalue and a bit-field. If the value of the right
operand is a temporary (12.2), the result is that temporary.
2In contexts where comma is given a special meaning, [ Example: in lists of arguments to functions (5.2.2)
and lists of initializers (8.5)— end example ] the comma operator as described in Clause 5can 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 ]
5.19 Constant expressions [expr.const]
1Certain contexts require expressions that satisfy additional requirements as detailed in this sub-clause; other
contexts have different semantics depending on whether or not an expression satisfies these requirements.
86) However, an invocation of an overloaded comma operator is an ordinary function call; hence, the evaluations of its argument
expressions are unsequenced relative to one another (see 1.9).
§ 5.19 123
c
ISO/IEC N????
Expressions that satisfy these requirements are called constant expressions. [ Note: Constant expressions
can be evaluated during translation. — end note ]
constant-expression:
conditional-expression
2Aconditional-expression eis a core constant expression unless the evaluation of e, following the rules of the
abstract machine (1.9), would evaluate one of the following expressions:
this (5.1.1), 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 (12.4) [ Note: Overload resolution (13.3) is applied as
usual — end note ];
an invocation of an undefined constexpr function or an undefined constexpr constructor;
an expression that would exceed the implementation-defined limits (see Annex B);
an operation that would have undefined behavior [ Note: including, for example, signed integer over-
flow (Clause 5), certain pointer arithmetic (5.7), division by zero (5.6), or certain shift operations (5.8)
— end note ];
a lambda-expression (5.1.2);
an lvalue-to-rvalue conversion (4.1) unless it is applied to
a non-volatile glvalue of integral or enumeration type that refers to a non-volatile const object with
a preceding initialization, initialized with a constant expression [ Note: a string literal (2.14.5)
corresponds to an array of such objects. — end note ], or
a non-volatile glvalue that refers to a non-volatile object defined with constexpr, or that refers
to a non-mutable sub-object of such an object, or
a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began
within the evalution of e;
an lvalue-to-rvalue conversion (4.1) or modification (5.17,5.2.6,5.3.2) that is applied to a glvalue that
refers to a non-active member of a union or a subobject thereof;
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
it is a non-static data member of an object whose lifetime began within the evaluation of e;
a conversion from type cv void * to a pointer-to-object type;
a dynamic cast (5.2.7);
a reinterpret_cast (5.2.10);
a pseudo-destructor call (5.2.4);
modification of an object (5.17,5.2.6,5.3.2) 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 (5.2.8) whose operand is a glvalue of a polymorphic class type;
§ 5.19 124
c
ISO/IEC N????
a new-expression (5.3.4);
a delete-expression (5.3.5);
a relational (5.9) or equality (5.10) operator where the result is unspecified; or
a throw-expression (15.1).
[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
// mwith the value 42
constexpr int w = A(false).m; // error: initializer for mis
// x, which is non-constant
constexpr int f1(int k) {
constexpr int x = k; // error: xis 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 xis 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 ywith the value 2
// h(1) is a core constant expression because
// the lifetime of kbegins inside h(1)
— end example ]
3An integral constant expression is an expression of integral or unscoped enumeration type, implicitly con-
verted to a prvalue, where the converted expression is a core constant expression. [ Note: Such expressions
may be used as array bounds (8.3.4,5.3.4), as bit-field lengths (9.6), as enumerator initializers if the un-
derlying type is not fixed (7.2), and as alignments (7.6.2). — end note ] A converted constant expression of
type Tis an expression, implicitly converted to a prvalue of type T, where the converted expression is a core
§ 5.19 125
c
ISO/IEC N????
constant expression and the implicit conversion sequence contains only user-defined conversions, lvalue-to-
rvalue conversions (4.1), integral promotions (4.5), and integral conversions (4.7) other than narrowing con-
versions (8.5.4). [ Note: such expressions may be used in new expressions (5.3.4), as case expressions (6.4.2),
as enumerator initializers if the underlying type is fixed (7.2), as array bounds (8.3.4), and as integral or
enumeration non-type template arguments (14.3). — end note ]
4Aconstant expression is either a glvalue core constant expression whose value refers to an object with static
storage duration or to a function, or a prvalue core constant expression whose value is an object where, for
that object and its subobjects:
each non-static data member of reference type refers to an object with static storage duration or to a
function, and
if the object or subobject is of pointer type, it contains the address of an object with static storage
duration, the address past the end of such an object (5.7), the address of a function, or a null pointer
value.
5[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.87 [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 ]
6If 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 4) 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() { return val; }
constexpr operator long() { 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 ]
87) Nonetheless, implementations are encouraged to provide consistent results, irrespective of whether the evaluation was
performed during translation and/or during program execution.
§ 5.19 126
c
ISO/IEC N????
6 Statements [stmt.stmt]
1Except as indicated, statements are executed in sequence.
statement:
labeled-statement
attribute-specifier-seqopt expression-statement
attribute-specifier-seqopt compound-statement
attribute-specifier-seqopt selection-statement
attribute-specifier-seqopt iteration-statement
attribute-specifier-seqopt jump-statement
declaration-statement
attribute-specifier-seqopt try-block
The optional attribute-specifier-seq appertains to the respective statement.
6.1 Labeled statement [stmt.label]
1A statement can be labeled.
labeled-statement:
attribute-specifier-seqopt identifier :statement
attribute-specifier-seqopt case constant-expression :statement
attribute-specifier-seqopt default : statement
The optional attribute-specifier-seq appertains to the label. 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 definition. Labels have their own name space and do not interfere with other identifiers.
2Case labels and default labels shall occur only in switch statements.
6.2 Expression statement [stmt.expr]
1Expression statements have the form
expression-statement:
expressionopt ;
The expression is a discarded-value expression (Clause 5). 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 (6.5.1). — end note ]
6.3 Compound statement or block [stmt.block]
1So that several statements can be used where one is expected, the compound statement (also, and equiva-
lently, called “block”) is provided.
compound-statement:
{statement-seqopt }
statement-seq:
statement
statement-seq statement
A compound statement defines a block scope (3.3). [ Note: A declaration is a statement (6.7). — end
§ 6.3 127
c
ISO/IEC N????
note ]
6.4 Selection statements [stmt.select]
1Selection statements choose one of several flows of control.
selection-statement:
if ( condition )statement
if ( condition )statement else statement
switch ( condition )statement
condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator =initializer-clause
attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list
See 8.3 for the optional attribute-specifier-seq in a condition. In Clause 6, 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 (3.3).
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, iis no longer in scope. — end example ]
2The rules for conditions apply both to selection-statements and to the for and while statements (6.5). The
declarator shall not specify a function or an array. 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 7.1.6.4.
3A name introduced by a declaration in a condition (either introduced by the decl-specifier-seq or the declara-
tor 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 re-declared in the outermost block of a substatement controlled by the
condition, the declaration that re-declares 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 ]
4The 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 4). 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.
5If a condition can be syntactically resolved as either an expression or the declaration of a block-scope name,
it is interpreted as a declaration.
§ 6.4 128
c
ISO/IEC N????
6In the decl-specifier-seq of a condition, each decl-specifier shall be either a type-specifier or constexpr.
6.4.1 The if statement [stmt.if]
1If the condition (6.4) 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.88
6.4.2 The switch statement [stmt.switch]
1The switch statement causes control to be transferred to one of several statements depending on the value
of a condition.
2The condition shall be of integral type, enumeration type, or class type. If of class type, the condition is
contextually implicitly converted (Clause 4) to an integral or enumeration type. Integral promotions are
performed. 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 (5.19) of the promoted type of the
switch condition. No two of the case constants in the same switch shall have the same value after conversion
to the promoted type of the switch condition.
3There shall be at most one label of the form
default :
within a switch statement.
4Switch statements can be nested; a case or default label is associated with the smallest switch enclosing
it.
5When 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.
6case 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,6.6.1. [ 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 ]
6.5 Iteration statements [stmt.iter]
1Iteration statements specify looping.
iteration-statement:
while ( condition )statement
do statement while ( expression ) ;
for ( for-init-statement conditionopt ;expressionopt )statement
for ( for-range-declaration :for-range-initializer )statement
for-init-statement:
expression-statement
simple-declaration
for-range-declaration:
attribute-specifier-seqopt decl-specifier-seq declarator
for-range-initializer:
expression
braced-init-list
88) In other words, the else is associated with the nearest un-elsed if.
§ 6.5 129
c
ISO/IEC N????
See 8.3 for the optional attribute-specifier-seq in a for-range-declaration. [ Note: Afor-init-statement
ends with a semicolon. — end note ]
2The substatement in an iteration-statement implicitly defines a block scope (3.3) 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;
}
3Thus after the while statement, iis no longer in scope. — end example ]
4[Note: The requirements on conditions in iteration statements are described in 6.4.— end note ]
6.5.1 The while statement [stmt.while]
1In the while statement the substatement is executed repeatedly until the value of the condition (6.4) becomes
false. The test takes place before each execution of the substatement.
2When the condition of a while statement is a declaration, the scope of the variable that is declared extends
from its point of declaration (3.3.2) 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
Tt=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 ]
6.5.2 The do statement [stmt.do]
1The expression is contextually converted to bool (Clause 4); if that conversion is ill-formed, the program is
ill-formed.
§ 6.5.2 130
c
ISO/IEC N????
2In 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.
6.5.3 The for statement [stmt.for]
1The for statement
for ( for-init-statement conditionopt ;expressionopt )statement
is equivalent to
{
for-init-statement
while ( condition ) {
statement
expression ;
}
}
except that names declared in the for-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 (6.4) specifies a test, made before each iteration, such that the loop is exited when
the condition becomes false; the expression often specifies incrementing that is done after each iteration.
— end note ]
2Either or both of the condition and the expression can be omitted. A missing condition makes the implied
while clause equivalent to while(true).
3If the for-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 ]
6.5.4 The range-based for statement [stmt.ranged]
1For a range-based for statement of the form
for ( for-range-declaration : expression )statement
let range-init be equivalent to the expression surrounded by parentheses89
(expression )
and for a range-based for statement of the form
for ( for-range-declaration :braced-init-list )statement
let range-init be equivalent to the braced-init-list. In each case, a range-based for statement is equivalent
to
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
89) this ensures that a top-level comma operator cannot be reinterpreted as a delimiter between init-declarators in the decla-
ration of __range.
§ 6.5.4 131
c
ISO/IEC N????
}
}
where __range,__begin, and __end are variables defined for exposition only, and _RangeT is the type
of the expression, and begin-expr and end-expr are determined as follows:
if _RangeT is an array type, begin-expr and end-expr are __range and __range + __bound, respec-
tively, where __bound is the array bound. If _RangeT is an array of unknown size or an array of
incomplete type, the program is ill-formed;
if _RangeT is a class type, the unqualified-idsbegin and end are looked up in the scope of class _RangeT
as if by class member access lookup (3.4.5), 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 (3.4.2). [ Note: Ordinary unqualified lookup (3.4.1)
is not performed. — end note ]
[Example:
int array[5] = { 1, 2, 3, 4, 5 };
for (int& x : array)
x *= 2;
— end example ]
2In the decl-specifier-seq of a for-range-declaration, each decl-specifier shall be either a type-specifier or
constexpr.
6.6 Jump statements [stmt.jump]
1Jump statements unconditionally transfer control.
jump-statement:
break ;
continue ;
return expressionopt ;
return braced-init-list ;
goto identifier ;
2On exit from a scope (however accomplished), objects with automatic storage duration (3.7.3) that have been
constructed in that scope are destroyed in the reverse order of their construction. [ Note: For temporaries,
see 12.2.— 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 6.7 for transfers into blocks).
[Note: However, the program can be terminated (by calling std::exit() or std::abort() (18.5), for
example) without destroying class objects with automatic storage duration. — end note ]
6.6.1 The break statement [stmt.break]
1The 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.
6.6.2 The continue statement [stmt.cont]
1The 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
§ 6.6.2 132
c
ISO/IEC N????
while (foo) {
{
// ...
}
contin: ;
}
do {
{
// ...
}
contin: ;
} while (foo);
for (;;) {
{
// ...
}
contin: ;
}
acontinue not contained in an enclosed iteration statement is equivalent to goto contin.
6.6.3 The return statement [stmt.return]
1A function returns to its caller by the return statement.
2A return statement with neither an expression nor a braced-init-list can be used only in functions that do not
return a value, that is, a function with the return type cv void, a constructor (12.1), or a destructor (12.4).
A return statement with an expression of non-void type can be used only in functions returning a value; the
value of the expression is returned to the caller of the function. The value of the expression is implicitly
converted to the return type of the function in which it appears. A return statement can involve the
construction and copy or move of a temporary object (12.2). [ Note: A copy or move operation associated
with a return statement may be elided or considered as an rvalue for the purpose of overload resolution in
selecting a constructor (12.8). — end note ] A return statement with a braced-init-list initializes the object
or reference to be returned from the function by copy-list-initialization (8.5.4) from the specified initializer
list. [ Example:
std::pair<std::string,int> f(const char* p, int x) {
return {p,x};
}
— end example ]
Flowing off the end of a function is equivalent to a return with no value; this results in undefined
behavior in a value-returning function.
3A return statement with an expression of type void can be used only in functions with a return type of cv
void; the expression is evaluated just before the function returns to its caller.
6.6.4 The goto statement [stmt.goto]
1The goto statement unconditionally transfers control to the statement labeled by the identifier. The identifier
shall be a label (6.1) located in the current function.
6.7 Declaration statement [stmt.dcl]
1A 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.
2Variables with automatic storage duration (3.7.3) 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 (6.6).
3It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A
program that jumps90 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 (8.5). [ Example:
void f() {
// ...
goto lx; // ill-formed: jump into scope of a
90) The transfer from the condition of a switch statement to a case label is considered a jump in this respect.
§ 6.7 133
c
ISO/IEC N????
// ...
ly:
Xa=1;
// ...
lx:
goto ly; // OK, jump implies destructor
// call for afollowed by construction
// again immediately following label ly
}
— end example ]
4The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage
duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of a
block-scope entity with static storage duration, if applicable, is performed before its block is first entered.
An implementation is permitted to perform early initialization of other block-scope variables with static or
thread storage duration under the same conditions that an implementation is permitted to statically initialize
a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is
initialized 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.91 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 ]
5The destructor for a block-scope object with static or thread storage duration will be executed if and only
if it was constructed. [ Note: 3.6.3 describes the order in which block-scope objects with static and thread
storage duration are destroyed. — end note ]
6.8 Ambiguity resolution [stmt.ambig]
1There is an ambiguity in the grammar involving expression-statements and declarations: An expression-
statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indis-
tinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a
declaration. [ Note: To disambiguate, the whole statement might have to be examined to determine if it is
an expression-statement or a declaration. This disambiguates many examples. [ Example: assuming Tis a
simple-type-specifier (7.1.6),
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 ]
2The remaining cases are declarations. [ Example:
91) The implementation must not introduce any deadlock around execution of the initializer.
§ 6.8 134
c
ISO/IEC N????
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 ]
3The 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
(*(*b)(T2(c)))(int(d)); // a variable of type T1
// but this will not allow
// the last part of the
// declaration to parse
// properly since it depends
// on T2 being a type-name
}
— end example ]
§ 6.8 135
c
ISO/IEC N????
7 Declarations [dcl.dcl]
1Declarations generally specify how names are to be interpreted. Declarations have the form
declaration-seq:
declaration
declaration-seq declaration
declaration:
block-declaration
function-definition
template-declaration
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
alias-declaration:
using identifier attribute-specifier-seqopt = type-id ;
simple-declaration:
decl-specifier-seqopt init-declarator-listopt ;
attribute-specifier-seq decl-specifier-seqopt init-declarator-list ;
static_assert-declaration:
static_assert ( constant-expression ,string-literal ) ;
empty-declaration:
;
attribute-declaration:
attribute-specifier-seq ;
[Note: asm-definitions are described in 7.4, and linkage-specifications are described in 7.5.Function-
definitions are described in 8.4 and template-declarations are described in Clause 14.Namespace-definitions
are described in 7.3.1,using-declarations are described in 7.3.3 and using-directives are described in 7.3.4.
— end note ]
The simple-declaration
attribute-specifier-seqopt decl-specifier-seqopt init-declarator-listopt ;
is divided into three parts. Attributes are described in 7.6.decl-specifiers, the principal components of a
decl-specifier-seq, are described in 7.1.declarators, the components of an init-declarator-list, are described
in Clause 8. The attribute-specifier-seq in a simple-declaration 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
Declarations 136
c
ISO/IEC N????
— end example ]
Except where otherwise specified, the meaning of an attribute-declaration is implementation-defined.
2A declaration occurs in a scope (3.3); the scope rules are summarized in 3.4. 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 7about 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.
3In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause 9)
or enumeration (7.2), that is, when the decl-specifier-seq contains either a class-specifier, an elaborated-
type-specifier with a class-key (9.1), 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, and except for the declaration of an unnamed bit-field (9.6), 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 ]
4In a static_assert-declaration the constant-expression shall be a constant expression (5.19) that can be
contextually converted to bool (Clause 4). 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 (1.4)
shall include the text of the string-literal, except that characters not in the basic source character set (2.3)
are not required to appear in the diagnostic message. [ Example:
static_assert(sizeof(long) >= 8, "64-bit code generation required for this library.");
— end example ]
5An empty-declaration has no effect.
6Each 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 type-specifiers (7.1.6)
in the decl-specifier-seq and the recursive declarator structure of the init-declarator describe a type (8.3),
which is then associated with the name being declared by the init-declarator.
7If 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 (7.1.3).
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 (8.3.5) and an object declaration otherwise.
8Syntactic components beyond those found in the general form of declaration are added to a function decla-
ration to make a function-definition. An object declaration, however, is also a definition unless it contains
the extern specifier and has no initializer (3.1). A definition causes the appropriate amount of storage to
be reserved and any appropriate initialization (8.5) to be done.
9Only in function declarations for constructors, destructors, and type conversions can the decl-specifier-seq
be omitted.92
7.1 Specifiers [dcl.spec]
1The specifiers that can be used in a declaration are
decl-specifier:
storage-class-specifier
type-specifier
function-specifier
friend
typedef
constexpr
92) The “implicit int” rule of C is no longer supported.
§ 7.1 137
c
ISO/IEC N????
decl-specifier-seq:
decl-specifier attribute-specifier-seqopt
decl-specifier decl-specifier-seq
The optional attribute-specifier-seq in a decl-specifier-seq appertains to the type determined by the pre-
ceding decl-specifiers (8.3). The attribute-specifier-seq affects the type only for the declaration it appears in,
not other declarations involving the same type.
2If 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 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 ]
3[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 ]
7.1.1 Storage class specifiers [dcl.stc]
1The storage class specifiers are
storage-class-specifier:
register
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 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 (9.5)). 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 shall
not be specified in an explicit specialization (14.7.3) or an explicit instantiation (14.7.2) directive.
2The register specifier shall be applied only to names of variables declared in a block (6.3) or to function
parameters (8.4). It specifies that the named variable has automatic storage duration (3.7.3). A variable
declared without a storage-class-specifier at block scope or declared as a function parameter has automatic
storage duration by default.
3Aregister specifier is a hint to the implementation that the variable so declared will be heavily used.
[Note: The hint can be ignored and in most implementations it will be ignored if the address of the variable
is taken. This use is deprecated (see D.2). — end note ]
4The thread_local specifier indicates that the named entity has thread storage duration (3.7.2). It shall be
applied only to the names of variables of namespace or block scope and to the names of static data members.
§ 7.1.1 138
c
ISO/IEC N????
When thread_local is applied to a variable of block scope the storage-class-specifier static is implied if
it does not appear explicitly.
5The static specifier can be applied only to names of variables and functions and to anonymous unions (9.5).
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 (3.7.1),
unless accompanied by the thread_local specifier, which declares the variable to have thread storage
duration (3.7.2). A static specifier can be used in declarations of class members; 9.4 describes its effect.
For the linkage of a name declared with a static specifier, see 3.5.
6The 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 3.5. [ 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 ]
7The 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; // ahas internal linkage
int a; // error: two definitions
static int b; // bhas internal linkage
extern int b; // bstill has internal linkage
int c; // chas external linkage
static int c; // error: inconsistent linkage
extern int d; // dhas external linkage
static int d; // error: inconsistent linkage
— end example ]
8The 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;
§ 7.1.1 139
c
ISO/IEC N????
extern S f();
extern void g(S);
void h() {
g(a); // error: Sis incomplete
f(); // error: Sis incomplete
}
— end example ]
9The mutable specifier can be applied only to names of class data members (9.2) and cannot be applied to
names declared const or static, and cannot be applied to reference members. [ Example:
class X {
mutable const int* p; // OK
mutable int* const q; // ill-formed
};
— end example ]
10 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 (7.1.6.1).
7.1.2 Function specifiers [dcl.fct.spec]
1Function-specifiers can be used only in function declarations.
function-specifier:
inline
virtual
explicit
2A function declaration (8.3.5,9.3,11.3) 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 defined by 7.1.2 shall still be respected.
3A function defined within a class definition is an inline function. The inline specifier shall not appear on
a block scope function declaration.93 If the inline specifier is used in a friend declaration, that declaration
shall be a definition or the function shall have previously been declared inline.
4An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly
the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its
definition appears in the translation unit. — end note ] If the definition of a function appears in a translation
unit before its first declaration as inline, the program is ill-formed. If a function 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 with external linkage shall have the same address in all
translation units. A static local variable in an extern inline function always refers to the same object.
A string literal in the body of an extern inline function is the same object in different translation units.
[Note: A string literal appearing in a default argument is not in the body of an inline function merely
because the expression is used in a function call from that inline function. — end note ] A type defined
within the body of an extern inline function is the same type in every translation unit.
5The virtual specifier shall be used only in the initial declaration of a non-static class member function;
see 10.3.
6The explicit specifier shall be used only in the declaration of a constructor or conversion function within
its class definition; see 12.3.1 and 12.3.2.
7.1.3 The typedef specifier [dcl.typedef]
1Declarations containing the decl-specifier typedef declare identifiers that can be used later for naming
93) The inline keyword has no effect on the linkage of a function.
§ 7.1.3 140
c
ISO/IEC N????
fundamental (3.9.1) or compound (3.9.2) types. The typedef specifier shall not be combined in a decl-
specifier-seq with any other kind of specifier except a type-specifier, and it shall not be used in the decl-
specifier-seq of a parameter-declaration (8.3.5) nor in the decl-specifier-seq of a function-definition (8.4).
typedef-name:
identifier
A name declared with the typedef specifier becomes a typedef-name. Within the scope of its declaration,
atypedef-name is syntactically equivalent to a keyword and names the type associated with the identifier in
the way described in Clause 8. A typedef-name is thus a synonym for another type. A typedef-name does
not introduce a new type the way a class declaration (9.1) 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 ]
2Atypedef-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. It has the same semantics as if it were introduced by the typedef specifier. In particular, it
does not define a new type and it shall not appear in the type-id. [ 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 ]
3Atypedef-name shall not name an array of runtime bound.
4In 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 ]
5In 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 ]
6If 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
§ 7.1.3 141
c
ISO/IEC N????
}
struct S { }; // OK
— end example ]
7In 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 ]
8Similarly, 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 ]
9[Note: Atypedef-name that names a class type, or a cv-qualified version thereof, is also a class-name (9.1).
If a typedef-name is used to identify the subject of an elaborated-type-specifier (7.1.6.3), a class definition
(Clause 9), a constructor declaration (12.1), or a destructor declaration (12.4), 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 ]
10 If the typedef declaration defines an unnamed class (or enum), the first typedef-name declared by the dec-
laration to be that class type (or enum type) is used to denote the class type (or enum type) for linkage
purposes only (3.5). [ Example:
typedef struct { } *ps, S; // Sis the class name for linkage purposes
— end example ]
7.1.4 The friend specifier [dcl.friend]
1The friend specifier is used to specify access to class members; see 11.3.
7.1.5 The constexpr specifier [dcl.constexpr]
1The constexpr specifier shall be applied only to the definition of a variable or variable template, the
declaration of a function or function template, or the declaration of a static data member of a literal
type (3.9). If any declaration of a function, function template, or variable 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
§ 7.1.5 142
c
ISO/IEC N????
};
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 (5.19) 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 ]
2Aconstexpr 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.constexpr functions and constexpr constructors are implicitly
inline (7.1.2).
3The definition of a constexpr function shall satisfy the following constraints:
it shall not be virtual (10.3);
its return type shall be a literal type;
each of its parameter types shall be a literal type;
its function-body shall be = delete,= default, or a compound-statement that does not contain
an asm-definition,
a goto statement,
a try-block, or
a definition of a variable of non-literal type or of static or thread storage duration or for which
no initialization is performed.
[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;
}
§ 7.1.5 143
c
ISO/IEC N????
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 ]
4The definition of a constexpr constructor shall satisfy the following constraints:
the class shall not have any virtual base classes;
each of the parameter types shall be a literal type;
its function-body shall not be a function-try-block;
In addition, either its function-body shall be = delete, or it shall satisfy the following constraints:
either its function-body shall be = default, or the compound-statement of its function-body shall satisfy
the constraints for a function-body of a constexpr function;
every non-variant non-static data member and base class sub-object shall be initialized (12.6.2);
if the class is a non-empty union, or for each non-empty anonymous union member of a non-union
class, exactly one non-static data member shall be initialized;
every constructor involved in initializing non-static data members and base class sub-objects shall be
aconstexpr constructor.
[Example:
struct Length {
explicit constexpr Length(int i = 0) : val(i) { }
private:
int val;
};
— end example ]
5For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting
constexpr constructor, if no argument values exist such that an invocation of the function or constructor
could be an evaluated subexpression of a core constant expression (5.19), 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) { } // xis 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
};
§ 7.1.5 144
c
ISO/IEC N????
— end example ]
6If 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
aconstexpr function or constexpr constructor when considered as a non-template function or constructor,
the template is ill-formed; no diagnostic required.
7A call to a constexpr function produces the same result as a call to an equivalent non-constexpr function
in all respects except that a call to a constexpr function can appear in a constant expression.
8The constexpr specifier has no effect on the type of a constexpr function or a constexpr constructor. The
class of which a constexpr function is a member shall be a literal type (3.9). [ Example:
class debug_flag {
public:
explicit debug_flag(bool);
constexpr bool is_on() const; // error: debug_flag not
// literal type
private:
bool flag;
};
constexpr int bar(int x, int y) // OK
{ return x + y + x*y; }
// ...
int bar(int x, int y) // error: redefinition of bar
{returnx*2+3*y;}
— end example ]
9Aconstexpr specifier used in an object declaration declares the object as const. Such an object shall have
literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant
expression (5.19). Otherwise, or if a constexpr specifier is used in a reference declaration, every full-
expression that appears in its initializer shall be a constant expression. [ Note: Each implicit conversion
used in converting the initializer expressions and each constructor call used for the initialization is part of
such a full-expression. — end note ] [ Example:
struct pixel {
int x, y;
};
constexpr pixel ur = { 1294, 1024 };// OK
constexpr pixel origin; // error: initializer missing
— end example ]
7.1.6 Type specifiers [dcl.type]
1The type-specifiers are
type-specifier:
trailing-type-specifier
class-specifier
enum-specifier
trailing-type-specifier:
simple-type-specifier
elaborated-type-specifier
typename-specifier
cv-qualifier
§ 7.1.6 145
c
ISO/IEC N????
type-specifier-seq:
type-specifier attribute-specifier-seqopt
type-specifier type-specifier-seq
trailing-type-specifier-seq:
trailing-type-specifier attribute-specifier-seqopt
trailing-type-specifier trailing-type-specifier-seq
The optional attribute-specifier-seq in a type-specifier-seq or a trailing-type-specifier-seq appertains to the
type denoted by the preceding type-specifiers (8.3). The attribute-specifier-seq affects the type only for the
declaration it appears in, not other declarations involving the same type.
2As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration or
in a type-specifier-seq or trailing-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.
3Except in a declaration of a constructor, destructor, or conversion function, at least one type-specifier
that is not a cv-qualifier shall appear in a complete type-specifier-seq or a complete decl-specifier-seq.94
Atype-specifier-seq shall not define a class or enumeration unless it appears in the type-id of an alias-
declaration (7.1.3) that is not the declaration of a template-declaration.
4[Note: enum-specifiers, class-specifiers, and typename-specifiers are discussed in 7.2, Clause 9, and 14.6,
respectively. The remaining type-specifiers are discussed in the rest of this section. — end note ]
7.1.6.1 The cv-qualifiers [dcl.type.cv]
1There 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 of the declaration shall
not be empty. [ Note: 3.9.3 and 8.3.5 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 ]
2[Note: Declaring a variable const can affect its linkage (7.1.1) and its usability in constant expressions (5.19).
As described in 8.5, the definition of an object or subobject of const-qualified type must specify an initializer
or be subject to default-initialization. — end note ]
3A 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 (5.2.11). — end note ]
4Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const
object during its lifetime (3.8) 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
94) 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.
§ 7.1.6.1 146
c
ISO/IEC N????
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
5For 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 ]
6What constitutes an access to an object that has volatile-qualified type is implementation-defined. If an
attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with
a non-volatile-qualified type, the program behavior is undefined.
7[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 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the
same in C++ as they are in C. — end note ]
7.1.6.2 Simple type specifiers [dcl.type.simple]
1The simple type specifiers are
§ 7.1.6.2 147
c
ISO/IEC N????
simple-type-specifier:
nested-name-specifieropt type-name
nested-name-specifier template simple-template-id
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 )
2The auto specifier is a placeholder for a type to be deduced (7.1.6.4). The other simple-type-specifiers
specify either a previously-declared type, a type determined from an expression, or one of the fundamental
types (3.9.1). Table 10 summarizes the valid combinations of simple-type-specifiers and the types they
specify.
3When 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 and certain bit-fields (9.6) are
represented as signed or unsigned quantities. The signed specifier forces char objects and bit-fields to be
signed; it is redundant in other contexts. — end note ]
§ 7.1.6.2 148
c
ISO/IEC N????
Table 10 — simple-type-specifiers and the types they specify
Specifier(s) Type
type-name the type named
simple-template-id the type as defined in 14.2
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(expression) the type as defined below
§ 7.1.6.2 149
c
ISO/IEC N????
4For an expression e, the type denoted by decltype(e) is defined as follows:
if ehas type “array of runtime bound”, the program is ill-formed;
otherwise, if eis an unparenthesized id-expression or an unparenthesized class member access (5.2.5),
decltype(e) is the type of the entity named by e. If there is no such entity, or if enames a set of
overloaded functions, the program is ill-formed;
otherwise, if eis an xvalue, decltype(e) is T&&, where Tis the type of e;
otherwise, if eis an lvalue, decltype(e) is T&, where Tis the type of e;
otherwise, decltype(e) is the type of e.
The operand of the decltype specifier is an unevaluated operand (Clause 5).
[Example:
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 0; // 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 7.1.6.4.
— end note ]
5[Note: in the case where the operand of a decltype-specifier is a function call and the return type of the
function is a class type, a special rule (5.2.2) ensures that the return type is not required to be complete (as
it would be if the call appeared in a sub-expression or outside of a decltype-specifier). 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. [ 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 (14.8.2) 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() {
§ 7.1.6.2 150
c
ISO/IEC N????
q(42); // Error: deduction against qsucceeds, 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 ]— end note ]
7.1.6.3 Elaborated type specifiers [dcl.type.elab]
elaborated-type-specifier:
class-key attribute-specifier-seqopt nested-name-specifieropt identifier
class-key nested-name-specifieropt templateopt simple-template-id
enum nested-name-specifieropt identifier
1An attribute-specifier-seq shall not appear in an elaborated-type-specifier unless the latter is the sole con-
stituent 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 (14.7.3), an explicit instantiation (14.7.2) or it has one of
the following forms:
class-key attribute-specifier-seqopt identifier ;
friend class-key ::opt identifier ;
friend class-key ::opt simple-template-id ;
friend class-key nested-name-specifier identifier ;
friend class-key nested-name-specifier templateopt 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.
23.4.4 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 (11.3). — end note ]
3The class-key or enum keyword present in the elaborated-type-specifier shall agree in kind with the dec-
laration 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 (7.2), the union class-key shall be used to refer to a union (Clause 9), and either the class
or struct class-key shall be used to refer to a class (Clause 9) declared using the class or struct class-key.
[Example:
enum class E { a, b };
enum E x = E::a; // OK
— end example ]
7.1.6.4 auto specifier [dcl.spec.auto]
1The auto and decltype(auto) type-specifiers designate a placeholder type that will be replaced later, either
by deduction from an initializer or by explicit specification with a trailing-return-type. The auto type-specifier
is also used to signify that a lambda is a generic lambda.
2The 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 func-
tion declarator includes a trailing-return-type (8.3.5), that specifies the declared return type of the function.
If the declared return type of the function contains a placeholder type, the return type of the function is
deduced from return statements in the body of the function, if any.
§ 7.1.6.4 151
c
ISO/IEC N????
3If the auto type-specifier appears as one of the decl-specifiers in the decl-specifier-seq of a parameter-
declaration of a lambda-expression, the lambda is a generic lambda (5.1.2). [ Example:
auto glambda = [](int i, auto a) { return i; }; // OK: a generic lambda
— end example ]
4The type of a variable declared using auto or decltype(auto) is deduced from its initializer. This use is al-
lowed when declaring variables in a block (6.3), in namespace scope (3.3.6), and in a for-init-statement (6.5.3).
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 init-declarators, each of which shall have a non-empty initial-
izer. In an initializer of the form
(expression-list )
the expression-list shall be a single assignment-expression.
[Example:
auto x = 5; // OK: xhas type int
const auto *v = &x, u = 6; // OK: vhas type const int*,uhas type const int
static auto y = 0.0; // OK: yhas type double
auto int r; // error: auto is not a storage-class-specifier
auto f() -> int; // OK: freturns int
auto g() { return 0.0; } // OK: greturns double
auto h(); // OK: h’s return type will be deduced when it is defined
— end example ]
5A placeholder type can also be used in declaring a variable in the condition of a selection statement (6.4) or
an iteration statement (6.5), in the type-specifier-seq in the new-type-id or type-id of a new-expression (5.3.4), in
afor-range-declaration, and in declaring a static data member with a brace-or-equal-initializer that appears
within the member-specification of a class definition (9.4.2).
6A program that uses auto or decltype(auto) in a context not explicitly allowed in this section is ill-formed.
7When a variable declared using a placeholder type is initialized, or a return statement occurs in a function
declared with a return type that contains a placeholder type, the deduced return type or variable type
is determined from the type of its initializer. In the case of a return with no operand, the initializer is
considered to be void(). Let Tbe the declared type of the variable or return type of the function. If the
placeholder is the auto type-specifier, the deduced type is determined using the rules for template argument
deduction. If the deduction is for a return statement and the initializer is a braced-init-list (8.5.4), the
program is ill-formed. Otherwise, obtain Pfrom Tby replacing the occurrences of auto with either a
new invented type template parameter Uor, if the initializer is a braced-init-list, with std::initializer_-
list<U>. Deduce a value for Uusing the rules of template argument deduction from a function call (14.8.2.1),
where Pis a function template parameter type and the initializer is the corresponding argument. If the
deduction fails, the declaration is ill-formed. Otherwise, the type deduced for the variable or return type is
obtained by substituting the deduced Uinto P. [ Example:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
— end example ]
[Example:
const auto &i = expr;
The type of iis the deduced type of the parameter uin the call f(expr) of the following invented
function template:
template <class U> void f(const U& u);
§ 7.1.6.4 152
c
ISO/IEC N????
— end example ]
If the placeholder is the decltype(auto) type-specifier, the declared type of the variable or return type
of the function shall be the placeholder alone. The type deduced for the variable or return type is determined
as described in 7.1.6.2, as though the initializer had been the operand of the decltype. [ Example:
int i;
int&& f();
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 ]
8If 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 as described above, 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
autoa=5,b={1,2}; // error: different types for auto
— end example ]
9If a function with a declared return type that contains a placeholder type has multiple return statements,
the return type is deduced for each return statement. If the type deduced is not the same in each deduction,
the program is ill-formed.
10 If a function with a declared return type that uses a placeholder type has no 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 ]
11 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 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 ]
12 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
§ 7.1.6.4 153
c
ISO/IEC N????
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. — 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 ]
13 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 ]
14 A function declared with a return type that uses a placeholder type shall not be virtual (10.3).
15 An explicit instantiation declaration (14.7.2) 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 ]
7.2 Enumeration declarations [dcl.enum]
1An enumeration is a distinct type (3.9.2) with named constants. Its name becomes an enum-name, within
its scope.
enum-name:
identifier
enum-specifier:
enum-head {enumerator-listopt }
enum-head {enumerator-list , }
§ 7.2 154
c
ISO/IEC N????
enum-head:
enum-key attribute-specifier-seqopt identifieropt enum-baseopt
enum-key attribute-specifier-seqopt nested-name-specifier identifier
enum-baseopt
opaque-enum-declaration:
enum-key attribute-specifier-seqopt identifier enum-baseopt ;
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
The optional attribute-specifier-seq in the enum-head and the opaque-enum-declaration appertains to
the enumeration; the attributes in that attribute-specifier-seq are thereafter considered attributes of the
enumeration whenever it is named.
2The enumeration type declared with an enum-key of only enum is an unscoped enumeration, and its enumer-
ators are unscoped enumerators. The enum-keysenum 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 enu-
merator by one.
[Example:
enum { a, b, c=0 };
enum { d, e, f=e+2 };
defines a,c, and dto be zero, band eto be 1, and fto be 3.— end example ]
3An 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.
4If 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.
5Each 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 enum-base; if not explicitly specified,
the underlying type of a scoped enumeration type is int. In these cases, the underlying type is said to be
§ 7.2 155
c
ISO/IEC N????
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 (5.19); if the initializing value of an enumerator cannot be represented by the underlying
type, the program is ill-formed. If the underlying type is not fixed, the type of each enumerator is the type
of its initializing value:
If an initializer is specified for an enumerator, the initializing value has the same type as the expression
and the constant-expression shall be an integral constant expression (5.19).
If no initializer is specified for the first enumerator, the initializing value has an unspecified integral
type.
Otherwise the type of the initializing value is the same as the type of the initializing value 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.
6An enumeration whose underlying type is fixed is an incomplete type from its point of declaration (3.3.2)
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.
7For 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.
8For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the
underlying type. Otherwise, for an enumeration where emin is the smallest enumerator and emax is the
largest, the values of the enumeration are the values in the range bmin to bmax, defined as follows: Let K
be 1 for a two’s complement representation and 0 for a one’s complement or sign-magnitude representation.
bmax is the smallest value greater than or equal to max(|emin| − K, |emax|)and equal to 2M1, where
Mis a non-negative integer. bmin is zero if emin is non-negative and (bmax +K)otherwise. The size of
the smallest bit-field large enough to hold all the values of the enumeration type is max(M, 1) if bmin is
zero and M+ 1 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.95
9Two enumeration types are layout-compatible if they have the same underlying type.
10 The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by
integral promotion (4.5). [ 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.
95) 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.
§ 7.2 156
c
ISO/IEC N????
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 ]
11 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 (3.3) and (3.4).[ 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 5.2.5. [ 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 ]
7.3 Namespaces [basic.namespace]
1A 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.
§ 7.3 157
c
ISO/IEC N????
2The outermost declarative region of a translation unit is a namespace; see 3.3.6.
7.3.1 Namespace definition [namespace.def]
1The grammar for a namespace-definition is
namespace-name:
original-namespace-name
namespace-alias
original-namespace-name:
identifier
namespace-definition:
named-namespace-definition
unnamed-namespace-definition
named-namespace-definition:
original-namespace-definition
extension-namespace-definition
original-namespace-definition:
inlineopt namespace identifier {namespace-body }
extension-namespace-definition:
inlineopt namespace original-namespace-name {namespace-body }
unnamed-namespace-definition:
inlineopt namespace { namespace-body }
namespace-body:
declaration-seqopt
2The identifier in an original-namespace-definition shall not have been previously defined in the declarative
region in which the original-namespace-definition appears. The identifier in an original-namespace-definition
is the name of the namespace. Subsequently in that declarative region, it is treated as an original-namespace-
name.
3The original-namespace-name in an extension-namespace-definition shall have previously been defined in an
original-namespace-definition in the same declarative region.
4Every namespace-definition shall appear in the global scope or in a namespace scope (3.3.6).
5Because 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 ]
6The 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 7.3.1.2). 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
§ 7.3.1 158
c
ISO/IEC N????
}
void V::C::m() { // enclosing namespaces are the global namespace, Q, and Q::V
}
}
— end example ]
7If 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 an extension-
namespace-definition only if it was previously used on the original-namespace-definition for that namespace.
8Members 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 (3.4.2) whenever one of them is, and a using-
directive (7.3.4) that names the inline namespace is implicitly inserted into the enclosing namespace as for
an unnamed namespace (7.3.1.1). Furthermore, each member of the inline namespace can subsequently be
explicitly instantiated (14.7.2) or explicitly specialized (14.7.3) as though it were a member of the enclosing
namespace. Finally, looking up a name in the enclosing namespace via explicit qualification (3.4.3.2) 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.
9These properties are transitive: if a namespace Ncontains an inline namespace M, which in turn contains an
inline namespace O, then the members of Ocan be used as though they were members of Mor N. The inline
namespace set of Nis 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.
7.3.1.1 Unnamed namespaces [namespace.unnamed]
1An unnamed-namespace-definition behaves as if it were replaced by
inlineopt 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, all occurrences of
unique in a translation unit are replaced by the same identifier, and this identifier differs from all other
identifiers in the entire program.96 [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
}
96) Although entities in an unnamed namespace might have external linkage, they are effectively qualified by a name unique
to their translation unit and therefore can never be seen from any other translation unit.
§ 7.3.1.1 159
c
ISO/IEC N????
— end example ]
7.3.1.2 Namespace member definitions [namespace.memdef]
1Members (including explicit specializations of templates (14.7.3)) of a namespace can be defined within that
namespace. [ Example:
namespace X {
void f() { /... /}
}
— end example ]
2Members of a named namespace can also be defined outside that namespace by explicit qualification (3.4.3.2)
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: Rdoesn’t enclose Q
}
— end example ]
3Every name first declared in a namespace is a member of that namespace. 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 (3.4.1) or qualified lookup (3.4.3). [ 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 (3.4.2). 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 fand ghave 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
97) this implies that the name of the class or function is unqualified.
§ 7.3.1.2 160
c
ISO/IEC N????
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: fis not a member of A::X
A::X::Y::g(); // error: gis not a member of A::X::Y
}
— end example ]
7.3.2 Namespace alias [namespace.alias]
1Anamespace-alias-definition declares an alternate name for a namespace according to the following grammar:
namespace-alias:
identifier
namespace-alias-definition:
namespace identifier =qualified-namespace-specifier ;
qualified-namespace-specifier:
nested-name-specifieropt namespace-name
2The 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 3.4.6.— end note ]
3In 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 ]
4Anamespace-name or namespace-alias shall not be declared as the name of any other entity in the same
declarative region. A namespace-name defined at global scope shall not be declared as the name of any
other entity in any global scope of the program. No diagnostic is required for a violation of this rule by
declarations in different translation units.
7.3.3 The using declaration [namespace.udecl]
1Ausing-declaration introduces a name into the declarative region in which the using-declaration appears.
using-declaration:
using typenameopt nested-name-specifier unqualified-id ;
using :: unqualified-id ;
The member name specified in a using-declaration is declared in the declarative region in which the
using-declaration appears. [ 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
§ 7.3.3 161
c
ISO/IEC N????
note ] If a using-declaration names a constructor (3.4.3.1), it implicitly declares a set of constructors in the
class in which the using-declaration appears (12.9); otherwise the name specified in a using-declaration is a
synonym for the name of some entity declared elsewhere.
2Every using-declaration is a declaration and a member-declaration and so can 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 ]
3In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the
class being defined. If such a using-declaration names a constructor, the nested-name-specifier shall name a
direct base class of the class being defined; otherwise it introduces the set of declarations found by member
name lookup (10.2,3.4.3.1). [ Example:
class C {
int g();
};
class D2 : public B {
using B::f; // OK: Bis a base of D2
using B::e; // OK: eis an enumerator of base B
using B::x; // OK: xis a union member of base B
using C::g; // error: Cisn’t a base of D2
};
— end example ]
4[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 (14.5.2). — end note ] If an
assignment operator brought from a base class into a derived class scope has the signature of a copy/move
assignment operator for the derived class (12.8), the using-declaration does not by itself suppress the implicit
declaration of the derived class assignment operator; the copy/move assignment operator from the base class
is hidden or overridden by the implicitly-declared copy/move assignment operator of the derived class, as
described below.
5Ausing-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
};
§ 7.3.3 162
c
ISO/IEC N????
— end example ]
6Ausing-declaration shall not name a namespace.
7Ausing-declaration shall not name a scoped enumerator.
8Ausing-declaration for 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 ]
9Members declared by a using-declaration can be referred to by explicit qualification just like other member
names (3.4.3.2). In a using-declaration, a prefix :: refers to the global namespace. [ 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 ]
10 Ausing-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;
using A::i; // OK: double declaration
}
void f() {
using A::i;
using A::i; // error: double declaration
}
struct B {
§ 7.3.3 163
c
ISO/IEC N????
int i;
};
struct X : B {
using B::i;
using B::i; // error: double member declaration
};
— end example ]
11 The entity declared by a using-declaration shall be known in the context using it according to its definition
at the point of the using-declaration. Definitions added to the namespace after the using-declaration are not
considered when a use of the name is made. [ Example:
namespace A {
void f(int);
}
using A::f; // fis 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; // fis a synonym for A::f;
// that is, for A::f(int) and A::f(char).
f(’a’); // calls f(char)
}
— end example ]
12 [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 (14.5.5). — end note ]
13 Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same
declarative region (3.3) 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;
§ 7.3.3 164
c
ISO/IEC N????
using B::i; // error: ideclared twice
void f(char);
using B::f; // OK: each fis 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 ]
14 If a function declaration in namespace scope or block scope has the same name and the same parameter-
type-list (8.3.5) 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
ausing-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 ]
15 When a using-declaration brings names from a base class into a derived class scope, 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 (8.3.5), cv-qualification, and ref-qualifier (if any) in a
base class (rather than conflicting). [ Note: For using-declarations that name a constructor, see 12.9.— end
note ] [ Example:
struct B {
virtual void f(int);
virtual void f(char);
void g(int);
void h(int);
};
struct D : B {
§ 7.3.3 165
c
ISO/IEC N????
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)
}
— end example ]
16 For the purpose of overload resolution, the functions which are introduced by a using-declaration into a
derived class will be 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.
17 The access rules for inheriting constructors are specified in 12.9; otherwise all instances of the name mentioned
in a using-declaration shall be accessible. In particular, if a derived class uses a using-declaration 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-declaration shall be visible in the scope of at least one of the direct base classes of the class where the
using-declaration is specified. [ Note: Because a using-declaration designates a base class member (and not
a member subobject or a member function of a base class subobject), a using-declaration cannot be used to
resolve inherited member ambiguities. For 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(); // ambiguous: B::x or C::x
}
— end note ]
18 The alias created by the using-declaration has the usual accessibility for a member-declaration. [ Note: A
using-declaration that names a constructor does not create aliases; see 12.9 for the pertinent accessibility
rules. — end note ] [ Example:
class A {
private:
void f(char);
§ 7.3.3 166
c
ISO/IEC N????
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 ]
19 If a using-declaration uses the keyword typename and specifies a dependent name (14.6.2), the name intro-
duced by the using-declaration is treated as a typedef-name (7.1.3).
7.3.4 Using directive [namespace.udir]
using-directive:
attribute-specifier-seqopt using namespace nested-name-specifieropt namespace-name ;
1Ausing-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 3.4.6.— end note ] The optional attribute-specifier-seq appertains to the using-directive.
2Ausing-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 (3.4.1), 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 ]
3Ausing-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 Band 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 iis visible
}
— end example ]
§ 7.3.4 167
c
ISO/IEC N????
4For unqualified lookup (3.4.1), 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 3.4.3.2.— 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 ]
5If a namespace is extended by an extension-namespace-definition 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 extension-namespace-definition can be used after the extension-namespace-definition.
6If 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 {
§ 7.3.4 168
c
ISO/IEC N????
void X(int);
extern "C" int g();
extern "C++" int h(int);
}
using namespace A;
using namespace B;
void f() {
X(1); // error: name Xfound in two namespaces
g(); // okay: name grefers to the same entity
h(); // okay: overload resolution selects A::h
}
— end note ]
7During 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.98 [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)
}
98) During name lookup in a class hierarchy, some ambiguities may be resolved by considering whether one member hides
the other along some paths (10.2). There is no such disambiguation when considering the set of names found as a result of
following using-directives.
§ 7.3.4 169
c
ISO/IEC N????
— end example ]
7.4 The asm declaration [dcl.asm]
1An asm declaration has the form
asm-definition:
asm ( string-literal ) ;
The asm declaration is conditionally-supported; its meaning is implementation-defined. [ Note: Typically
it is used to pass information through the implementation to an assembler. — end note ]
7.5 Linkage specifications [dcl.link]
1All function types, function names with external linkage, and variable names with external linkage have a
language linkage. [ Note: Some of the properties associated with an entity with language linkage are specific
to each implementation and are not described here. For example, a particular language linkage may be
associated with a particular form of representing names of objects and functions with external linkage, or
with a particular calling convention, etc. — end note ] The default language linkage of all function types,
function names, and variable names is C++ language linkage. Two function types with different language
linkages are distinct types even if they are otherwise identical.
2Linkage (3.5) between C++ and non-C++ code fragments can be achieved using a linkage-specification:
linkage-specification:
extern string-literal {declaration-seqopt }
extern string-literal declaration
The string-literal indicates the required language linkage. This International Standard specifies the se-
mantics for the string-literals"C" and "C++". Use of a string-literal other than "C" or "C++" is conditionally-
supported, with implementation-defined semantics. [ Note: Therefore, a linkage-specification with a string-
literal that is unknown to the implementation requires a diagnostic. — end note ] [ Note: It is recommended
that the spelling of the string-literal be taken from the document defining that language. For example, Ada
(not ADA) and Fortran or FORTRAN, depending on the vintage. — end note ]
3Every implementation shall provide for linkage to functions written in the C programming language, "C",
and linkage to C++ functions, "C++". [ Example:
complex sqrt(complex); // C++ linkage by default
extern "C" {
double sqrt(double); // C linkage
}
— end example ]
4Linkage specifications nest. When linkage specifications nest, the innermost one determines the language
linkage. A linkage specification does not establish a scope. A linkage-specification shall occur only in
namespace scope (3.3). In a linkage-specification, the specified language linkage applies to the function
types of all function declarators, function names with external linkage, and variable names with external
linkage declared within the linkage-specification. [ Example:
extern "C" void f1(void(*pf)(int));
// the name f1 and its function type have C language
// linkage; pf is a pointer to a C function
extern "C" typedef void FUNC();
FUNC f2; // the name f2 has C++ language linkage and the
// function’s type has C language linkage
extern "C" FUNC f3; // the name of function f3 and the function’s type
// have C language linkage
void (*pf2)(FUNC*); // the name of the variable pf2 has C++ linkage and
// the type of pf2 is pointer to C++ function that
// takes one parameter of type pointer to C function
extern "C" {
static void f4(); // the name of the function f4 has
§ 7.5 170
c
ISO/IEC N????
// internal linkage (not C language
// linkage) and the function’s type
// has C language linkage.
}
extern "C" void f5() {
extern void f4(); // OK: Name linkage (internal)
// and function type linkage (C
// language linkage) gotten from
// previous declaration.
}
extern void f4(); // OK: Name linkage (internal)
// and function type linkage (C
// language linkage) gotten from
// previous declaration.
void f6() {
extern void f4(); // OK: Name linkage (internal)
// and function type linkage (C
// language linkage) gotten from
// previous declaration.
}
— end example ] A C language linkage is ignored in determining the language linkage of the names of class
members and the function type of class member functions. [ Example:
extern "C" typedef void FUNC_c();
class C {
void mf1(FUNC_c*); // the name of the function mf1 and the member
// function’s type have C++ language linkage; the
// parameter has type pointer to C function
FUNC_c mf2; // the name of the function mf2 and the member
// function’s type have C++ language linkage
static FUNC_c* q; // the name of the data member qhas C++ language
// linkage and the data member’s type is pointer to
// C function
};
extern "C" {
class X {
void mf(); // the name of the function mf and the member
// function’s type have C++ language linkage
void mf2(void(*)()); // the name of the function mf2 has C++ language
// linkage; the parameter has type pointer to
// C function
};
}
— end example ]
5If two declarations declare functions with the same name and parameter-type-list (8.3.5) to be members of
the same namespace or declare objects with the same name to be members of the same namespace and the
declarations give the names different language linkages, the program is ill-formed; no diagnostic is required
if the declarations appear in different translation units. Except for functions with C++ linkage, a function
declaration without a linkage specification shall not precede the first linkage specification for that function.
§ 7.5 171
c
ISO/IEC N????
A function can be declared without a linkage specification after an explicit linkage specification has been
seen; the linkage explicitly specified in the earlier declaration is not affected by such a function declaration.
6At most one function with a particular name can have C language linkage. Two declarations for a function
with C language linkage with the same function name (ignoring the namespace names that qualify it) that
appear in different namespace scopes refer to the same function. Two declarations for a variable with C
language linkage with the same name (ignoring the namespace names that qualify it) that appear in different
namespace scopes refer to the same variable. An entity with C language linkage shall not be declared with
the same name as an entity in global scope, unless both declarations denote the same entity; no diagnostic
is required if the declarations appear in different translation units. A variable with C language linkage shall
not be declared with the same name as a function with C language linkage (ignoring the namespace names
that qualify the respective names); no diagnostic is required if the declarations appear in different translation
units. [ Note: Only one definition for an entity with a given name with C language linkage may appear in
the program (see 3.2); this implies that such an entity must not be defined in more than one namespace
scope. — end note ] [ Example:
int x;
namespace A {
extern "C" int f();
extern "C" int g() { return 1; }
extern "C" int h();
extern "C" int x(); // ill-formed: same name as global-space object x
}
namespace B {
extern "C" int f(); // A::f and B::f refer to the same function
extern "C" int g() { return 1; } // ill-formed, the function g
// with C language linkage has two definitions
}
int A::f() { return 98; } //definition for the function fwith C language linkage
extern "C" int h() { return 97; } // definition for the function hwith C language linkage
// A::h and ::h refer to the same function
— end example ]
7A declaration directly contained in a linkage-specification is treated as if it contains the extern speci-
fier (7.1.1) for the purpose of determining the linkage of the declared name and whether it is a definition.
Such a declaration shall not specify a storage class. [ Example:
extern "C" double f();
static double f(); // error
extern "C" int i; // declaration
extern "C" {
int i; // definition
}
extern "C" static void g(); // error
— end example ]
8[Note: Because the language linkage is part of a function type, when indirecting through a pointer to C
function, the function to which the resulting lvalue refers is considered a C function. — end note ]
9Linkage from C++ to objects defined in other languages and to objects defined in C++ from other languages
is implementation-defined and language-dependent. Only where the object layout strategies of two language
§ 7.5 172
c
ISO/IEC N????
implementations are similar enough can such linkage be achieved.
7.6 Attributes [dcl.attr]
7.6.1 Attribute syntax and semantics [dcl.attr.grammar]
1Attributes specify additional information for various source constructs such as types, variables, names,
blocks, or translation units.
attribute-specifier-seq:
attribute-specifier-seqopt attribute-specifier
attribute-specifier:
[ [ attribute-list ] ]
alignment-specifier
alignment-specifier:
alignas ( type-id ...opt )
alignas ( assignment-expression ...opt )
attribute-list:
attributeopt
attribute-list ,attributeopt
attribute ...
attribute-list ,attribute ...
attribute:
attribute-token attribute-argument-clauseopt
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-tokenopt
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
2[Note: For each individual attribute, the form of the balanced-token-seq will be specified. — end note ]
3In 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 (14.5.3). 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 (2.12)
or an alternative token (2.6) that satisfies the syntactic requirements of an identifier (2.11) is contained
in an attribute-token, it is considered an identifier. No name lookup (3.4) 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). The use of an attribute-scoped-token is conditionally-supported, with
implementation-defined behavior. [ Note: Each implementation should choose a distinctive name for the
attribute-namespace in an attribute-scoped-token.— end note ]
4Each attribute-specifier-seq is said to appertain to some entity or statement, identified by the syntactic
context where it appears (Clause 6, Clause 7, Clause 8). If an attribute-specifier-seq that appertains to
some entity or statement contains an attribute that is not allowed to apply to that entity or statement, the
§ 7.6.1 173
c
ISO/IEC N????
program is ill-formed. If an attribute-specifier-seq appertains to a friend declaration (11.3), that declaration
shall be a definition. No attribute-specifier-seq shall appertain to an explicit instantiation (14.7.2).
5For an attribute-token not specified in this International Standard, the behavior is implementation-defined.
6Two consecutive left square bracket tokens shall appear only when introducing an attribute-specifier. [ 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.
}
— end example ]
7.6.2 Alignment specifier [dcl.align]
1An 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, an exception-declaration (15.3), or a variable declared with the register
storage class specifier. An alignment-specifier may also be applied to the declaration or definition of a
class (in an elaborated-type-specifier (7.1.6.3) or class-head (Clause 9), respectively) and to the declaration
or definition of an enumeration (in an opaque-enum-declaration or enum-head, respectively (7.2)). An
alignment-specifier with an ellipsis is a pack expansion (14.5.3).
2When the alignment-specifier is of the form alignas( assignment-expression ):
the assignment-expression shall be an integral constant expression
if the constant expression evaluates to a fundamental alignment, the alignment requirement of the
declared entity shall be the specified fundamental alignment
if the constant expression evaluates to an extended alignment and the implementation supports that
alignment in the context of the declaration, the alignment of the declared entity shall be that alignment
if the constant expression evaluates to an extended alignment and the implementation does not support
that alignment in the context of the declaration, the program is ill-formed
if the constant expression evaluates to zero, the alignment specifier shall have no effect
otherwise, the program is ill-formed.
3When the alignment-specifier is of the form alignas( type-id ), it shall have the same effect as alignas(
alignof(type-id )) (5.3.6).
4When multiple alignment-specifiers are specified for an entity, the alignment requirement shall be set to the
strictest specified alignment.
5The 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 were
omitted (including those in other declarations).
6If 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:
§ 7.6.2 174
c
ISO/IEC N????
// Translation unit #1:
struct S { int x; } s, p = &s;
// Translation unit #2:
struct alignas(16) S; // error: definition of Slacks alignment; no
extern S* p; // diagnostic required
— end example ]
7[Example: An aligned buffer with an alignment requirement of Aand holding Nelements of type Tother
than char,signed char, or unsigned char 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 ]
8[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 ]
7.6.3 Noreturn attribute [dcl.attr.noreturn]
1The 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.
2If a function fis called where fwas previously declared with the noreturn attribute and feventually
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 ]
3[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 ]
7.6.4 Carries dependency attribute [dcl.attr.depend]
1The 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 (1.10) each lvalue-
to-rvalue conversion (4.1) 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.
§ 7.6.4 175
c
ISO/IEC N????
2The 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.
3[Note: The carries_dependency attribute does not change the meaning of the program, but may result in
generation of more efficient code. — end note ]
4[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));
}
5The carries_dependency attribute on function fmeans that the return value carries a dependency out of
f, so that the implementation need not constrain ordering upon return from f. Implementations of fand
its caller may choose to preserve dependencies instead of emitting hardware memory ordering instructions
(a.k.a. fences).
6Function g’s second parameter has a carries_dependency attribute, but its first parameter does not. There-
fore, function h’s first call to gcarries 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 ]
§ 7.6.4 176
c
ISO/IEC N????
8 Declarators [dcl.decl]
1A 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.
init-declarator-list:
init-declarator
init-declarator-list ,init-declarator
init-declarator:
declarator initializeropt
2The three components of a simple-declaration are the attributes (7.6), the specifiers (decl-specifier-seq;7.1)
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 8.5 and 12.6.
3Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself.99
4Declarators have the syntax
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-seqopt
noptr-declarator parameters-and-qualifiers
noptr-declarator [expressionopt ]attribute-specifier-seqopt
(ptr-declarator )
parameters-and-qualifiers:
(parameter-declaration-clause )cv-qualifier-seqopt
ref-qualifieropt exception-specificationopt attribute-specifier-seqopt
trailing-return-type:
-> trailing-type-specifier-seq abstract-declaratoropt
99) 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 Tis a decl-specifier-seq and each Di is an init-declarator. An exception occurs 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 occurs when Tis auto (7.1.6.4), for example:
auto i = 1, j = 2.0; // error: deduced types for iand jdo not match
as opposed to
auto i = 1; // OK: ideduced to have type int
auto j = 2.0; // OK: jdeduced to have type double
Declarators 177
c
ISO/IEC N????
ptr-operator:
*attribute-specifier-seqopt cv-qualifier-seqopt
&attribute-specifier-seqopt
&& attribute-specifier-seqopt
nested-name-specifier *attribute-specifier-seqopt cv-qualifier-seqopt
cv-qualifier-seq:
cv-qualifier cv-qualifier-seqopt
cv-qualifier:
const
volatile
ref-qualifier:
&
&&
declarator-id:
...opt id-expression
5The optional attribute-specifier-seq in a trailing-return-type appertains to the indicated return type. The
type-id in a trailing-return-type includes the longest possible sequence of abstract-declarators. [ Note: This
resolves the ambiguous binding of array and function declarators. [ Example:
auto f()->int(*)[4]; // function returning a pointer to array[4] of int
// not function returning array[4] of pointer to int
— end example ]— end note ]
8.1 Type names [dcl.name]
1To 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.
type-id:
type-specifier-seq abstract-declaratoropt
abstract-declarator:
ptr-abstract-declarator
noptr-abstract-declaratoropt parameters-and-qualifiers trailing-return-type
abstract-pack-declarator
ptr-abstract-declarator:
noptr-abstract-declarator
ptr-operator ptr-abstract-declaratoropt
noptr-abstract-declarator:
noptr-abstract-declaratoropt parameters-and-qualifiers
noptr-abstract-declaratoropt [constant-expressionopt ]attribute-specifier-seqopt
(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-expressionopt ]attribute-specifier-seqopt
...
It is possible to identify uniquely the location in the abstract-declarator where the identifier would appear
if the construction were a declarator in a declaration. 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]
§ 8.1 178
c
ISO/IEC N????
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 ]
2A type can also be named (often more easily) by using a typedef (7.1.3).
8.2 Ambiguity resolution [dcl.ambig.res]
1The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in 6.8
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 6.8, the resolution is to consider any construct
that could possibly be a declaration a declaration. [ Note: A declaration can be explicitly disambiguated by
a nonfunction-style cast, by an =to indicate initialization or by removing the redundant parentheses around
the parameter name. — 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 z = int(a); // object declaration
}
— end example ]
2The ambiguity arising from the similarity between a function-style cast and a type-id can occur in different
contexts. The ambiguity appears as a choice between a function-style cast expression and a declaration of a
type. The resolution is that any construct that could possibly be a type-id in its syntactic context shall be
considered a type-id.
3[Example:
#include <cstddef>
char* p;
void* operator new(std::size_t, int);
void foo() {
const int x = 63;
new (int(*p)) int; // new-placement expression
new (int(*[x])); // new type-id
}
4For another example,
template <class T>
struct S {
T* p;
};
S<int()> x; // type-id
S<int(1)> y; // expression (ill-formed)
5For another example,
void foo() {
sizeof(int(1)); // expression
§ 8.2 179
c
ISO/IEC N????
sizeof(int()); // type-id (ill-formed)
}
6For another example,
void foo() {
(int(1)); // expression
(int())1; // type-id (ill-formed)
}
— end example ]
7Another ambiguity arises in a parameter-declaration-clause of a function declaration, or in a type-id that
is the operand of a sizeof or typeid operator, 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 1to 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 ]
8.3 Meaning of declarators [dcl.meaning]
1A list of declarators appears after an optional (Clause 7)decl-specifier-seq (7.1). Each 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 (12.1,12.3,12.4,13.5)
and for the declaration of template specializations or partial specializations (14.7). 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 (7.3.1)) or to a specialization thereof; the member shall not merely have been introduced by
ausing-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.
2Astatic,thread_local,extern,register,mutable,friend,inline,virtual, or typedef specifier ap-
plies directly to each declarator-id in an init-declarator-list; the type specified for each declarator-id depends
on both the decl-specifier-seq and its declarator.
3Thus, a declaration of a particular identifier has the form
T D
where Tis of the form attribute-specifier-seqopt decl-specifier-seq and Dis a declarator. Following is a
recursive procedure for determining the type specified for the contained declarator-id by such a declaration.
§ 8.3 180
c
ISO/IEC N????
4First, the decl-specifier-seq determines a type. In a declaration
T D
the decl-specifier-seq Tdetermines the type T. [ Example: in the declaration
int unsigned i;
the type specifiers int unsigned determine the type “unsigned int” (7.1.6.2). — end example ]
5In a declaration attribute-specifier-seqopt T D where Dis an unadorned identifier the type of this identifier is
T.
6In a declaration T D where Dhas 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.
8.3.1 Pointers [dcl.ptr]
1In a declaration T D where Dhas the form
*attribute-specifier-seqopt cv-qualifier-seqopt 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 Dis “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 (7.6.1) appertains to
the pointer and not to the object pointed to. There shall be no pointers to arrays of runtime bound.
2[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 ppoint to ci ...
// ... because of previous error
*p = 5; // clobber ci
§ 8.3.1 181
c
ISO/IEC N????
— end example ]
3See also 5.17 and 8.5.
4[Note: There are no pointers to references; see 8.3.2. Since the address of a bit-field (9.6) cannot be taken,
a pointer can never point to a bit-field. — end note ]
8.3.2 References [dcl.ref]
1In a declaration T D where Dhas either of the forms
&attribute-specifier-seqopt D1
&& attribute-specifier-seqopt 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 Dis “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 (7.1.3,14.1) or decltype-specificer (7.1.6.2), 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.
2A 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.
3[Example:
void f(double& a) { a += 3.14; }
// ...
double d = 0;
f(d);
declares ato be a reference parameter of fso 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 7to the fourth element
of the array v. For another example,
struct link {
link* next;
};
link* first;
void h(link*& p) { // pis a reference to pointer
p->next = first;
first = p;
p = 0;
}
void k() {
link* q = new link;
h(q);
}
§ 8.3.2 182
c
ISO/IEC N????
declares pto be a reference to a pointer to link so h(q) will leave qwith the value zero. See also 8.5.3.
— end example ]
4It is unspecified whether or not a reference requires storage (3.7).
5There shall be no references to references, no references to arrays of runtime bound, no arrays of references,
and no pointers to references. The declaration of a reference shall contain an initializer (8.5.3) except when
the declaration contains an explicit extern specifier (7.1.1), is a class member (9.2) declaration within a
class definition, or is the declaration of a parameter or a return type (8.3.5); see 3.1. 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 9.6, a
reference cannot be bound directly to a bit-field. — end note ]
6If a typedef (7.1.3), a type template-parameter (14.3.1), or a decltype-specifier (7.1.6.2) 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.
[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 ]
8.3.3 Pointers to members [dcl.mptr]
1In a declaration T D where Dhas the form
nested-name-specifier *attribute-specifier-seqopt cv-qualifier-seqopt 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 Dis “derived-declarator-type-list cv-qualifier-
seq pointer to member of class nested-name-specifier of type T. The optional attribute-specifier-seq (7.6.1)
appertains to the pointer-to-member.
2[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 Xof type int, a pointer to a member of
Xof type void(int), a pointer to a member of Xof type double and a pointer to a member of Yof type
char respectively. The declaration of pmd is well-formed even though Xhas no members of type double.
§ 8.3.3 183
c
ISO/IEC N????
Similarly, the declaration of pmc is well-formed even though Yis an incomplete type. pmi and pmf can be
used like this:
X obj;
// ...
obj.*pmi = 7; // assign 7to an integer
// member of obj
(obj.*pmf)(7); // call a function member of obj
// with the argument 7
— end example ]
3A pointer to member shall not point to a static member of a class (9.4), a member with reference type, or
cv void.
[Note: See also 5.3 and 5.5. 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 ]
8.3.4 Arrays [dcl.array]
1In a declaration T D where Dhas the form
D1 [ expressionopt ]attribute-specifier-seqopt
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type
of the identifier of Dis an array type; if the type of the identifier of Dcontains the auto type-specifier, the
program is ill-formed. Tis called the array element type; this type shall not be a reference type, the (possibly
cv-qualified) type void, a function type, an array of unknown or runtime bound, or an abstract class type.
Except as noted below, if the expression is omitted, the type of the identifier of Dis “derived-declarator-type-
list array of unknown bound of T. If the expression is present, it is implicitly converted to std::size_t.
The expression is erroneous if:
— its value before converting to std::size_t or, in the case of an expression of class type, before
application of the second standard conversion (13.3.3.1.2) is less than or equal to zero;
its value is such that the size of the allocated object would exceed the implementation-defined limit
(Annex B);
the initializer of the object is a braced-init-list whose number of (top-level) initializer-clauses exceeds
the number of elements to initialize; or
the object is initialized with a string literal and there are more initializers than there are array elements.
If the expression, after converting to std::size_t, is a core constant expression and the expression is
erroneous, the program is ill-formed.
If the expression, after converting to std::size_t, is a core constant expression whose value is N, the
type of the identifier of Dis “derived-declarator-type-list array of N T.
Otherwise, the type of the identifier of Dis “derived-declarator-type-list array of runtime bound of T” and
the value of the expression designates the number of elements Nin the array. If the expression is erroneous,
an exception of a type that would match a handler (15.3) of type std::bad_array_length (18.6.2.2) is
thrown.
An object of array type contains a contiguously allocated non-empty set of Nsubobjects of type T. 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 3.9. Any type of the form “cv-qualifier-seq array of N T” is adjusted to “array
of Ncv-qualifier-seq T”, and similarly for “array of unknown bound of T” and “array of runtime 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 int
typedef const AA CAA; // type is “array of 2 array of 3 const int
§ 8.3.4 184
c
ISO/IEC N????
void f(unsigned int n) {
int a[n]; // type of ais “array of runtime bound of int
}
— end example ] [ Note: An “array of Ncv-qualifier-seq T” has cv-qualified type; see 3.9.3.— end note ]
2An 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.
3When several “array of” specifications are adjacent, a multidimensional array is created. 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 (8.3.5). An array bound may also be omitted when the declarator is
followed by an initializer (8.5). In this case the bound is calculated from the number of initial elements (say,
N) supplied (8.5.1), and the type of the identifier of Dis “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.
4An array of runtime bound shall only be used as the type of a local object with automatic storage duration.
If the size of the array exceeds the size of the memory available for objects with automatic storage duration,
the behavior is undefined.100 It is unspecified whether a global allocation function (3.7.4) is invoked to
obtain storage for the array. If it is invoked, the corresponding global deallocation function is invoked to
release the storage after the lifetime of the array has ended.101
5[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 3×5×7. 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 ]
6[Note: conversions affecting expressions of array type are described in 4.2. Objects of array types cannot
be modified, see 3.10.— end note ]
7[Note: Except where it has been declared for a class (13.5.5), the subscript operator [] is interpreted in such
a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an
100) Implementations that detect this case are encouraged to throw an exception that would match a handler (15.3) of type
std::bad_array_length (18.6.2.2).
101) Alternatively, an implementation could allocate such an array on the usual stack or obtain storage via malloc (20.8.13).
§ 8.3.4 185
c
ISO/IEC N????
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.
8A consistent rule is followed for multidimensional arrays. If Eis an n-dimensional array of rank i×j×. . .×k,
then Eappearing in an expression that is subject to the array-to-pointer conversion (4.2) is converted to a
pointer to an (n1)-dimensional array with rank j×. . . ×k. If the *operator, either explicitly or implicitly
as a result of subscripting, is applied to this pointer, the result is the pointed-to (n1)-dimensional array,
which itself is immediately converted into a pointer.
9[Example: consider
int x[3][5];
Here xis a 3×5array of integers. When xappears 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),xis
first converted to a pointer as described; then x+i is converted to the type of x, which involves multiplying
iby 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 ]
10 [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 ]
8.3.5 Functions [dcl.fct]
1In a declaration T D where Dhas the form
D1 ( parameter-declaration-clause )cv-qualifier-seqopt
ref-qualifieropt exception-specificationopt attribute-specifier-seqopt
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 Dis “derived-declarator-type-list function of (parameter-declaration-clause )cv-
qualifier-seqopt ref-qualifieropt returning T. The optional attribute-specifier-seq appertains to the function type.
2In a declaration T D where Dhas the form
D1 ( parameter-declaration-clause )cv-qualifier-seqopt
ref-qualifieropt exception-specificationopt attribute-specifier-seqopt trailing-return-type
and the type of the contained declarator-id in the declaration T D1 is “derived-declarator-type-list T”,
Tshall be the single type-specifier auto. The type of the declarator-id in Dis “derived-declarator-type-list
function of (parameter-declaration-clause)cv-qualifier-seqopt ref-qualifieropt returning trailing-return-type.
The optional attribute-specifier-seq appertains to the function type.
3A type of either form is a function type.102
parameter-declaration-clause:
parameter-declaration-listopt ...opt
parameter-declaration-list ,...
parameter-declaration-list:
parameter-declaration
parameter-declaration-list ,parameter-declaration
parameter-declaration:
attribute-specifier-seqopt decl-specifier-seq declarator
attribute-specifier-seqopt decl-specifier-seq declarator =initializer-clause
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt =initializer-clause
The optional attribute-specifier-seq in a parameter-declaration appertains to the parameter.
4The 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 5.2.2.— end note ] If the parameter-declaration-clause is empty, the function takes
102) As indicated by syntax, cv-qualifiers are a significant component in function return types.
§ 8.3.5 186
c
ISO/IEC N????
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 (14.5.3), 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 5.2.2 and 18.10). — end note ]
5A single name can be used for several different functions in a single scope; this is function overloading
(Clause 13). 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 “function returning T” is
adjusted to be “pointer to T” or “pointer to function returning T,” respectively. 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 ]
6Acv-qualifier-seq or a ref-qualifier shall only be part of:
the function type for a non-static member function,
the function type to which a pointer to member refers,
the top-level function type of a function typedef declaration or alias-declaration,
the type-id in the default argument of a type-parameter (14.1), or
the type-id of a template-argument for a type-parameter (14.2).
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, and the cv-qualifier-seq, but not
the default arguments (8.3.6) or the exception specification (15.4), 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 ]
7[Example: the declaration
int fseek(FILE*, long, int);
§ 8.3.5 187
c
ISO/IEC N????
declares a function taking three arguments of the specified types, and returning int (7.1.6). — end
example ]
8If the type of a parameter includes a type of the form “array of runtime bound of T”, “pointer to array
of unknown bound of T”, or “reference to array of unknown bound of T”, the program is ill-formed.103
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.
9Types 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 class type (possibly cv-qualified) unless the function is
deleted (8.4.3) or the definition is nested within the member-specification for that class (including definitions
in nested classes defined within the class).
10 A typedef of function type may be used to declare a function but shall not be used to define a function (8.4).
[Example:
typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // ill-formed
void fv() { } // OK: definition of fv
— end example ] A typedef of a function type whose declarator includes a cv-qualifier-seq shall be used
only to declare the function type for a non-static member function, to declare the function type to which a
pointer to member refers, or to declare the top-level function type of another function typedef declaration.
[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 ]
11 An identifier can optionally be provided as a parameter name; if present in a function definition (8.4), it
names a parameter (sometimes called “formal argument”). [ 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 (3.3.4). — end note ]
12 [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 ftaking 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
103) This excludes parameters of type “ptr-arr-seq T2” where T2 is “pointer to array of unknown bound of T” and where ptr-
arr-seq means any sequence of “pointer to” and “array of” derived declarator types. This exclusion applies to the parameters
of the function, and if a parameter is a pointer to function or pointer to member function then to its parameters also, etc.
§ 8.3.5 188
c
ISO/IEC N????
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);
Atrailing-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 ]
13 Adeclarator-id or abstract-declarator containing an ellipsis shall only be used in a parameter-declaration.
Such a parameter-declaration is a parameter pack (14.5.3). When it is part of a parameter-declaration-clause,
the parameter pack is a function parameter pack (14.5.3). [ Note: Otherwise, the parameter-declaration is
part of a template-parameter-list and the parameter pack is a template parameter pack; see 14.1.— end
note ] A function parameter pack is a pack expansion (14.5.3). [ 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 ]
14 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.104
8.3.6 Default arguments [dcl.fct.default]
1If 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.
2[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:
104) 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).
§ 8.3.6 189
c
ISO/IEC N????
point(1,2); point(1); point();
The last two calls are equivalent to point(1,4) and point(3,4), respectively. — end example ]
3A default argument shall be specified only in the parameter-declaration-clause of a function declaration or
in a template-parameter (14.1); 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.105
4For 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 3.2. 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.
5The 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 (8.5). 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 14.7.1. [ Example: in the following code, gwill 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;
{
105) This means that default arguments cannot appear, for example, in declarations of pointers to functions, references to
functions, or typedef declarations.
§ 8.3.6 190
c
ISO/IEC N????
int a = 3;
g(); // g(f(::a))
}
}
— end example ] [ Note: In member function declarations, names in default arguments are looked up as
described in 3.4.1. Access checking applies to names in default arguments as described in Clause 11.— end
note ]
6Except 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. 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 ]
7Local variables shall not be used in a default argument. [ Example:
void f() {
int i;
extern void g(int x = i); //error
// ...
}
— end example ]
8The keyword this shall not be used in a default argument of a member function. [ Example:
class A {
void f(A* p = this) { } // error
};
— end example ]
9Default arguments are evaluated each time the function is called. The order of evaluation of function
arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument,
even if they are not evaluated. 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 Ifound
int h(int a, int b = sizeof(a)); // error, parameter aused
// in default argument
— end example ] Similarly, a non-static member shall not be used in a default argument, even if it is not
evaluated, unless it appears as the id-expression of a class member access expression (5.2.5) or unless it is
used to form a pointer to member (5.3.1). [ 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.
§ 8.3.6 191
c
ISO/IEC N????
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 9.— 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 (7.3.3), 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.
10 A virtual function call (10.3) 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 ]
8.4 Function definitions [dcl.fct.def]
8.4.1 In general [dcl.fct.def.general]
1Function definitions have the form
function-definition:
attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
function-body:
ctor-initializeropt compound-statement
function-try-block
= default ;
= delete ;
§ 8.4.1 192
c
ISO/IEC N????
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. A
virt-specifier-seq can be part of a function-definition only if it is a member-declaration (9.2).
2The declarator in a function-definition shall have the form
D1 ( parameter-declaration-clause )cv-qualifier-seqopt
ref-qualifieropt exception-specificationopt attribute-specifier-seqopt trailing-return-typeopt
as described in 8.3.5. A function shall be defined only in namespace or class scope.
3[Example: a simple example of a complete function definition is
int max(int a, int b, int c) {
intm=(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 ]
4Actor-initializer is used only in a constructor; see 12.1 and 12.6.
5Acv-qualifier-seq or a ref-qualifier (or both) can be part of a non-static member function declaration,
non-static member function definition, or pointer to member function only (8.3.5); see 9.3.2.
6[Note: Unused parameters need not be named. For example,
void print(int a, int) {
std::printf("a = %d\n",a);
}
— end note ]
7In the function-body, a function-local predefined variable denotes a block-scope object of static storage du-
ration that is implicitly defined (see 3.3.3).
8The 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.106
[Example:
struct S {
S() : s(__func__) { } // OK
const char* s;
};
void f(const char* s = __func__); // error: __func__ is undeclared
— end example ]
8.4.2 Explicitly-defaulted functions [dcl.fct.def.default]
1A function definition of the form:
attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt = 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 Tis the name of the member function’s class) as if it had been implicitly declared,
and
106) Implementations are permitted to provide additional predefined variables with names that are reserved to the implemen-
tation (17.6.4.3.2). If a predefined variable is not odr-used (3.2), its string value need not be present in the program image.
§ 8.4.2 193
c
ISO/IEC N????
not have default arguments.
2An explicitly-defaulted function may be declared constexpr only if it would have been implicitly declared as
constexpr, and may have an explicit exception-specification only if it is compatible (15.4) with the exception-
specification on the implicit declaration. If a function is explicitly defaulted on its first declaration,
it is implicitly considered to be constexpr if the implicit declaration would be, and,
it is implicitly considered to have the same exception-specification as if it had been implicitly de-
clared (15.4).
3[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() throw(int) = default; // ill-formed: exception specification does not match
private:
int i;
S(S&); // OK: private copy constructor
};
S::S(S&) = default; // OK: defines copy constructor
— end example ]
4Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions,
and the implementation shall provide implicit definitions for them (12.1 12.4,12.8), 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 ]
5[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 ]
8.4.3 Deleted definitions [dcl.fct.def.delete]
1A function definition of the form:
attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt = delete ;
is called a deleted definition. A function with a deleted definition is also called a deleted function.
§ 8.4.3 194
c
ISO/IEC N????
2A 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. — end note ]
3[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 ]
4A deleted function is implicitly inline. [ Note: The one-definition rule (3.2) 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. [ Example:
struct sometype {
sometype();
};
sometype::sometype() = delete; // ill-formed; not first declaration
— end example ]
8.5 Initializers [dcl.init]
1A 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 8.5 applies also to initializa-
tions specified by other syntactic contexts, such as the initialization of function parameters with argument
expressions (5.2.2) or the initialization of return values (6.6.3).
initializer:
brace-or-equal-initializer
(expression-list )
§ 8.5 195
c
ISO/IEC N????
brace-or-equal-initializer:
=initializer-clause
braced-init-list
initializer-clause:
assignment-expression
braced-init-list
initializer-list:
initializer-clause ...opt
initializer-list ,initializer-clause ...opt
braced-init-list:
{initializer-list ,opt }
{ }
2Except for objects declared with the constexpr specifier, for which see 7.1.5, 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 ]
3[Note: Default arguments are more restricted; see 8.3.6.
4The order of initialization of variables with static storage duration is described in 3.6 and 6.7.— end note ]
5A declaration of a block-scope variable with external or internal linkage that has an initializer is ill-formed.
6To zero-initialize an object or reference of type Tmeans:
if Tis a scalar type (3.9), the object is initialized to the value obtained by converting the integer literal
0(zero) to T;107
if Tis a (possibly cv-qualified) non-union class type, each non-static data member and each base-class
subobject is zero-initialized and padding is initialized to zero bits;
if Tis 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 Tis an array type, each element is zero-initialized;
if Tis a reference type, no initialization is performed.
7To default-initialize an object of type Tmeans:
if Tis a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for Tis called (and
the initialization is ill-formed if Thas no default constructor or overload resolution (13.3) results in an
ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
if Tis an array type, each element is default-initialized;
otherwise, no initialization is performed.
If a program calls for the default initialization of an object of a const-qualified type T,Tshall be a class
type with a user-provided default constructor.
8To value-initialize an object of type Tmeans:
— if Tis a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a
default constructor that is user-provided or deleted, then the object is default-initialized;
107) As specified in 4.10, converting an integer literal whose value is 0to a pointer type results in a null pointer value.
§ 8.5 196
c
ISO/IEC N????
if Tis 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
Thas a non-trivial default constructor, the object is default-initialized;
if Tis an array type, then each element is value-initialized;
otherwise, the object is zero-initialized.
An object that is value-initialized is deemed to be constructed and thus subject to provisions of this
International Standard applying to “constructed” objects, objects “for which the constructor has completed,”
etc., even if no constructor is invoked for the object’s initialization.
9A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.
10 [Note: Every object of static storage duration is zero-initialized at program startup before any other initial-
ization takes place. In some cases, additional initialization is done later. — end note ]
11 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 (5.3.4,5.2.3,12.6.2). — end
note ]
12 If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an
object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or
thread storage duration are zero-initialized, see 3.6.2.— end note ]
13 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 ]
14 The form of initialization (using parentheses or =) is generally insignificant, but does matter when the
initializer or the entity being initialized has a class type; see below. If the entity being initialized does not
have class type, the expression-list in a parenthesized initializer shall be a single expression.
15 The initialization that occurs in the form
Tx=a;
as well as in argument passing, function return, throwing an exception (15.1), handling an exception
(15.3), and aggregate member initialization (8.5.1) is called copy-initialization. [ Note: Copy-initialization
may invoke a move (12.8). — end note ]
16 The initialization that occurs in the forms
T x(a);
T x{a};
as well as in new expressions (5.3.4), static_cast expressions (5.2.9), functional notation type conver-
sions (5.2.3), and base and member initializers (12.6.2) is called direct-initialization.
17 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.
§ 8.5 197
c
ISO/IEC N????
If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized (8.5.4).
If the destination type is a reference type, see 8.5.3.
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 8.5.2.
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 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 (13.3.1.3), and the best
one is chosen through overload resolution (13.3). 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 13.3.1.4, and the best one is
chosen through overload resolution (13.3). 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 initializes a temporary of the cv-unqualified
version of the destination type. The temporary is a prvalue. The result of the call (which is the
temporary for the constructor case) is then used to direct-initialize, according to the rules above,
the object that is the destination of the copy-initialization. In certain cases, an implementation
is permitted to eliminate the copying inherent in this direct-initialization by constructing the
intermediate result directly into the object being initialized; see 12.2,12.8.
Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered.
The applicable conversion functions are enumerated (13.3.1.5), and the best one is chosen through
overload resolution (13.3). 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 ini-
tializer expression. Standard conversions (Clause 4) will be used, if necessary, to convert the initializer
expression to the cv-unqualified version of the destination type; no user-defined conversions are con-
sidered. If the conversion cannot be done, the initialization is ill-formed. [ 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 ]
18 An initializer-clause followed by an ellipsis is a pack expansion (14.5.3).
§ 8.5 198
c
ISO/IEC N????
8.5.1 Aggregates [dcl.init.aggr]
1An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or
protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
2When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list
are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each
member is copy-initialized from the corresponding initializer-clause. If the initializer-clause is an expression
and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed. [ Note:
If an initializer-clause is itself an initializer list, the member is list-initialized, which will result in a recursive
application of the rules in this section if the member 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. — end example ]
3An aggregate that is a class can also be initialized with a single expression not enclosed in braces, as described
in 8.5.
4An array of unknown size initialized with a brace-enclosed initializer-list containing ninitializer-clauses,
where nshall be greater than zero, is defined as having nelements (8.3.4). [ Example:
int x[] = { 1, 3, 5 };
declares and initializes xas 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.108
5Static data members and anonymous bit-fields are not considered members of the class for purposes of
aggregate initialization. [ 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 anonymous bit-field before it. — end example ]
6For types other than arrays of runtime bound (8.3.4), an initializer-list is ill-formed if the number of
initializer-clauses exceeds the number of members or elements to initialize. [ Example:
char cv[4] = { ’a’, ’s’, ’d’, ’f’, 0 }; // error
is ill-formed. — end example ]
7If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member
not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal-
initializer, from an empty initializer list (8.5.4). [ Example:
struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
108) The syntax provides for empty initializer-lists, but nonetheless C++ does not have zero length arrays.
§ 8.5.1 199
c
ISO/IEC N????
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; };
Xa[]={1,2,3,4,5,6};
Xb[2]={{1,2,3},{4,5,6}};
aand bhave the same value — end example ]
8If an aggregate class Ccontains a subaggregate member mthat has no members for purposes of aggregate
initialization, the initializer-clause for mshall not be omitted from an initializer-list for an object of type C
unless the initializer-clauses for all members of Cfollowing mare 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 ]
9If an incomplete or empty initializer-list leaves a member of reference type uninitialized, the program is
ill-formed.
10 When initializing a multi-dimensional array, the initializer-clauses initialize the elements with the last (right-
most) index of the array varying the fastest (8.3.4). [ 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 ]
11 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 members of a subaggregate; it is
erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a sub-
aggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to
initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next
member of the aggregate of which the current subaggregate is a member. [ 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
§ 8.5.1 200
c
ISO/IEC N????
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 ybegins 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 ]
12 All implicit type conversions (Clause 4) are considered when initializing the aggregate member with an
assignment-expression. If the assignment-expression can initialize a member, the member is initialized.
Otherwise, if the member is itself a subaggregate, brace elision is assumed and the assignment-expression
is considered for the initialization of the first member of the subaggregate. [ Note: As specified above,
brace elision cannot apply to subaggregates with no members for purposes of aggregate initialization; 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;
Bb={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 ]
13 [Note: An aggregate array or an aggregate class may contain members of a class type with a user-provided
constructor (12.1). Initialization of these aggregate objects is described in 12.6.1.— end note ]
14 [Note: Whether the initialization of aggregates with static storage duration is static or dynamic is specified
in 3.6.2 and 6.7.— end note ]
15 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; };
ua={1};
ub=a;
uc=1; // error
u d = { 0, "asdf" }; // error
u e = { "asdf" }; // error
— end example ]
16 [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 ]
8.5.2 Character arrays [dcl.init.string]
1An array of narrow character type (3.9.1), char16_t array, char32_t array, or wchar_t array can be ini-
tialized 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 (2.14.5). Successive characters of
the value of the string literal initialize the elements of the array. [ Example:
char msg[] = "Syntax error on line %s\n";
§ 8.5.2 201
c
ISO/IEC 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 ]
2[Note: There cannot be more initializers than there are array elements; see 8.3.4. [ Example:
char cv[4] = "asdf"; // error
is ill-formed since there is no space for the implied trailing ’\0’.— end example ]— end note ]
3If there are fewer initializers than there are array elements, each element not explicitly initialized shall be
zero-initialized (8.5).
8.5.3 References [dcl.init.ref]
1A variable declared to be a T& or T&&, that is, “reference to type T” (8.3.2), shall be initialized by an object,
or function, of type Tor by an object that can be converted into a T. [ Example:
int g(int);
void f() {
int i;
int& r = i; // rrefers to i
r = 1; // the value of ibecomes 1
int* p = &r; // ppoints to i
int& rr = r; // rr refers to what rrefers 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 ]
2A reference cannot be changed to refer to another object after initialization. Note that initialization of a
reference is treated very differently from assignment to it. Argument passing (5.2.2) and function value
return (6.6.3) are initializations.
3The initializer can be omitted for a reference only in a parameter declaration (8.3.5), in the declaration of
a function return type, in the declaration of a class member within its class definition (9.2), and where the
extern specifier is explicitly used. [ Example:
int& r1; // error: initializer missing
extern int& r2; // OK
— end example ]
4Given 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 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 11) or ambiguous (10.2) base class of T2.
5A 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
implicitly converted to an lvalue of type “cv3 T3,” where “cv1 T1” is reference-compatible with cv3
T3109 (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6)
and choosing the best one through overload resolution (13.3)),
109) This requires a conversion function (12.3.2) returning a reference type.
§ 8.5.3 202
c
ISO/IEC N????
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 (4.1), array-to-pointer (4.2), and function-to-pointer
(4.3) 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 Asubobject in b
const A& rca = b; // rca refers to Asubobject 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 xvalue (but not a bit-field), class prvalue, array prvalue 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
implicitly converted to an xvalue, class prvalue, or function lvalue of type “cv3 T3”, where
cv1 T1” is reference-compatible with “cv3 T3”,
then the reference is bound to the value of the initializer expression in the first case and to
the result of the conversion in the second case (or, in either case, to an appropriate base class
subobject). In the second case, if the reference is an rvalue reference and the second standard con-
version sequence of the user-defined conversion sequence includes an lvalue-to-rvalue conversion,
the program is ill-formed.
[Example:
struct A { };
struct B : A { } b;
extern B f();
const A& rca2 = f(); // bound to the Asubobject of the Brvalue.
A&& rra = f(); // same as above
struct X {
operator B();
operator int&();
} x;
const A& r = x; // bound to the Asubobject 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
§ 8.5.3 203
c
ISO/IEC N????
int&& rri2 = X(); // error: lvalue-to-rvalue conversion applied to the
// result of operator int&
— end example ]
Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression
using the rules for a non-reference copy-initialization (8.5). The reference is then bound to the
temporary. If T1 is reference-related to T2,cv1 shall be the same cv-qualification as, or greater
cv-qualification than, cv2. If T1 is reference-related to T2 and the reference is an rvalue reference,
the initializer expression shall not be an lvalue. [ Example:
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: type qualifiers dropped
double d2 = 1.0;
double&& rrd2 = d2; // error: copying 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., creating and initializing a temporary from the initializer expression), the
reference is said to bind directly to the initializer expression.
6[Note: 12.2 describes the lifetime of temporaries bound to references. — end note ]
8.5.4 List-initialization [dcl.init.list]
1List-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
as the initializer in a variable definition (8.5)
as the initializer in a new expression (5.3.4)
in a return statement (6.6.3)
as a for-range-initializer (6.5)
as a function argument (5.2.2)
as a subscript (5.2.1)
as an argument to a constructor invocation (8.5,5.2.3)
as an initializer for a non-static data member (9.2)
in a mem-initializer (12.6.2)
on the right-hand side of an assignment (5.17)
[Example:
§ 8.5.4 204
c
ISO/IEC N????
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 ]
2A 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 (8.3.6). [ Note: Initializer-list
constructors are favored over other constructors in list-initialization (13.3.1.7). — 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 (7.1.6.4) — the program
is ill-formed.
3List-initialization of an object or reference of type Tis defined as follows:
If Tis an aggregate, aggregate initialization is performed (8.5.1).
[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 Tis a class type with a default constructor, the
object is value-initialized.
Otherwise, if Tis a specialization of std::initializer_list<E>, a prvalue initializer_list object
is constructed as described below and used to initialize the object according to the rules for initialization
of an object from a class of the same type (8.5).
Otherwise, if Tis a class type, constructors are considered. The applicable constructors are enumerated
and the best one is chosen through overload resolution (13.3,13.3.1.7). 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
Ss2={1,2,3}; // invoke #2
Ss3={}; // invoke #3
§ 8.5.4 205
c
ISO/IEC N????
— 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 the initializer list has a single element of type Eand either Tis not a reference type or
its referenced type is reference-related to E, the object or reference is initialized from that element; 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 Tis a reference type, a prvalue temporary of the type referenced by Tis copy-list-initialized
or direct-list-initialized, depending on the kind of initialization for the reference, and the reference is
bound to that temporary. [ 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:
§ 8.5.4 206
c
ISO/IEC N????
int** pp {}; // initialized to null pointer
— end example ]
Otherwise, the program is ill-formed.
[Example:
struct A { int i; int j; };
Aa1{1,2}; // aggregate initialization
A a2 { 1.2 }; // error: narrowing
struct B {
B(std::initializer_list<int>);
};
Bb1{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 ]
4Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack
expansions (14.5.3), 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 ]
5An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation
allocated a temporary array of Nelements of type const E, where Nis 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 11) 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 ]
6The array has the same lifetime as any other temporary object (12.2), 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:
§ 8.5.4 207
c
ISO/IEC N????
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 } {} // creates an Awith 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 a constructor’s
ctor-initializer, so the array persists only until the constructor exits, and so any use of the elements of i4
after the constructor exits produces undefined behavior. — 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 ]
7Anarrowing 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);
§ 8.5.4 208
c
ISO/IEC N????
int a[] =
{ 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level
— end example ]
§ 8.5.4 209
c
ISO/IEC N????
9 Classes [class]
1A class is a type. Its name becomes a class-name (9.1) within its scope.
class-name:
identifier
simple-template-id
Class-specifiers and elaborated-type-specifiers (7.1.6.3) are used to make class-names. An object of a class
consists of a (possibly empty) sequence of members and base class objects.
class-specifier:
class-head {member-specificationopt }
class-head:
class-key attribute-specifier-seqopt class-head-name class-virt-specifieropt base-clauseopt
class-key attribute-specifier-seqopt base-clauseopt
class-head-name:
nested-name-specifieropt class-name
class-virt-specifier:
final
class-key:
class
struct
union
Aclass-specifier whose class-head omits the class-head-name defines an unnamed class. [ Note: An
unnamed class thus can’t be final.— end note ]
2Aclass-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.
3If a class is marked with the class-virt-specifier final and it appears as a base-type-specifier in a base-clause
(Clause 10), 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 ]
4Complete objects and member subobjects of class type shall have nonzero size.110 [Note: Class objects can
be assigned, passed as arguments to functions, and returned by functions (except objects of classes for which
110) Base class subobjects are not so constrained.
Classes 210
c
ISO/IEC N????
copying or moving has been restricted; see 12.8). Other plausible operators, such as equality comparison,
can be defined by the user; see 13.5.— end note ]
5Aunion is a class defined with the class-key union; it holds only one data member at a time (9.5). [ Note:
Aggregates of class type are described in 8.5.1.— end note ]
6Atrivially copyable class is a class that:
has no non-trivial copy constructors (12.8),
has no non-trivial move constructors (12.8),
has no non-trivial copy assignment operators (13.5.3,12.8),
has no non-trivial move assignment operators (13.5.3,12.8), and
has a trivial destructor (12.4).
Atrivial class is a class that has a default constructor (12.1), has no non-trivial default constructors,
and is trivially copyable.
[Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base
classes. — end note ]
7Astandard-layout class is a class that:
has no non-static data members of type non-standard-layout class (or array of such types) or reference,
has no virtual functions (10.3) and no virtual base classes (10.1),
has the same access control (Clause 11) for all non-static data members,
has no non-standard-layout base classes,
either has no non-static data members in the most derived class and at most one base class with
non-static data members, or has no base classes with non-static data members, and
has no base classes of the same type as the first non-static data member.111
8Astandard-layout struct is a standard-layout class defined with the class-key struct or the class-key class.
Astandard-layout union is a standard-layout class defined with the class-key union.
9[Note: Standard-layout classes are useful for communicating with code written in other programming lan-
guages. Their layout is specified in 9.2.— end note ]
10 APOD struct112 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;
111) 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 (5.10).
112) The acronym POD stands for “plain old data”.
Classes 211
c
ISO/IEC N????
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 ]
11 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 (7.3.1) of that namespace (i.e., not merely inherited or introduced by
ausing-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.
9.1 Class names [class.name]
1A 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: Yassigned to X
a1 = a3; // error: int assigned to X
are type mismatches, and that
int f(X);
int f(Y);
declare an overloaded (Clause 13) 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 Stwice. — end example ]
2A 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 (3.3). 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 (3.4.4). [ Example:
struct stat {
// ...
};
§ 9.1 212
c
ISO/IEC N????
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 11.3, operator functions in 13.5.— end example ]— end note ]
3[Note: An elaborated-type-specifier (7.1.6.3) 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 ]
4[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;
§ 9.1 213
c
ISO/IEC N????
first specifies Ato 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 ]
5Atypedef-name (7.1.3) 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.
9.2 Class members [class.mem]
member-specification:
member-declaration member-specificationopt
access-specifier :member-specificationopt
member-declaration:
attribute-specifier-seqopt decl-specifier-seqopt member-declarator-listopt ;
function-definition ;opt
using-declaration
static_assert-declaration
template-declaration
alias-declaration
member-declarator-list:
member-declarator
member-declarator-list ,member-declarator
member-declarator:
declarator virt-specifier-seqopt pure-specifieropt
declarator brace-or-equal-initializeropt
identifieropt attribute-specifier-seqopt :constant-expression
virt-specifier-seq:
virt-specifier
virt-specifier-seq virt-specifier
virt-specifier:
override
final
pure-specifier:
= 0
1The member-specification in a class definition declares the full set of members of the class; no member can
be added elsewhere. Members of a class are data members, member functions (9.3), nested types, and
enumerators. Data members and member functions are static or non-static; see 9.4. Nested types are
classes (9.1,9.7) and enumerations (7.2) defined in the class, and arbitrary types declared as members by
use of a typedef declaration (7.1.3). The enumerators of an unscoped enumeration (7.2) defined in the class
are members of the class. Except when used to declare friends (11.3) or to introduce the name of a member
of a base class into a derived class (7.3.3), member-declarations declare members of the class, and each such
member-declaration shall declare at least one member name of the class. A member shall not be declared
twice in the member-specification, except that a nested class or member class template can be declared and
then later defined, and except that an enumeration can be introduced with an opaque-enum-declaration and
later redeclared with an enum-specifier.
2A class is considered a completely-defined object type (3.9) (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, using-declarations introducing inheriting constructors (12.9), exception-specifications, and
brace-or-equal-initializers for non-static data members (including such things in nested classes). Otherwise
it is regarded as incomplete within its own class member-specification.
3[Note: A single name can denote several function members provided their types are sufficiently different
(Clause 13). — end note ]
4Abrace-or-equal-initializer shall appear only in the declaration of a data member. (For static data members,
see 9.4.2; for non-static data members, see 12.6.2).
§ 9.2 214
c
ISO/IEC N????
5A member shall not be declared with the extern or register storage-class-specifier. Within a class definition,
a member shall not be declared with the thread_local storage-class-specifier unless also declared static.
6The 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 (11.3). A pure-specifier shall be used only in the declaration of a virtual function (10.3).
7The 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.
8Avirt-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 (10.3).
9A non-static (9.4) data member shall not have incomplete type or type “array of runtime bound”. [ Note:
In particular, a class Cshall not contain a non-static member of class C, but it can contain a pointer or
reference to an object of class C.— end note ]
10 [Note: See 5.1 for restrictions on the use of non-static data members and non-static member functions.
— end note ]
11 [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 ]
12 [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 sto 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 ]
13 Nonstatic data members of a (non-union) class with the same access control (Clause 11) 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 11). 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 (10.3) and virtual base classes (10.1).
14 If Tis 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 (12.1)— end note ];
every member of class Tthat is itself a type;
every enumerator of every member of class Tthat is an unscoped enumerated type; and
every member of every anonymous union that is a member of class T.
15 In addition, if class Thas a user-declared constructor (12.1), every non-static data member of class Tshall
have a name different from T.
§ 9.2 215
c
ISO/IEC N????
16 Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static
data members and corresponding non-static data members (in declaration order) have layout-compatible
types (3.9).
17 Two standard-layout union (Clause 9) types 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 (3.9).
18 If a standard-layout union contains two or more standard-layout structs that share a common initial sequence,
and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted
to inspect the common initial part of any of them. Two standard-layout structs share a common initial
sequence if corresponding members have layout-compatible types and either neither member is a bit-field or
both are bit-fields with the same width for a sequence of one or more initial members.
19 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 ]
9.3 Member functions [class.mfct]
1Functions declared in the definition of a class, excluding those declared with a friend specifier (11.3), are
called member functions of that class. A member function may be declared static in which case it is a static
member function of its class (9.4); otherwise it is a non-static member function of its class (9.3.1,9.3.2).
2A member function may be defined (8.4) in its class definition, in which case it is an inline member func-
tion (7.1.2), 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 (14.7) appearing outside of the class definition, a member function shall not
be redeclared.
3An 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. [ Note: Member functions of a class in namespace scope have external linkage.
Member functions of a local class (9.8) have no linkage. See 3.5.— end note ]
4There shall be at most one definition of a non-inline member function in a program; no diagnostic is required.
There may be more than one inline member function definition in a program. See 3.2 and 7.1.2.
5If 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 (8.3.6) or in the
member function body) is looked up as described in 3.4.— end note ] [ Example:
struct X {
typedef int T;
static T count;
void f(T);
};
void X::f(T t = count) { }
The member function fof class Xis defined in global scope; the notation X::f specifies that the function
fis a member of class Xand in the scope of class X. In the function definition, the parameter type Trefers to
the typedef member Tdeclared in class Xand the default argument count refers to the static data member
count declared in class X.— end example ]
6Astatic local variable in a member function always refers to the same object, whether or not the member
function is inline.
7Previously declared member functions may be mentioned in friend declarations.
§ 9.3 216
c
ISO/IEC N????
8Member functions of a local class shall be defined inline in their class definition, if they are defined at all.
9[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 8.3.5. For example,
typedef void fv(void);
typedef void fvc(void) const;
struct S {
fv memfunc1; // equivalent to: void memfunc1(void);
void memfunc2();
fvc memfunc3; // equivalent to: void memfunc3(void) const;
};
fv S::* pmfv1 = &S::memfunc1;
fv S::* pmfv2 = &S::memfunc2;
fvc S::* pmfv3 = &S::memfunc3;
Also see 14.3.— end note ]
9.3.1 Nonstatic member functions [class.mfct.non-static]
1Anon-static member function may be called for an object of its class type, or for an object of a class derived
(Clause 10) from its class type, using the class member access syntax (5.2.5,13.3.1.1). A non-static member
function may also be called directly using the function call syntax (5.2.2,13.3.1.1) from within the body of
a member function of its class or of a class derived from its class.
2If a non-static member function of a class Xis called for an object that is not of type X, or of a type derived
from X, the behavior is undefined.
3When an id-expression (5.1) that is not part of a class member access syntax (5.2.5) and not used to form
a pointer to member (5.3.1) is used in a member of class Xin a context where this can be used (5.1.1),
if name lookup (3.4) 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 Cis Xor a base class of X, the id-expression is
transformed into a class member access expression (5.2.5) using (*this) (9.3.2) as the postfix-expression to
the left of the .operator. [ Note: If Cis not Xor a base class of X, the class member access expression is
ill-formed. — end note ] Similarly during name lookup, when an unqualified-id (5.1) used in the definition of
a member function for class Xresolves to a static member, an enumerator or a nested type of class Xor of a
base class of X, the unqualified-id is transformed into a qualified-id (5.1) in which the nested-name-specifier
names the class of the member function. [ 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);
§ 9.3.1 217
c
ISO/IEC N????
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.113 — end
example ]
4A non-static member function may be declared const,volatile, or const volatile. These cv-qualifiers
affect the type of the this pointer (9.3.2). They also affect the function type (8.3.5) of the member function;
a member function declared const is a const member function, a member function declared volatile is
avolatile 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 ]
5A non-static member function may be declared with a ref-qualifier (8.3.5); see 13.3.1.
6A non-static member function may be declared virtual (10.3) or pure virtual (10.4).
9.3.2 The this pointer [class.this]
1In the body of a non-static (9.3) 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 Xis 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 ]
2Similarly, volatile semantics (7.1.6.1) apply in volatile member functions when accessing the object and
its non-static data members.
3Acv-qualified member function can be called on an object-expression (5.2.5) 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
}
113) See, for example, <cstring> (21.8).
§ 9.3.2 218
c
ISO/IEC N????
The call y.g() is ill-formed because yis const and s::g() is a non-const member function, that is,
s::g() is less-qualified than the object-expression y.— end example ]
4Constructors (12.1) and destructors (12.4) 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 (12.1)
and (12.4). — end note ]
9.4 Static members [class.static]
1A data or function member of a class may be declared static in a class definition, in which case it is a
static member of the class.
2Astatic member sof class Xmay be referred to using the qualified-id expression X::s; it is not necessary to
use the class member access syntax (5.2.5) 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 ]
3Astatic member may be referred to directly in the scope of its class or in the scope of a class derived
(Clause 10) 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 ]
4If an unqualified-id (5.1) is used in the definition of a static member following the member’s declarator-id,
and name lookup (3.4.1) 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
aqualified-id expression in which the nested-name-specifier names the class scope from which the member
is referenced. [ Note: See 5.1 for restrictions on the use of non-static data members and non-static member
functions. — end note ]
5Static members obey the usual class member access rules (Clause 11). 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 ]
9.4.1 Static member functions [class.static.mfct]
1[Note: The rules described in 9.3 apply to static member functions. — end note ]
2[Note: Astatic member function does not have a this pointer (9.3.2). — end note ] A static member
function shall not be virtual. There shall not be a static and a non-static member function with the
§ 9.4.1 219
c
ISO/IEC N????
same name and the same parameter types (13.1). A static member function shall not be declared const,
volatile, or const volatile.
9.4.2 Static data members [class.static.data]
1Astatic 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.
2The declaration of a static data member in its class definition is not a definition and may be of an incomplete
type other than cv-qualified void. The definition for a static data member 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 (3.3.7). [ 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 ]
3If a non-volatile 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 (5.19). A static data member of literal type can be declared in the
class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer
in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both
these cases, the member may appear in constant expressions. — end note ] The member shall still be defined
in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not
contain an initializer.
4[Note: There shall be exactly one definition of a static data member that is odr-used (3.2) 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.
5Static data members of a class in namespace scope have external linkage (3.5). A local class shall not have
static data members.
6Static data members are initialized and destroyed exactly like non-local variables (3.6.2,3.6.3).
7Astatic data member shall not be mutable (7.1.1).
9.5 Unions [class.union]
1In a union, at most one of the non-static data members 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 (9.2), and if an object of this standard-layout union type
contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of
standard-layout struct members; see 9.2.— 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. All non-static data members of a union object have the same address.
§ 9.5 220
c
ISO/IEC N????
2A union can have member functions (including constructors and destructors), but not virtual (10.3) 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. At most one non-static data member of a union may
have a brace-or-equal-initializer. [ Note: If any non-static data member of a union has a non-trivial default
constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move
assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be
user-provided or it will be implicitly deleted (8.4.3) for the union. — end note ]
3[Example: Consider the following union:
union U {
int i;
float f;
std::string s;
};
Since std::string (21.3) declares non-trivial versions of all of the special member functions, Uwill
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 ]
4[Note: In general, one must use explicit destructor calls and placement new operators to change the active
member of a union. — end note ] [ Example: Consider an object uof a union type Uhaving non-static data
members mof type Mand nof type N. If Mhas a non-trivial destructor and Nhas a non-trivial constructor
(for instance, if they declare or inherit virtual functions), the active member of ucan be safely switched
from mto nusing the destructor and placement new operator as follows:
u.m.~M();
new (&u.n) N;
— end example ]
5A union of the form
union { member-specification } ;
is called an anonymous union; it defines an unnamed object of unnamed type. The member-specification
of an anonymous union shall only define non-static data members. [ Note: Nested types 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 aand pare used like ordinary (nonmember) variables, but since they are union members they have
the same address. — end example ]
6Anonymous 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 11). An
anonymous union shall not have function members.
7A 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
§ 9.5 221
c
ISO/IEC N????
}
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 (8.5.1). — end note ]
8Aunion-like class is a union or a class that has an anonymous union as a direct member. A union-like
class Xhas a set of variant members. If Xis a union its variant members are the non-static data members;
otherwise, its variant members are the non-static data members of all anonymous unions that are members
of X.
9.6 Bit-fields [class.bit]
1Amember-declarator of the form
identifieropt attribute-specifier-seqopt :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 (3.9) 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 (3.9) 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 ]
2A 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.
3A bit-field shall not be a static member. A bit-field shall have integral or enumeration type (3.9.1). 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 (8.5.3). [ 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. See 8.5.3.— end note ]
4If 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 (7.2), 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 ]
9.7 Nested class declarations [class.nest]
1A 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.
§ 9.7 222
c
ISO/IEC N????
[Note: See 5.1 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 ]
2Member 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 ]
3If class Xis defined in a namespace scope, a nested class Ymay be declared in class Xand later defined in the
definition of class Xor 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 ]
§ 9.7 223
c
ISO/IEC N????
4Like a member function, a friend function (11.3) 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 (9.4), but it has no
special access rights to members of an enclosing class.
9.8 Local class declarations [class.local]
1A 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 (3.2) 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 ]
2An enclosing function has no special access to members of the local class; it obeys the usual access rules
(Clause 11). Member functions of a local class shall be defined within their class definition, if they are
defined at all.
3If class Xis a local class a nested class Ymay be declared in class Xand later defined in the definition of
class Xor be later defined in the same scope as the definition of class X. A class nested within a local class
is a local class.
4A local class shall not have static data members.
9.9 Nested type names [class.nested.type]
1Type 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 ]
§ 9.9 224
c
ISO/IEC N????
10 Derived classes [class.derived]
1A list of base classes can be specified in a class definition using the notation:
base-clause:
:base-specifier-list
base-specifier-list:
base-specifier ...opt
base-specifier-list ,base-specifier ...opt
base-specifier:
attribute-specifier-seqopt base-type-specifier
attribute-specifier-seqopt virtual access-specifieropt base-type-specifier
attribute-specifier-seqopt access-specifier virtualopt base-type-specifier
class-or-decltype:
nested-name-specifieropt class-name
decltype-specifier
base-type-specifier:
class-or-decltype
access-specifier:
private
protected
public
The optional attribute-specifier-seq appertains to the base-specifier.
2The type denoted by a base-type-specifier shall be a class type that is not an incompletely defined class
(Clause 9); this class is called a direct base class for the class being defined. During the lookup for a base
class name, non-type names are ignored (3.3.10). If the name found is not a class-name, the program is
ill-formed. A class Bis a base class of a class Dif it is a direct base class of Dor 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 11 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. The base class members are said to
be inherited by the derived class. 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 (10.2). [ Note: The scope
resolution operator :: (5.1) 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 11.2. A pointer to a derived class can be implicitly converted to a pointer to
an accessible unambiguous base class (4.10). An lvalue of a derived class type can be bound to a reference
to an accessible unambiguous base class (8.5.3). — end note ]
3The 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 {
Derived classes 225
c
ISO/IEC N????
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 ]
4Abase-specifier followed by an ellipsis is a pack expansion (14.5.3).
5The order in which the base class subobjects are allocated in the most derived object (1.8) 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. A DAG of subobjects is often referred to as a “subobject
lattice.
Base
Derived1
Derived2
Figure 2 — Directed acyclic graph
6The arrows need not have a physical representation in memory. — end note ]
7[Note: Initialization of objects representing base classes can be specified in constructors; see 12.6.2.— end
note ]
8[Note: A base class subobject might have a layout (3.7) different from the layout of a most derived object
of the same type. A base class subobject might have a polymorphic behavior (12.7) different from the
polymorphic behavior of a most derived object of the same type. A base class subobject may be of zero size
(Clause 9); 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 (5.10). — end note ]
10.1 Multiple base classes [class.mi]
1A 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 ]
2[Note: The order of derivation is not significant except as specified by the semantics of initialization by
constructor (12.6.2), cleanup (12.4), and storage layout (9.2,11.1). — end note ]
3A 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
§ 10.1 226
c
ISO/IEC N????
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 ]
4A 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 (1.8) 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. [ Example:
for an object of class type C, each distinct occurrence of a (non-virtual) base class Lin the class lattice of
Ccorresponds one-to-one with a distinct Lsubobject within the object of type C. Given the class Cdefined
above, an object of class Cwill have two subobjects of class Las shown below.
L L
A B
C
Figure 3 — Non-virtual base
5In 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 Lsubobject:
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 ambigu-
ity (10.2).
6For another example,
class V { /... /};
class A : virtual public V { /... /};
class B : virtual public V { /... /};
class C : public A, public B { /... /};
for an object cof class type C, a single subobject of type Vis shared by every base subobject of cthat has
avirtual base class of type V. Given the class Cdefined above, an object of class Cwill have one subobject
of class V, as shown below.
7A 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 Bin the class lattice of AA correspond to a
single Bsubobject 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 Bsubobject within the object of type AA.
§ 10.1 227
c
ISO/IEC N????
V
A B
C
Figure 4 — Virtual base
B B
AA
X Y Z
Figure 5 — Virtual and non-virtual base
Given the class AA defined above, class AA has two subobjects of class B:Z’s Band the virtual Bshared by X
and Y, as shown below.
— end example ]
10.2 Member name lookup [class.member.lookup]
1Member name lookup determines the meaning of a name (id-expression) in a class scope (3.3.7). 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 (3.4, Clause 11).
2The following steps define the result of name lookup for a member name fin a class scope C.
3The lookup set for fin C, called S(f, C), 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 members they
designate, and type declarations (including injected-class-names) are replaced by the types they designate.
S(f, C)is calculated as follows:
4If Ccontains a declaration of the name f, the declaration set contains every declaration of fdeclared in
Cthat satisfies the requirements of the language construct in which the lookup occurs. [ Note: Looking
up a name in an elaborated-type-specifier (3.4.4) or base-specifier (Clause 10), for instance, ignores all non-
type declarations, while looking up a name in a nested-name-specifier (3.4.3) ignores function, variable, and
enumerator declarations. As another example, looking up a name in a using-declaration (7.3.3) 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.
5Otherwise (i.e., Cdoes not contain a declaration of for the resulting declaration set is empty), S(f, C)is
initially empty. If Chas base classes, calculate the lookup set for fin each direct base class subobject Bi,
and merge each such lookup set S(f, Bi)in turn into S(f, C).
6The following steps define the result of merging lookup set S(f, Bi)into the intermediate S(f, C):
§ 10.2 228
c
ISO/IEC N????
If each of the subobject members of S(f, Bi)is a base class subobject of at least one of the subobject
members of S(f, C), or if S(f, Bi)is empty, S(f, C)is unchanged and the merge is complete. Con-
versely, if each of the subobject members of S(f, C)is a base class subobject of at least one of the
subobject members of S(f, Bi), or if S(f, C)is empty, the new S(f, C)is a copy of S(f, Bi).
Otherwise, if the declaration sets of S(f, Bi)and S(f, C)differ, the merge is ambiguous: the new
S(f, C)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 S(f, C)is a lookup set with the shared set of declarations and the union of the
subobject sets.
7The result of name lookup for fin Cis the declaration set of S(f, C). 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, { Ain C,Bin 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
}
S(x, F )is unambiguous because the Aand Bbase subobjects of Dare also base subobjects of E, so S(x, D)
is discarded in the first merge step. — end example ]
8If the name of an overloaded function is unambiguously found, overloading resolution (13.3) 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 ]
9[Note: A static member, a nested type or an enumerator defined in a base class Tcan 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 };
§ 10.2 229
c
ISO/IEC N????
};
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 ]
10 [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(); };
W V W
B C
D
Figure 6 — Name lookup
11 [Note: The names declared in Vand the left-hand instance of Ware hidden by those in B, but the names
declared in the right-hand instance of Ware not hidden at all. — end note ]
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 ]
12 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 { };
§ 10.2 230
c
ISO/IEC N????
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 Aor B’s A?
V* pv = &d; // OK: only one Vsubobject
}
— end example ]
13 [Note: Even if the result of name lookup is unambiguous, use of a name found in multiple subobjects might
still be ambiguous (4.11,5.2.5,11.2). — 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 ]
10.3 Virtual functions [class.virtual]
1Virtual functions support dynamic binding and object-oriented programming. A class that declares or
inherits a virtual function is called a polymorphic class.
2If 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 (8.3.5), 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 overrides114 Base::vf. For convenience we say that any virtual function overrides itself.
A virtual member function C::vf of a class object Sis a final overrider unless the most derived class (1.8)
of which Sis 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:
114) A function with the same name but a different parameter list (Clause 13) 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 11) is not considered in determining overriding.
§ 10.3 231
c
ISO/IEC N????
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 Band Csubobjects, respectively
— end example ]
3[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 Dhides 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 ]
4If a virtual function fin some class Bis marked with the virt-specifier final and in a class Dderived from
Ba 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 ]
5If 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:
§ 10.3 232
c
ISO/IEC N????
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 ]
6Even though destructors are not inherited, a destructor in a derived class overrides a base class destructor
declared virtual; see 12.4 and 12.5.
7The 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
classes115
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.
8If 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 (5.2.2). [ 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();
};
115) Multi-level pointers to classes or references to multi-level pointers to classes are not allowed.
§ 10.3 233
c
ISO/IEC N????
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 ]
9[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) (5.2.2). — end note ]
10 [Note: The virtual specifier implies membership, so a virtual function cannot be a nonmember (7.1.2)
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 ]
11 A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no
diagnostic is required (3.2).
12 [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 { // Dhas two separate Asubobjects
};
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 Dabove there are two occurrences of class Aand 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.
13 The following example shows a function that does not have a unique final overrider:
§ 10.3 234
c
ISO/IEC N????
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.
14 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 ]
15 Explicit qualification with the scope operator (5.1) 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 ]
16 A function with a deleted definition (8.4) 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.
10.4 Abstract classes [class.abstract]
1The 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.
2An 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 (9.2) in the function declaration in the class definition. A
§ 10.4 235
c
ISO/IEC N????
pure virtual function need be defined only if called with, or as if with (12.4), the qualified-id syntax (5.1).
[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 ]
3An 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 ]
4A 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 nonabstract and a definition of circle::draw() must be provided. — end exam-
ple ]
5[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 ]
6Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a
virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed)
from such a constructor (or destructor) is undefined.
§ 10.4 236
c
ISO/IEC N????
11 Member access control [class.access]
1A 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 11.4).
public; that is, its name can be used anywhere without access restriction.
2A 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.116
3Members 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 ]
4Access 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 (11.3) and using-
declarations (7.3.3). — 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 ]
5It 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.
6All access controls in Clause 11 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
116) Access permissions are thus transitive and cumulative to nested and local classes.
Member access control 237
c
ISO/IEC N????
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 { };
7Here, all the uses of A::I are well-formed because A::f,A::x, and A::Q are members of class Aand gand
Rare 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 Dis derived from A, so checking of base-specifiers
must be deferred until the entire base-specifier-list has been seen. — end example ]
8The names in a default argument (8.3.6) 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 14.7.1.
9The names in a default template-argument (14.1) 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 ]
11.1 Access specifiers [class.access.spec]
1Member declarations can be labeled by an access-specifier (Clause 10):
access-specifier :member-specificationopt
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
§ 11.1 238
c
ISO/IEC N????
public:
int b; // X::b is public
int c; // X::c is public
};
— end example ]
2Any 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 ]
3[Note: The effect of access control on the order of allocation of data members is described in 9.2.— end
note ]
4When 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 ]
5[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 Ais inaccessible
::A* q; // OK
};
— end example ]
11.2 Accessibility of base classes and base class members [class.access.base]
1If a class is declared to be a base class (Clause 10) 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 class117.
117) As specified previously in Clause 11, 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.
§ 11.2 239
c
ISO/IEC N????
2In 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 { /... /}; // Bprivate by default
struct D4 : public B { /... /};
struct D5 : private B { /... /};
struct D6 : B { /... /}; // Bpublic by default
class D7 : protected B { /... /};
struct D8 : protected B { /... /};
Here Bis 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 ]
3[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 (4.10) and explicit casts (5.4), 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: Bis a private base class
::B* bp2 = (::B*)this; // OK with cast
bp2->mi = 3; // OK: access through a pointer to B.
}
— end note ]
4A base class Bof Nis accessible at R, if
an invented public member of Bwould be a public member of N, or
Roccurs in a member or friend of class N, and an invented public member of Bwould be a private or
protected member of N, or
Roccurs in a member or friend of a class Pderived from N, and an invented public member of Bwould
be a private or protected member of P, or
there exists a class Ssuch that Bis a base class of Saccessible at Rand Sis a base class of Naccessible
at R.
[Example:
§ 11.2 240
c
ISO/IEC N????
class B {
public:
int m;
};
class S: private B {
friend class N;
};
class N: private S {
void f() {
B* p = this; // OK because class Ssatisfies the fourth condition
// above: Bis a base class of Naccessible in f() because
// Bis an accessible base class of Sand Sis an accessible
// base class of N.
}
};
— end example ]
5If a base class is accessible, one can implicitly convert a pointer to a derived class to a pointer to that base
class (4.10,4.11). [ Note: It follows that members and friends of a class Xcan 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 (5.2.5) 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 mis accessible at the point Rwhen named in class Nif
mas a member of Nis public, or
mas a member of Nis private, and Roccurs in a member or friend of class N, or
mas a member of Nis protected, and Roccurs in a member or friend of class N, or in a member or
friend of a class Pderived from N, where mas a member of Pis public, private, or protected, or
there exists a base class Bof Nthat is accessible at R, and mis accessible at Rwhen 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 fhas access to iin A
}
— end example ]
6If 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.
§ 11.2 241
c
ISO/IEC N????
[Note: This requirement is in addition to the requirement that the member be accessible as named. — end
note ]
11.3 Friends [class.friend]
1A 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 ]
2Declaring 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, Yis a friend of X
};
class Z {
int v[X::a]; // error: X::a is private
};
§ 11.3 242
c
ISO/IEC N????
— 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 ]
3Afriend 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: Afriend declaration may be the declaration in a template-declaration (Clause 14,14.5.4). — 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 Din 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 ]
4A function first declared in a friend declaration has external linkage (3.5). Otherwise, the function retains
its previous linkage (7.1.1).
5When 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 Xcan 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 ]
6A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8),
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 ]
§ 11.3 243
c
ISO/IEC N????
7Such a function is implicitly 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 (3.4.1).
8No storage-class-specifier shall appear in the decl-specifier-seq of a friend declaration.
9A 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 (9.2) portion of the class member-specification.
10 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: Cis not a friend of A
// despite being a friend of a friend
}
};
class D : public B {
void f(A* p) {
p->a++; // error: Dis not a friend of A
// despite being derived from a friend
}
};
— end example ]
11 If a friend declaration appears in a local class (9.8) 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 Xis 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 Zis found
}
§ 11.3 244
c
ISO/IEC N????
— end example ]
11.4 Protected member access [class.protected]
1An additional access check beyond those described earlier in Clause 11 is applied when a non-static data
member or non-static member function is a protected member of its naming class (11.2)118 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 (5.3.1), the nested-name-specifier shall denote Cor a
class derived from C. All other accesses involve a (possibly implicit) object expression (5.2.5). In this case,
the class of the object expression shall be Cor 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; // OK (because refers to static member)
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 jrefers 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
}
118) This additional check does not apply to other members, e.g., static data members or enumerator member constants.
§ 11.4 245
c
ISO/IEC N????
— end example ]
11.5 Access to virtual functions [class.access.virt]
1The access rules (Clause 11) 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 ]
2Access 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 (Din the example above) is in general not known.
11.6 Multiple access [class.paths]
1If 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
};
2Since W::f() is available to C::f() along the public path through B, access is allowed. — end example ]
11.7 Nested classes [class.access.nest]
1A 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 11)
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
§ 11.7 246
c
ISO/IEC N????
}
};
int g(I* p) {
return p->y; // error: I::y is private
}
};
— end example ]
§ 11.7 247
c
ISO/IEC N????
12 Special member functions [special]
1The default constructor (12.1), copy constructor and copy assignment operator (12.8), move constructor
and move assignment operator (12.8), and destructor (12.4) 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 (3.2).
See 12.1,12.4 and 12.8.— 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.
2Programs 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 ]
3[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 ]
4Special member functions obey the usual access rules (Clause 11). [ Example: declaring a constructor
protected ensures that only derived classes and friends can create objects using it. — end example ]
12.1 Constructors [class.ctor]
1Constructors do not have names. A declaration of a constructor uses a function declarator (8.3.5) of the
form
ptr-declarator (parameter-declaration-clause )exception-specificationopt attribute-specifier-seqopt
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and op-
tional surrounding parentheses, and the id-expression has one of the following forms:
in a member-declaration that belongs to the member-specification of a class but is not a friend dec-
laration (11.3), the id-expression is the injected-class-name (Clause 9) of the immediately-enclosing
class;
in a member-declaration that belongs to the member-specification of a class template but is not a friend
declaration, the id-expression is a class-name that names the current instantiation (14.6.2.1) of the
immediately-enclosing class template; or
in a declaration at namespace scope or in a friend declaration, the id-expression is a qualified-id that
names a constructor (3.4.3.1).
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
};
§ 12.1 248
c
ISO/IEC N????
S::S() { } // defines the constructor
— end example ]
2A 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 (5.2.3)
will cause a constructor to be called to initialize an object. [ Note: For initialization of objects of class type
see 12.6.— end note ]
3A constructor can be invoked for a const,volatile or const volatile object. const and volatile seman-
tics (7.1.6.1) are not applied on an object under construction. They come into effect when the constructor
for the most derived object (1.8) ends.
4Adefault constructor for a class Xis a constructor of class Xthat can be called without an argument. If
there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared
as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A
defaulted default constructor for class Xis defined as deleted if:
Xis a union-like class that has a variant member with a non-trivial default constructor,
any non-static data member with no brace-or-equal-initializer 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,
Xis a union and all of its variant members are of const-qualified type (or array thereof),
Xis a non-union class and all members of any anonymous union member are of const-qualified type
(or array thereof),
any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class
type M(or array thereof) and either Mhas no default constructor or overload resolution (13.3) as applied
to M’s default constructor results in an ambiguity or in a function that is deleted or inaccessible from
the defaulted default constructor, or
any direct or virtual base class or non-static data member 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 (10.3) and no virtual base classes (10.1), and
no non-static data member of its class has a brace-or-equal-initializer, 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.
5A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-
used (3.2) to create an object of its class type (1.8) 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 (12.6.2) 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 (7.1.5),
the implicitly-defined default constructor is constexpr. Before the defaulted default constructor for a
§ 12.1 249
c
ISO/IEC N????
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 (15.4). An explicitly-defaulted definition might have an implicit exception-
specification, see 8.4.— end note ]
6Default constructors are called implicitly to create class objects of static, thread, or automatic storage
duration (3.7.1,3.7.2,3.7.3) defined without an initializer (8.5), are called to create class objects of dynamic
storage duration (3.7.4) created by a new-expression in which the new-initializer is omitted (5.3.4), or
are called when the explicit type conversion syntax (5.2.3) is used. A program is ill-formed if the default
constructor for an object is implicitly used and the constructor is not accessible (Clause 11).
7[Note: 12.6.2 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 ]
8Areturn statement in the body of a constructor shall not specify a return value. The address of a constructor
shall not be taken.
9A functional notation type conversion (5.2.3) 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 ]
10 An object created in this way is unnamed. [ Note: 12.2 describes the lifetime of temporary objects. — end
note ] [ Note: Explicit constructor calls do not yield lvalues, see 3.10.— end note ]
11 [Note: some language constructs have special semantics when used during construction; see 12.6.2 and 12.7.
— end note ]
12 During the construction of a const 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’;
}
— end example ]
12.2 Temporary objects [class.temporary]
1Temporaries of class type are created in various contexts: binding a reference to a prvalue (8.5.3), returning
a prvalue (6.6.3), a conversion that creates a prvalue (4.1,5.2.9,5.2.11,5.4), throwing an exception (15.1),
entering a handler (15.3), and in some initializations (8.5). [ Note: The lifetime of exception objects is
described in 15.1.— end note ] Even when the creation of the temporary object is unevaluated (Clause 5)
or otherwise avoided (12.8), all the semantic restrictions shall be respected as if the temporary object had
been created and later destroyed. [ Note: This includes accessibility (11) and whether it is deleted, for
§ 12.2 250
c
ISO/IEC N????
the constructor selected and for the destructor. However, in the special case of a function call used as the
operand of a decltype-specifier (5.2.2), no temporary is introduced, so the foregoing does not apply to the
prvalue of any such function call. — end note ]
2[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);
}
An implementation might use a temporary in which to construct X(2) before passing it to f() using X’s
copy constructor; alternatively, X(2) might be constructed in the space used to hold the argument. Likewise,
an implementation might use a temporary in which to construct Y(3) before passing it to g() using Y’s
move constructor; alternatively, Y(3) might be constructed in the space used to hold the argument. Also,
a temporary might be used to hold the result of f(X(2)) before copying it to busing X’s copy constructor;
alternatively, f()’s result might be constructed in b. Likewise, a temporary might be used to hold the result
of g(Y(3)) before moving it to cusing Y’s move constructor; alternatively, g()’s result might be constructed
in c. On the other hand, the expression a=f(a) requires a temporary for the result of f(a), which is then
assigned to a.— end example ]
3When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1,
12.8), 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 (12.4). Temporary objects are destroyed as the last step
in evaluating the full-expression (1.9) 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.
4There are two 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. 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.
5The second context is when a reference is bound to a temporary.119 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:
119) The same rules apply to initialization of an initializer_list object (8.5.4) with its underlying temporary array
§ 12.2 251
c
ISO/IEC N????
A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the
constructor exits.
A temporary bound to a reference parameter in a function call (5.2.2) 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 (6.6.3) 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 (5.3.4) 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 (3.7.1,3.7.2,3.7.3); 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 ]
12.3 Conversions [class.conv]
1Type 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 4), for
initialization (8.5), and for explicit type conversions (5.4,5.2.9).
§ 12.3 252
c
ISO/IEC N????
2User-defined conversions are applied only where they are unambiguous (10.2,12.3.2). Conversions obey the
access control rules (Clause 11). Access control is applied after ambiguity resolution (3.4).
3[Note: See 13.3 for a discussion of the use of conversions in function calls as well as examples below. — end
note ]
4At 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 ]
5User-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 (13.3.3) 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 ]
12.3.1 Conversion by constructor [class.conv.ctor]
1A constructor declared without the function-specifier explicit specifies a conversion from the types of its
parameters 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) {
Xa=1; // a = X(1)
X b = "Jessie"; // b = X("Jessie",0)
a = 2; // a = X(2)
§ 12.3.1 253
c
ISO/IEC N????
f(3); // f(X(3))
f({1, 2}); // f(X(1,2))
}
— end example ]
2An explicit constructor constructs objects just like non-explicit constructors, but does so only where the
direct-initialization syntax (8.5) or where casts (5.2.9,5.4) are explicitly used. A default constructor
may be an explicit constructor; such a constructor will be used to perform default-initialization or value-
initialization (8.5). [ Example:
struct Z {
explicit Z();
explicit Z(int);
explicit Z(int, int);
};
Z a; // OK: default-initialization performed
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
Za6={3,4}; // error: no implicit conversion
— end example ]
3A non-explicit copy/move constructor (12.8) is a converting constructor. An implicitly-declared copy/move
constructor is not an explicit constructor; it may be called for implicit type conversions.
12.3.2 Conversion functions [class.conv.fct]
1A member function of a class Xhaving no parameters with a name of the form
conversion-function-id:
operator conversion-type-id
conversion-type-id:
type-specifier-seq conversion-declaratoropt
conversion-declarator:
ptr-operator conversion-declaratoropt
specifies a conversion from Xto the type specified by the conversion-type-id. Such functions are called
conversion functions. No return type can be specified. If a conversion function is a member function, the
type of the conversion function (8.3.5) 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.120
[Example:
struct X {
operator int();
};
void f(X a) {
int i = int(a);
120) These conversions are considered as standard conversions for the purposes of overload resolution (13.3.3.1,13.3.3.1.4) and
therefore initialization (8.5) and explicit casts (5.2.9). A conversion to void does not invoke any conversion function (5.2.9).
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.
§ 12.3.2 254
c
ISO/IEC N????
i = (int)a;
i = a;
}
In all three cases the value assigned will be converted by X::operator int().— end example ]
2A conversion function may be explicit (7.1.2), in which case it is only considered as a user-defined conversion
for direct-initialization (8.5). 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 ]
3The conversion-type-id shall not represent a function type nor an array type. The conversion-type-id in
aconversion-function-id is the longest possible sequence of conversion-declarators. [ 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 ]— end note ]
4Conversion functions are inherited.
5Conversion functions can be virtual.
6Conversion functions cannot be declared static.
12.4 Destructors [class.dtor]
1A declaration of a destructor uses a function declarator (8.3.5) of the form
ptr-declarator (parameter-declaration-clause )exception-specificationopt attribute-specifier-seqopt
where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and op-
tional surrounding parentheses, and the id-expression has one of the following forms:
in a member-declaration that belongs to the member-specification of a class but is not a friend declara-
tion (11.3), the id-expression is ˜class-name and the class-name is the injected-class-name (Clause 9)
of the immediately-enclosing class;
in a member-declaration that belongs to the member-specification of a class template but is not a
friend declaration, the id-expression is ˜class-name and the class-name names the current instantia-
tion (14.6.2.1) of the immediately-enclosing class template; or
in a declaration at namespace scope or in a friend declaration, the id-expression is nested-name-specifier
˜class-name and the class-name names the same class as the nested-name-specifier.
§ 12.4 255
c
ISO/IEC N????
The class-name shall not be a typedef-name. A destructor shall take no arguments (8.3.5). In a destructor
declaration, each decl-specifier of the optional decl-specifier-seq shall be friend,inline, or virtual.
2A 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 (7.1.6.1) are not applied on an object under destruction. They stop being in effect when the
destructor for the most derived object (1.8) starts.
3A declaration of a destructor that does not have an exception-specification is implicitly considered to have
the same exception-specification as an implicit declaration (15.4).
4If a class has no user-declared destructor, a destructor is implicitly declared as defaulted (8.4). An implicitly-
declared destructor is an inline public member of its class.
5A defaulted destructor for a class Xis defined as deleted if:
Xis a union-like class that has a variant member with a non-trivial destructor,
any of the non-static data members has class type M(or array thereof) and Mhas a deleted destructor
or a destructor that is inaccessible from the defaulted destructor,
any direct or virtual base class 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.
6A destructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (3.2) to
destroy an object of its class type (3.7) or when it is explicitly defaulted after its first declaration.
7Before 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.
8After executing the body of the destructor and destroying any automatic objects allocated within the body, a
destructor for class Xcalls the destructors for X’s direct non-variant non-static data members, the destructors
for X’s direct base classes and, if Xis the type of the most derived class (12.6.2), 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 12.6.2). A return
statement (6.6.3) 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 12.6).
9A destructor can be declared virtual (10.3) or pure virtual (10.4); 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.
10 [Note: some language constructs have special semantics when used during destruction; see 12.7.— end
note ]
11 Destructors are invoked implicitly
for constructed objects with static storage duration (3.7.1) at program termination (3.6.3),
§ 12.4 256
c
ISO/IEC N????
for constructed objects with thread storage duration (3.7.2) at thread exit,
for constructed objects with automatic storage duration (3.7.3) when the block in which an object is
created exits (6.7),
for constructed temporary objects when the lifetime of a temporary object ends (12.2),
for constructed objects allocated by a new-expression (5.3.4), through use of a delete-expression (5.3.5),
in several situations due to the handling of exceptions (15.3).
A program is ill-formed if an object of class type or array thereof is declared and the destructor for the
class is not accessible at the point of the declaration. Destructors can also be invoked explicitly.
12 At the point of definition of a virtual destructor (including an implicit definition (12.8)), the non-array
deallocation function is looked up in the scope of the destructor’s class (10.2), and, if no declaration is
found, the function is looked up in the global scope. If the result of this lookup is ambiguous or inaccessible,
or if the lookup selects a placement deallocation function or a function with a deleted definition (8.4), 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 (12.5). — end note ]
13 In an explicit destructor call, the destructor name appears as 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 (9.3); 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 5.3.5.— 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 opera-
tor (5.2.5) or a qualified-id (5.1); in particular, the unary-expression ˜X() in a member function is not an
explicit destructor call (5.3.1). — end note ]
14 [Note: explicit calls of destructors are rarely needed. One use of such calls is for objects placed at specific
addresses using a new-expression with the placement option. 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);
§ 12.4 257
c
ISO/IEC N????
~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 ]
15 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 (3.8). [ 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 ]
16 [Note: the notation for explicit call of a destructor can be used for any scalar type name (5.2.4). 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 ]
12.5 Free store [class.free]
1Any allocation function for a class Tis a static member (even if not explicitly declared static).
2[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 ]
3When an object is deleted with a delete-expression (5.3.5), 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 (3.7.4.2).
4If a delete-expression begins with a unary :: operator, the deallocation function’s name is looked up in
global scope. Otherwise, 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 (12.4).121 Otherwise, if the delete-expression is used to deallocate an object of
class Tor array thereof, the static and dynamic types of the object shall be identical and the deallocation
121) A similar provision is not needed for the array version of operator delete because 5.3.5 requires that in this situation,
the static type of the object to be deleted be the same as its dynamic type.
§ 12.5 258
c
ISO/IEC N????
function’s name is looked up in the scope of T. If this lookup fails to find the name, the name is looked up in
the global scope. If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a placement
deallocation function, the program is ill-formed.
5When a delete-expression is executed, the selected deallocation function shall be called with the address of
the block of storage to be reclaimed as its first argument and (if the two-parameter style is used) the size of
the block as its second argument.122
6Any deallocation function for a class Xis 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 ]
7Since 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 Dis 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];
122) If the static type of the object to be deleted is different from the dynamic type and the destructor is not virtual the size
might be incorrect, but that case is already undefined; see 5.3.5.
§ 12.5 259
c
ISO/IEC N????
delete [] dp; // uses D::operator delete[](void*, std::size_t)
B* bp = new D[i];
delete[] bp; // undefined behavior
}
— end note ]
8Access 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 ]
9[Note: If a deallocation function has no explicit exception-specification, it is treated as if it were specified
with noexcept(true) (15.4). — end note ]
12.6 Initialization [class.init]
1When 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 8.5.
2An object of class type (or array thereof) can be explicitly initialized; see 12.6.1 and 12.6.2.
3When 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 8.3.4. [ Note: Destructors for the array elements are called in reverse order of their construction. — end
note ]
12.6.1 Explicit initialization [class.expl.init]
1An 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 8.5. [ 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 (13.5.3) has no effect on initialization. — end
note ]
2An object of class type can also be initialized by a braced-init-list. List-initialization semantics apply; see 8.5
and 8.5.4. [ Example:
§ 12.6.1 260
c
ISO/IEC N????
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 8.5.1.
— end note ]
3[Note: If Tis 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 12.6 and 8.5). — end note ]
4[Note: the order in which objects with static or thread storage duration are initialized is described in 3.6.2
and 6.7.— end note ]
12.6.2 Initializing bases and members [class.base.init]
1In the definition of a constructor for a class, initializers for direct and virtual base subobjects and non-static
data members can be specified by a ctor-initializer, which has the form
ctor-initializer:
:mem-initializer-list
mem-initializer-list:
mem-initializer ...opt
mem-initializer ,mem-initializer-list ...opt
mem-initializer:
mem-initializer-id (expression-listopt )
mem-initializer-id braced-init-list
mem-initializer-id:
class-or-decltype
identifier
2In 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.
3Amem-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 ]
4If 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(); };
§ 12.6.2 261
c
ISO/IEC N????
struct B: public virtual A { };
struct C: public A, public B { C(); };
C::C(): A() { } // ill-formed: which A?
— end example ]
5Actor-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.
6Amem-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 principal constructor is the first constructor invoked
in the construction of an object (that is, not a target constructor for that object’s construction). 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 is 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 ]
7The 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 8.5
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 ] The initialization performed by each mem-initializer constitutes a full-expression. Any
expression in a mem-initializer is evaluated as part of the full-expression that performs the initialization.
Amem-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.
8In a non-delegating constructor, if a given non-static data member or base class 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) and the entity is not a virtual base class of an abstract class (10.4), then
if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized
as specified in 8.5;
otherwise, if the entity is an anonymous union or a variant member (9.5), no initialization is performed;
otherwise, the entity is default-initialized (8.5).
§ 12.6.2 262
c
ISO/IEC N????
[Note: An abstract class (10.4) 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. After the call
to a constructor for class Xhas completed, if a member of Xis neither initialized nor given a value during
execution of the compound-statement of the body of the constructor, the member has indeterminate value.
[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: Bhas no default constructor
int i; // OK: ihas indeterminate value
int j = 5; // OK: jhas the value 5
};
— end example ]
9If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initializa-
tion specified by the mem-initializer is performed, and the non-static data member’s brace-or-equal-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 ito the value of arg, and the side effects in i’s brace-or-
equal-initializer will not take place. — end example ]
10 In a non-delegating constructor, initialization proceeds in the following order:
First, and only for the constructor of the most derived class (1.8), 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 ]
11 [Example:
struct V {
V();
V(int);
§ 12.6.2 263
c
ISO/IEC N????
};
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 ]
12 Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the con-
structor 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 Xis 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 ]
13 Member functions (including virtual member functions, 10.3) can be called for an object under construction.
Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_-
cast (5.2.7). 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 result
of the operation is undefined. [ Example:
class A {
public:
A(int);
};
§ 12.6.2 264
c
ISO/IEC N????
class B : public A {
int j;
public:
int f();
B() : A(f()), // undefined: calls member function
// but base Anot 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 Cnot yet initialized
i(f()) { } // well-defined: bases are all initialized
};
— end example ]
14 [Note: 12.7 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 ]
15 Amem-initializer followed by an ellipsis is a pack expansion (14.5.3) 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 ]
12.7 Construction and destruction [class.cdtor]
1For 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
§ 12.7 265
c
ISO/IEC N????
extern X xobj;
int* p3 = &xobj.i; //OK, Xis a trivial class
X xobj;
2For another example,
struct W { int j; };
struct X : public virtual W { };
struct Y {
int* p;
X x;
Y() : p(&x.j) { // undefined, xis not yet constructed
}
};
— end example ]
3To explicitly or implicitly convert a pointer (a glvalue) referring to an object of class Xto a pointer (reference)
to a direct or indirect base class Bof X, the construction of Xand the construction of all of its direct or
indirect bases that directly or indirectly derive from Bshall 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 Dis not constructed
// D((C*)this), // defined:
// E* C* defined because E() has started
// and C* A* defined because
// Cfully constructed
X(this) { // defined: upon construction of X,
// C/B/D/A sublattice is fully constructed
}
};
— end example ]
4Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2).
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 (5.2.5) and the object expression refers to the complete
object of xor one of that object’s base class subobjects but not xor one of its base class subobjects, the
behavior is undefined. [ Example:
struct V {
virtual void f();
virtual void g();
};
§ 12.7 266
c
ISO/IEC N????
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(); // vis 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 ]
5The typeid operator (5.2.8) can be used during construction or destruction (12.6.2). When typeid is used
in a constructor (including the mem-initializer or brace-or-equal-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 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 result of typeid is undefined.
6dynamic_casts (5.2.7) can be used during construction or destruction (12.6.2). When a dynamic_cast
is used in a constructor (including the mem-initializer or brace-or-equal-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) { }
};
§ 12.7 267
c
ISO/IEC N????
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 Anot a base of B
dynamic_cast<B*>(v); // well-defined: vof type V*,Vbase of B
// results in B*
dynamic_cast<B*>(a); // undefined behavior,
// ahas type A*,Anot a base of B
}
— end example ]
12.8 Copying and moving class objects [class.copy]
1A class object can be copied or moved in two ways: by initialization (12.1,8.5), including for function argu-
ment passing (5.2.2) and for function value return (6.6.3); and by assignment (5.17). Conceptually, these two
operations are implemented by a copy/move constructor (12.1) and copy/move assignment operator (13.5.3).
2A non-template constructor for class Xis 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 (8.3.6). [ 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);
Xc=b; // calls X(const X&, int);
— end example ]
3A non-template constructor for class Xis 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 (8.3.6). [ 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&&)
Ye=d; // calls Y(const Y&)
— end example ]
4[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 ]
5[Note: If a class Xonly 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
§ 12.8 268
c
ISO/IEC N????
X(X&); // copy constructor with a nonconst parameter
};
const X cx;
X x = cx; // error: X::X(X&) cannot copy cx into x
— end example ]— end note ]
6A declaration of a constructor for a class Xis ill-formed if its first parameter is of type (optionally cv-qualified)
Xand 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 ]
7If the class definition does not explicitly declare a copy constructor, 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 (8.4). The latter case is deprecated if the class has
a user-declared copy assignment operator or a user-declared destructor. Thus, for the class definition
struct X {
X(const X&, int);
};
a copy constructor is implicitly-declared. If the user-declared constructor is later defined as
X::X(const X& x, int i =0) { /... /}
then any use of X’s copy constructor is ill-formed because of the ambiguity; no diagnostic is required.
8The implicitly-declared copy constructor for a class Xwill have the form
X::X(const X&)
if
each direct or virtual base class Bof Xhas a copy constructor whose first parameter is of type const
B& or const volatile B&, and
for all the non-static data members of Xthat are of a class type M(or array thereof), each such class
type has a copy constructor whose first parameter is of type const M& or const volatile M&.123
Otherwise, the implicitly-declared copy constructor will have the form
X::X(X&)
9If the definition of a class Xdoes not explicitly declare a move constructor, one will be implicitly declared
as defaulted if and only if
Xdoes not have a user-declared copy constructor,
123) This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue;
see C.1.9.
§ 12.8 269
c
ISO/IEC N????
Xdoes not have a user-declared copy assignment operator,
Xdoes not have a user-declared move assignment operator, and
Xdoes 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 ]
10 The implicitly-declared move constructor for class Xwill have the form
X::X(X&&)
11 An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/
move constructor for a class Xis defined as deleted (8.4.3) if Xhas:
a variant member with a non-trivial corresponding constructor and Xis a union-like class,
a non-static data member of class type M(or array thereof) that cannot be copied/moved because
overload resolution (13.3), as applied to M’s corresponding constructor, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted constructor,
a direct or virtual base class Bthat cannot be copied/moved because overload resolution (13.3), as
applied to B’s corresponding constructor, results in an ambiguity or a function that is deleted or
inaccessible from the defaulted constructor,
any direct or virtual base class or non-static data member 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 (13.3,13.4).
[Note: A deleted move constructor would otherwise interfere with initialization from an rvalue which can
use the copy constructor instead. — end note ]
12 A copy/move constructor for class Xis trivial if it is not user-provided, its declared parameter type is the
same as if it had been implicitly declared, and if
class Xhas no virtual functions (10.3) and no virtual base classes (10.1), and
class Xhas no non-static data members of volatile-qualified type, and
the constructor selected to copy/move each direct base class subobject is trivial, and
for each non-static data member of Xthat 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.
13 A copy/move constructor that is defaulted and not defined as deleted is implicitly defined if it is odr-
used (3.2) 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 (3.2,12.2). — end note ] If the implicitly-
defined constructor would satisfy the requirements of a constexpr constructor (7.1.5), the implicitly-defined
constructor is constexpr.
14 Before the defaulted copy/move constructor for a class is implicitly defined, all non-user-provided copy/move
constructors for its direct and virtual base classes and its non-static data members shall have been implicitly
defined. [ Note: An implicitly-declared copy/move constructor has an exception-specification (15.4). — end
note ]
§ 12.8 270
c
ISO/IEC N????
15 The implicitly-defined copy/move constructor for a non-union class Xperforms a memberwise copy/move
of its bases and members. [ Note: brace-or-equal-initializers of non-static data members are ignored. See
also the example in 12.6.2.— end note ] The order of initialization is the same as the order of initialization
of bases and members in a user-defined constructor (see 12.6.2). Let xbe 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 mhas 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 12.6.2).
16 The implicitly-defined copy/move constructor for a union Xcopies the object representation (3.9) of X.
17 A user-declared copy assignment operator X::operator= is a non-static non-template member function of
class Xwith exactly one parameter of type X,X&,const X&,volatile X& or const volatile X&.124 [Note:
An overloaded assignment operator must be declared to have only one parameter; see 13.5.3.— end note ]
[Note: More than one form of copy assignment operator may be declared for a class. — end note ] [ Note:
If a class Xonly 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 ]
18 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 (8.4). 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 Xwill have the form
X& X::operator=(const X&)
if
each direct base class Bof Xhas 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 Xthat 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.125
124) 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.
125) This implies that the reference parameter of the implicitly-declared copy assignment operator cannot bind to a volatile
lvalue; see C.1.9.
§ 12.8 271
c
ISO/IEC N????
Otherwise, the implicitly-declared copy assignment operator will have the form
X& X::operator=(X&)
19 A user-declared move assignment operator X::operator= is a non-static non-template member function of
class Xwith 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 13.5.3.— end note ]
[Note: More than one form of move assignment operator may be declared for a class. — end note ]
20 If the definition of a class Xdoes not explicitly declare a move assignment operator, one will be implicitly
declared as defaulted if and only if
Xdoes not have a user-declared copy constructor,
Xdoes not have a user-declared move constructor,
Xdoes not have a user-declared copy assignment operator, and
Xdoes 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 oper-
ator 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 ]
21 The implicitly-declared move assignment operator for a class Xwill have the form
X& X::operator=(X&&);
22 The implicitly-declared copy/move assignment operator for class Xhas 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.
23 A defaulted copy/move assignment operator for class Xis defined as deleted if Xhas:
a variant member with a non-trivial corresponding assignment operator and Xis 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 non-static data member of class type M(or array thereof) that cannot be copied/moved because
overload resolution (13.3), as applied to M’s corresponding assignment operator, results in an ambiguity
or a function that is deleted or inaccessible from the defaulted assignment operator, or
a direct or virtual base class Bthat cannot be copied/moved because overload resolution (13.3), as
applied to B’s corresponding assignment operator, results in an ambiguity or a function that is deleted
or inaccessible from the defaulted assignment operator.
§ 12.8 272
c
ISO/IEC N????
A defaulted move assignment operator that is defined as deleted is ignored by overload resolution (13.3,
13.4).
24 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 (13.5.3). A using-declaration (7.3.3) 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.
25 A copy/move assignment operator for class Xis trivial if it is not user-provided, its declared parameter type
is the same as if it had been implicitly declared, and if
class Xhas no virtual functions (10.3) and no virtual base classes (10.1), and
class Xhas no non-static data members of volatile-qualified type, and
the assignment operator selected to copy/move each direct base class subobject is trivial, and
for each non-static data member of Xthat 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.
26 A copy/move assignment operator for a class Xthat is defaulted and not defined as deleted is implicitly
defined when it is odr-used (3.2) (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
Xis 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 Xthat is of class type (or array thereof), the assignment operator
selected to copy/move that member is a constexpr function.
27 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 exception-
specification (15.4). — end note ]
28 The implicitly-defined copy/move assignment operator for a non-union class Xperforms memberwise copy-
/move assignment of its subobjects. The direct base classes of Xare assigned first, in the order of their
declaration in the base-specifier-list, and then the immediate non-static data members of Xare assigned, in
the order in which they were declared in the class definition. Let xbe 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 xas 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.
§ 12.8 273
c
ISO/IEC N????
It is unspecified whether subobjects representing virtual base classes are assigned more than once by the
implicitly-defined copy 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 Vis assigned twice by the implicitly-defined copy
assignment operator for C.— end example ] [ Note: This does not apply to move assignment, as a defaulted
move assignment operator is deleted if the class has virtual bases. — end note ]
29 The implicitly-defined copy assignment operator for a union Xcopies the object representation (3.9) of X.
30 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 11). [ 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 ]
31 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, and the destruction of that object
occurs at the later of the times when the two objects would have been destroyed without the optimization.126
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 or catch-clause parameter) with the same cv-
unqualified type as the function return type, the copy/move operation can be omitted by constructing
the automatic object directly into the function’s return value
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 (15.1) can be omitted by constructing the automatic object directly into the exception object
when a temporary class object that has not been bound to a reference (12.2) would be copied/moved
to a class object with the same cv-unqualified type, the copy/move operation can be omitted by
constructing the temporary object directly into the target of the omitted copy/move
when the exception-declaration of an exception handler (Clause 15) declares an object of the same type
(except for cv-qualification) as the exception object (15.1), the copy/move 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.
[Example:
class Thing {
public:
Thing();
~Thing();
Thing(const Thing&);
};
126) 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.
§ 12.8 274
c
ISO/IEC N????
Thing f() {
Thing t;
return t;
}
Thing t2 = f();
Here the criteria for elision can be combined to eliminate two calls to the copy constructor of class Thing:
the copying of the local automatic object tinto the temporary object for the return value of function f()
and the copying of that temporary object into 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
temporary object to t2 that is elided. — end example ]
32 When the criteria for elision of a copy operation are met or would be met save for the fact that the source
object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to
select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload
resolution fails, 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: Thing(Thing&&) used (or elided) to construct t2
— end example ]
12.9 Inheriting constructors [class.inhctor]
1Ausing-declaration (7.3.3) that names a constructor implicitly declares a set of inheriting constructors. The
candidate set of inherited constructors from the class Xnamed in the using-declaration consists of actual
constructors and notional constructors that result from the transformation of defaulted parameters as follows:
all non-template constructors of X, and
for each non-template constructor of Xthat has at least one parameter with a default argument, the set
of constructors that results from omitting any ellipsis parameter specification and successively omitting
parameters with a default argument from the end of the parameter-type-list, and
all constructor templates of X, and
§ 12.9 275
c
ISO/IEC N????
for each constructor template of Xthat has at least one parameter with a default argument, the set of
constructor templates that results from omitting any ellipsis parameter specification and successively
omitting parameters with a default argument from the end of the parameter-type-list.
2The constructor characteristics of a constructor or constructor template are
the template parameter list (14.1), if any,
the parameter-type-list (8.3.5),
absence or presence of explicit (12.3.1), and
absence or presence of constexpr (7.1.5).
3For each non-template constructor in the candidate set of inherited constructors other than a constructor
having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly
declared with the same constructor characteristics unless there is a user-declared constructor with the same
signature in the complete class where the using-declaration appears. Similarly, for each constructor template
in the candidate set of inherited constructors, a constructor template is implicitly declared with the same
constructor characteristics unless there is an equivalent user-declared constructor template (14.5.6.1) in
the complete class where the using-declaration appears. [ Note: Default arguments are not inherited. An
exception-specification is implied as specified in 15.4.— end note ]
4A constructor so declared has the same access as the corresponding constructor in X. It is deleted if the
corresponding constructor in Xis deleted (8.4).
5[Note: Default and copy/move constructors may be implicitly declared as specified in 12.1 and 12.8.— end
note ]
6[Example:
struct B1 {
B1(int);
};
struct B2 {
B2(int = 13, int = 42);
};
struct D1 : B1 {
using B1::B1;
};
struct D2 : B2 {
using B2::B2;
};
The candidate set of inherited constructors in D1 for B1 is
B1(const B1&)
B1(B1&&)
B1(int)
The set of constructors present in D1 is
D1(), implicitly-declared default constructor, ill-formed if odr-used
§ 12.9 276
c
ISO/IEC N????
D1(const D1&), implicitly-declared copy constructor, not inherited
D1(D1&&), implicitly-declared move constructor, not inherited
D1(int), implicitly-declared inheriting constructor
The candidate set of inherited constructors in D2 for B2 is
B2(const B2&)
B2(B2&&)
B2(int = 13, int = 42)
B2(int = 13)
B2()
The set of constructors present in D2 is
D2(), implicitly-declared default constructor, not inherited
D2(const D2&), implicitly-declared copy constructor, not inherited
D2(D2&&), implicitly-declared move constructor, not inherited
D2(int, int), implicitly-declared inheriting constructor
D2(int), implicitly-declared inheriting constructor
— end example ]
7[Note: If two using-declarations declare inheriting constructors with the same signatures, the program is
ill-formed (9.2,13.1), because an implicitly-declared constructor introduced by the first using-declaration is
not a user-declared constructor and thus does not preclude another declaration of a constructor with the
same signature by a subsequent using-declaration. [ Example:
struct B1 {
B1(int);
};
struct B2 {
B2(int);
};
struct D1 : B1, B2 {
using B1::B1;
using B2::B2;
}; // ill-formed: attempts to declare D1(int) twice
struct D2 : B1, B2 {
using B1::B1;
using B2::B2;
D2(int); // OK: user declaration supersedes both implicit declarations
};
§ 12.9 277
c
ISO/IEC N????
— end example ]— end note ]
8An inheriting constructor for a class is implicitly defined when it is odr-used (3.2) to create an object of its
class type (1.8). An implicitly-defined inheriting constructor performs the set of initializations of the class
that would be performed by a user-written inline constructor for that class with a mem-initializer-list whose
only mem-initializer has a mem-initializer-id that names the base class denoted in the nested-name-specifier
of the using-declaration and an expression-list as specified below, and where the compound-statement in
its function body is empty (12.6.2). If that user-written constructor would be ill-formed, the program is
ill-formed. Each expression in the expression-list is of the form static_cast<T&&>(p), where pis the name
of the corresponding constructor parameter and Tis the declared type of p.
9[Example:
struct B1 {
B1(int) { }
};
struct B2 {
B2(double) { }
};
struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x;
};
void test() {
D1 d(6); // OK: d.x is not initialized
D1 e; // error: D1 has no default constructor
}
struct D2 : B2 {
using B2::B2; // OK: implicitly declares D2(double)
B1 b;
};
D2 f(1.0); // error: B1 has no default constructor
template< class T >
struct D : T {
using T::T; // declares all constructors from class T
~D() { std::clog << "Destroying wrapper" << std::endl; }
};
Class template Dwraps any class and forwards all of its constructors, while writing a message to the
standard log whenever an object of class Dis destroyed. — end example ]
§ 12.9 278
c
ISO/IEC N????
13 Overloading [over]
1When 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.
2When 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 13.3. [ Example:
double abs(double);
int abs(int);
abs(1); // calls abs(int);
abs(1.0); // calls abs(double);
— end example ]
13.1 Overloadable declarations [over.load]
1Not 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 (7.3.3). 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 ]
2Certain function declarations cannot be overloaded:
Function declarations that differ only in the return type cannot be overloaded.
Member function declarations with the same name and the same parameter-type-list cannot be over-
loaded if any of them is a static member function declaration (9.4). Likewise, member function
template declarations with the same name, the same parameter-type-list, and the same template pa-
rameter 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 (13.3.1) 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 func-
tion 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 ]
§ 13.1 279
c
ISO/IEC N????
Member function declarations with the same name and the same parameter-type-list as well as mem-
ber 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 (8.3.5).
[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 ]
3[Note: As specified in 8.3.5, 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 (7.1.3). [ 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 (8.3.5). Only the second and subsequent
array dimensions are significant in parameter types (8.3.4). [ 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 ]
§ 13.1 280
c
ISO/IEC N????
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 (8.3.5). [ 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 specifica-
tion 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.127 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 ]
13.2 Declaration matching [over.dcl]
1Two function declarations of the same name refer to the same function if they are in the same scope and
have equivalent parameter declarations (13.1). 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:
127) 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.
§ 13.2 281
c
ISO/IEC N????
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 ]
2A 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 ]
3Different 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 ]
13.3 Overload resolution [over.match]
1Overload 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
§ 13.3 282
c
ISO/IEC N????
restrictions, such as the accessibility of the function, can make its use in the calling context ill-formed.
— end note ]
2Overload resolution selects the function to call in seven distinct contexts within the language:
invocation of a function named in the function call syntax (13.3.1.1.1);
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 (13.3.1.1.2);
invocation of the operator referenced in an expression (13.3.1.2);
invocation of a constructor for direct-initialization (8.5) of a class object (13.3.1.3);
invocation of a user-defined conversion for copy-initialization (8.5) of a class object (13.3.1.4);
invocation of a conversion function for initialization of an object of a nonclass type from an expression
of class type (13.3.1.5); and
— invocation of a conversion function for conversion to a glvalue or class prvalue to which a refer-
ence (8.5.3) will be directly bound (13.3.1.6).
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 (13.3.2).
Then the best viable function is selected based on the implicit conversion sequences (13.3.3.1) needed
to match each argument to the corresponding parameter of each viable function.
3If 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 11) in the context in which it is used, the program is
ill-formed.
13.3.1 Candidate functions and argument lists [over.match.funcs]
1The subclauses of 13.3.1 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.
2The 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.
3Similarly, 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.
4For non-static member functions, the type of the implicit object parameter is
“lvalue reference to cv X” for functions declared without a ref-qualifier or with the &ref-qualifier
“rvalue reference to cv X” for functions declared with the && ref-qualifier
§ 13.3.1 283
c
ISO/IEC N????
where Xis 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 (13.3.3). — end note ]
5During overload resolution, the implied object argument is indistinguishable from other arguments. The
implicit object parameter, however, retains its identity since conversions on the corresponding argument
shall obey these additional rules:
no temporary object can be introduced to hold the argument for the implicit object parameter; and
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 (13.3.3.2). — end note ]
6Because 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 (13.3.3,13.3.3.1). [ Example:
class T {
public:
T();
};
class C : T {
public:
C(int);
};
Ta=1; // ill-formed: T(C(1)) not tried
— end example ]
7In each case where a candidate is a function template, candidate function template specializations are gen-
erated using template argument deduction (14.8.3,14.8.2). Those candidates are then handled as candidate
functions in the usual way.128 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.
8A defaulted move constructor or assignment operator (12.8) that is defined as deleted is excluded from the
set of candidate functions in all contexts.
128) 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 the function template
specializations can be treated as normal (non-template) functions for the remainder of overload resolution.
§ 13.3.1 284
c
ISO/IEC N????
13.3.1.1 Function call syntax [over.match.call]
1In a function call (5.2.2)
postfix-expression (expression-listopt )
if the postfix-expression denotes a set of overloaded functions and/or function templates, overload reso-
lution is applied as specified in 13.3.1.1.1. If the postfix-expression denotes an object of class type, overload
resolution is applied as specified in 13.3.1.1.2.
2If 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 13.4.— end note ]
13.3.1.1.1 Call to named function [over.call.func]
1Of interest in 13.3.1.1.1 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.
2In 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 13 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 13 assumes that the postfix-expression that is the left operand of the .
operator has type “cv T” where Tdenotes a class129. Under this assumption, the id-expression in the call
is looked up as a member function of Tfollowing the rules for looking up names in classes (10.2). 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 (13.3.1).
3In 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 (3.4). 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 (9.3.2) 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
Tbecomes the implied object argument130. 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.
13.3.1.1.2 Call to object of class type [over.call.object]
1If the primary-expression Ein 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().
2In addition, for each non-explicit conversion function declared in Tof the form
129) Note that cv-qualifiers on the type of objects are significant in overload resolution for both glvalue and class prvalue
objects.
130) 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.
§ 13.3.1.1.2 285
c
ISO/IEC N????
operator conversion-type-id ( ) cv-qualifier ref-qualifieropt exception-specificationopt attribute-
specifier-seqopt ;
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 (P1,...,Pn) returning R”, or the type “reference
to pointer to function of (P1,...,Pn) returning R”, or the type “reference to function of (P1,...,Pn) returning
R”, a surrogate call function with the unique name call-function and having the form
Rcall-function (conversion-type-id F, P1 a1, ... ,Pn an) { return F (a1,... ,an); }
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 Tprovided the
function is not hidden within Tby another intervening declaration131.
3If such a surrogate call function is selected by overload resolution, the corresponding conversion function will
be called to convert Eto 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.
4The 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 ]
13.3.1.2 Operators in expressions [over.match.oper]
1If 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 5. [ Note: Because .,.*, and ::
cannot be overloaded, these operators are always built-in operators interpreted according to Clause 5.?:
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 (5.16). — end note ] [ Example:
struct String {
String (const String&);
String (const char*);
operator const char* ();
};
String operator + (const String&, const String&);
void f(void) {
const char* p= "one" + "two"; // ill-formed because neither
131) 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.
§ 13.3.1.2 286
c
ISO/IEC N????
// operand has class or enumeration type
intI=1+1; // Always evaluates to 2even if
// class or enumeration types exist that
// would perform the operation.
}
— end example ]
2If 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 11
(where @denotes one of the operators covered in the specified subclause).
Table 11 — Relationship between operator and function call notation
Subclause Expression As member function As non-member function
13.5.1 @a (a).operator@ ( ) operator@ (a)
13.5.2 a@b (a).operator@ (b) operator@ (a, b)
13.5.3 a=b (a).operator= (b)
13.5.5 a[b] (a).operator[](b)
13.5.6 a-> (a).operator-> ( )
13.5.7 a@ (a).operator@ (0) operator@ (a, 0)
3For 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, the set of member candidates is the result of the qualified lookup of
T1::operator@ (13.3.1.1.1); 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 (3.4.2)
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 (possibly
cv-qualified) T1”, when T1 is an enumeration type, or (if there is a right operand) a second parameter
of type T2 or “reference to (possibly cv-qualified) 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 13.6 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
13.3.3.1, and
do not have the same parameter-type-list as any non-template non-member candidate.
4For the built-in assignment operators, conversions of the left operand are restricted as follows:
§ 13.3.1.2 287
c
ISO/IEC N????
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.
5For all other operators, no such restrictions apply.
6The 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 13.3.2 and 13.3.3.132 [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 ]
7If a built-in candidate is selected by overload resolution, the operands are converted to the types of the cor-
responding parameters of the selected operation function. Then the operator is treated as the corresponding
built-in operator and interpreted according to Clause 5.
8The 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.133
9If 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 5.
10 [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 ]
13.3.1.3 Initialization by constructor [over.match.ctor]
1When objects of class type are direct-initialized (8.5), or copy-initialized from an expression of the same or
a derived class type (8.5), overload resolution selects the constructor. For direct-initialization, the candidate
functions are all the constructors of the class of the object being initialized. For copy-initialization, the
132) If the set of candidate functions is empty, overload resolution is unsuccessful.
133) 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.
§ 13.3.1.3 288
c
ISO/IEC N????
candidate functions are all the converting constructors (12.3.1) of that class. The argument list is the
expression-list or assignment-expression of the initializer.
13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
1Under the conditions specified in 8.5, 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. Assuming that “cv1 T” is
the type of the object being initialized, with Ta class type, the candidate functions are selected as follows:
The converting constructors (12.3.1) of Tare candidate functions.
When the type of the initializer expression is a class type “cv S”, the non-explicit conversion functions of
Sand its base classes are considered. When initializing a temporary to be bound to the first parameter
of a constructor that takes a reference to possibly cv-qualified Tas its first argument, 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 Sand yield a type whose cv-unqualified
version is the same type as Tor 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 Xfor this process of selecting candidate functions.
2In 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 ]
13.3.1.5 Initialization by conversion function [over.match.conv]
1Under the conditions specified in 8.5, as part of an initialization of an object of nonclass 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 Sa
class type, the candidate functions are selected as follows:
— The conversion functions of Sand its base classes are considered. Those non-explicit conversion
functions that are not hidden within Sand yield type Tor a type that can be converted to type T
via a standard conversion sequence (13.3.3.1.1) are candidate functions. For direct-initialization, those
explicit conversion functions that are not hidden within Sand yield type Tor a type that can be
converted to type Twith a qualification conversion (4.4) 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 Xfor this process of selecting candidate functions.
2The 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 ]
13.3.1.6 Initialization by conversion function for direct reference binding [over.match.ref]
1Under the conditions specified in 8.5.3, 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 “cv1 T” is the underlying type of the reference being
initialized, and “cv S” is the type of the initializer expression, with Sa class type, the candidate functions
are selected as follows:
— The conversion functions of Sand its base classes are considered. Those non-explicit conversion
functions that are not hidden within Sand 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
§ 13.3.1.6 289
c
ISO/IEC N????
(when initializing an rvalue reference or an lvalue reference to function), where “cv1 T” is reference-
compatible (8.5.3) with “cv2 T2”, are candidate functions. For direct-initialization, those explicit
conversion functions that are not hidden within Sand yield type “lvalue reference to cv2 T2” or “cv2
T2” or “rvalue reference to cv2 T2,” respectively, where T2 is the same type as Tor can be converted
to type Twith a qualification conversion (4.4), are also candidate functions.
2The 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 ]
13.3.1.7 Initialization by list-initialization [over.match.list]
1When objects of non-aggregate class type Tare list-initialized (8.5.4), overload resolution selects the con-
structor in two phases:
— Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class Tand 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 Tand the argument list consists of the elements
of the initializer list.
If the initializer list has no elements and Thas 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 (13.3.1.3,13.3.1.4), 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 ]
13.3.2 Viable functions [over.match.viable]
1From the set of candidate functions constructed for a given context (13.3.1), a set of viable functions is
chosen, from which the best function will be selected by comparing argument conversion sequences for the
best fit (13.3.3). The selection of viable functions considers relationships between arguments and function
parameters other than the ranking of conversion sequences.
2First, 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 marguments in the list, all candidate functions having exactly mparameters are viable.
A candidate function having fewer than mparameters is viable only if it has an ellipsis in its parameter
list (8.3.5). For the purposes of overload resolution, any argument for which there is no corresponding
parameter is considered to “match the ellipsis” (13.3.3.1.3) .
A candidate function having more than mparameters is viable only if the (m+1)-st parameter has a
default argument (8.3.6).134 For the purposes of overload resolution, the parameter list is truncated
on the right, so that there are exactly mparameters.
3Second, for Fto be a viable function, there shall exist for each argument an implicit conversion se-
quence (13.3.3.1) 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 13.3.3.1.4).
134) According to 8.3.6, parameters following the (m+1)-st parameter must also have default arguments.
§ 13.3.2 290
c
ISO/IEC N????
13.3.3 Best viable function [over.match.best]
1Define ICSi(F) as follows:
if Fis 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)135;
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.13.3.3.1 defines the implicit conversion sequences and
13.3.3.2 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 8.5,13.3.1.5, and 13.3.1.6) 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 (13.3.1.6) of a refer-
ence 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 a non-template function 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 14.5.6.2.
135) 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.
§ 13.3.3 291
c
ISO/IEC N????
2If 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-formed136.
[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 sshort is also better than sint
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 cint is better than cshort
}
— end example ]
3If 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 ]
13.3.3.1 Implicit conversion sequences [over.best.ics]
1An 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 4, which means it is governed by the rules for initialization of an
object or reference by a single expression (8.5,8.5.3).
136) The algorithm for selecting the best viable function is linear in the number of viable functions. Run a simple tournament
to find a function Wthat is not worse than any opponent it faced. Although another function Fthat Wdid not face might be
at least as good as W,Fcannot be the best function because at some point in the tournament Fencountered another function
Gsuch that Fwas not better than G. Hence, Wis either the best function or there is no best function. So, make a second pass
over the viable functions to verify that Wis better than all other functions.
§ 13.3.3.1 292
c
ISO/IEC N????
2Implicit 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, or accessibility of the argument and whether or not
the argument is a bit-field 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.
3A well-formed implicit conversion sequence is one of the following forms:
a standard conversion sequence (13.3.3.1.1),
a user-defined conversion sequence (13.3.3.1.2), or
an ellipsis conversion sequence (13.3.3.1.3).
4However, when considering the argument of a constructor or user-defined conversion function that is a
candidate by 13.3.1.3 when invoked for the copying/moving of the temporary in the second step of a class
copy-initialization, by 13.3.1.7 when passing the initializer list as a single argument or when the initializer
list has exactly one element and a conversion to some class Xor reference to (possibly cv-qualified) Xis
considered for the first parameter of a constructor of X, or by 13.3.1.4,13.3.1.5, or 13.3.1.6 in all cases, only
standard conversion sequences and ellipsis conversion sequences are considered.
5For the case where the parameter type is a reference, see 13.3.3.1.4.
6When 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 13; 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 (13.3.3.1.1).
7In all contexts, when converting to the implicit object parameter or when converting to the left operand of
an assignment operation only standard conversion sequences that create no temporary object for the result
are allowed.
8If 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 (13.3.3.1.1).
9If no sequence of conversions can be found to convert an argument to a parameter type or the conversion is
otherwise ill-formed, an implicit conversion sequence cannot be formed.
10 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 13.3.3.2, the ambiguous conversion sequence is treated as a user-defined sequence that is
indistinguishable from any other user-defined conversion sequence137. If a function that uses the ambiguous
137) The ambiguous conversion sequence is ranked with user-defined conversion sequences because multiple conversion sequences
for an argument can exist only if they involve different user-defined conversions. The ambiguous conversion sequence is indistin-
guishable from any other user-defined conversion sequence because it represents at least two user-defined conversion sequences,
each with a different user-defined conversion, and any other user-defined conversion sequence must be indistinguishable from
at least one of them.
This rule prevents a function from becoming non-viable because of an ambiguous conversion sequence for one of its parameters.
Consider this example,
§ 13.3.3.1 293
c
ISO/IEC N????
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.
11 The three forms of implicit conversion sequences mentioned above are defined in the following subclauses.
13.3.3.1.1 Standard conversion sequences [over.ics.scs]
1Table 12 summarizes the conversions defined in Clause 4and 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 Transforma-
tions 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 ]
2[Note: As described in Clause 4, 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. At most one
conversion from each category is allowed in a single standard conversion sequence. 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 ]
3Each conversion in Table 12 also has an associated rank (Exact Match, Promotion, or Conversion). These are
used to rank standard conversion sequences (13.3.3.2). 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 (13.3.3.1.4). 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.
13.3.3.1.2 User-defined conversion sequences [over.ics.user]
1A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user-
defined conversion (12.3) followed by a second standard conversion sequence. If the user-defined conversion
is specified by a constructor (12.3.1), 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 (12.3.2), the initial standard conversion sequence converts the source type to the implicit object
parameter of the conversion function.
2The 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 13.3.3 and 13.3.3.1).
3If the user-defined conversion is specified by a specialization of a conversion function template, the second
standard conversion sequence shall have exact match rank.
4A 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
class B;
class A { A (B&);};
class B { operator A (); };
class C { C (B&); };
void f(A) { }
void f(C) { }
B b;
f(b); // ambiguous because bCvia constructor and
// bAvia constructor or conversion function.
If it were not for this rule, f(A) would be eliminated as a viable function for the call f(b) causing overload resolution to
select f(C) as the function to call even though it is not clearly the best choice. On the other hand, if an f(B) were to be
declared then f(b) would resolve to that f(B) because the exact match with f(B) is better than any of the sequences required
to match f(A).
§ 13.3.3.1.2 294
c
ISO/IEC N????
Table 12 — Conversions
Conversion Category Rank Subclause
No conversions required Identity
Lvalue-to-rvalue conversion 4.1
Array-to-pointer conversion Lvalue Transformation Exact Match 4.2
Function-to-pointer conversion 4.3
Qualification conversions Qualification Adjustment 4.4
Integral promotions 4.5
Floating point promotion Promotion Promotion 4.6
Integral conversions 4.7
Floating point conversions 4.8
Floating-integral conversions 4.9
Pointer conversions Conversion Conversion 4.10
Pointer to member conversions 4.11
Boolean conversions 4.12
a constructor (i.e., a user-defined conversion function) is called for those cases.
13.3.3.1.3 Ellipsis conversion sequences [over.ics.ellipsis]
1An ellipsis conversion sequence occurs when an argument in a function call is matched with the ellipsis
parameter specification of the function called (see 5.2.2).
13.3.3.1.4 Reference binding [over.ics.ref]
1When a parameter of reference type binds directly (8.5.3) 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 (13.3.3.1).
[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 (13.3.3.1.2),
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.
2When 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 underlying type of the reference according
to 13.3.3.1. Conceptually, this conversion sequence corresponds to copy-initializing a temporary of the
underlying type with the argument expression. Any difference in top-level cv-qualification is subsumed by
the initialization itself and does not constitute a conversion.
3Except for an implicit object parameter, for which see 13.3.1, 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 is a temporary or
would require one to be created to initialize the lvalue reference (see 8.5.3). — end note ]
§ 13.3.3.1.4 295
c
ISO/IEC N????
4Other 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 (8.5.3). — end example ]
13.3.3.1.5 List-initialization sequence [over.ics.list]
1When an argument is an initializer list (8.5.4), it is not an expression and special rules apply for converting
it to a parameter type.
2If the parameter type is std::initializer_list<X> or “array of X138 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 ]
3Otherwise, if the parameter is a non-aggregate class Xand overload resolution per 13.3.1.7 chooses a single
best constructor of Xto perform the initialization of an object of type Xfrom the argument initializer list,
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 13.3.3.1.
[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);
138) Since there are no parameters of array type, this will only occur as the underlying type of a reference parameter.
§ 13.3.3.1.5 296
c
ISO/IEC N????
};
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 ]
4Otherwise, if the parameter has an aggregate type which can be initialized from the initializer list according
to the rules for aggregate initialization (8.5.1), 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 ]
5Otherwise, if the parameter is a reference, see 13.3.3.1.4. [ 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 ]
6Otherwise, if the parameter type is not a class:
if the initializer list has one element, 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
§ 13.3.3.1.5 297
c
ISO/IEC N????
— 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 ]
7In all cases other than those enumerated above, no conversion is possible.
13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]
113.3.3.2 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.
2When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1)
a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined con-
version sequence or an ellipsis conversion sequence, and
a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conver-
sion sequence (13.3.3.1.3).
3Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of
the following rules applies:
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 13.3.3.1.1, 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 distin-
guishable by the rules in the paragraph below, or, if not that,
S1 and S2 are reference bindings (8.5.3) 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() &&;
§ 13.3.3.2 298
c
ISO/IEC N????
};
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 (8.5.3) 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 (4.4),
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 int *);
int f(int *);
int i;
int j = f(&i); // calls f(int*)
— end example ] or, if not that,
S1 and S2 are reference bindings (8.5.3), 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 con-
version sequence U2 if they contain the same user-defined conversion function or constructor or they
§ 13.3.3.2 299
c
ISO/IEC N????
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 ]
List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if L1
converts to std::initializer_list<X> for some Xand L2 does not.
4Standard 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.
If class Bis 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 Bis derived directly or indirectly from class Aand class Cis 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 Cto a reference to type Bis better than binding an expression
of type Cto a reference to type A,
conversion of A::* to B::* is better than conversion of A::* to C::*,
conversion of Cto Bis better than conversion of Cto A,
conversion of B* to A* is better than conversion of C* to A*,
binding of an expression of type Bto a reference to type Ais better than binding an expression
of type Cto a reference to type A,
conversion of B::* to C::* is better than conversion of A::* to C::*, and
conversion of Bto Ais better than conversion of Cto 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 13.3.3);
in all other contexts, the source types will be the same and the target types will be different. — end
note ]
§ 13.3.3.2 300
c
ISO/IEC N????
13.4 Address of overloaded function [over.over]
1A 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. The function selected
is the one whose type is identical to the function type of the target type required in the context. [ 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
an object or reference being initialized (8.5,8.5.3,8.5.4),
the left side of an assignment (5.17),
a parameter of a function (5.2.2),
a parameter of a user-defined operator (13.5),
the return value of a function, operator function, or conversion (6.6.3),
an explicit type conversion (5.2.3,5.2.9,5.4), or
a non-type template-parameter (14.3.2).
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 (5.1). — end note ]
2If the name is a function template, template argument deduction is done (14.8.2.2), 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 14.8.1,
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 ]
3Non-member functions and static member functions match targets of type “pointer-to-function” or “reference-
to-function. Nonstatic member functions match targets of type “pointer-to-member-function”. 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 5.3.1.
4If more than one function is selected, any function template specializations in the set are eliminated if the
set also contains a non-template function, 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 14.5.6.2. After such eliminations, if
any, there shall remain exactly one selected function.
5[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,
§ 13.4 301
c
ISO/IEC N????
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 ]
6[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 ]
7[Note: There are no standard conversions (Clause 4) of one pointer-to-function type into another. In
particular, even if Bis a public base of D, we have
D* f();
B* (*p1)() = &f; // error
void g(D*);
void (*p2)(B*) = &g; // error
— end note ]
13.5 Overloaded operators [over.oper]
1A 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 (5.2.2) and subscripting (5.2.1). The operators new[],
delete[],(), and [] are formed from more than one token. — end note ]
2Both the unary and binary forms of
+ - * &
can be overloaded.
3The following operators cannot be overloaded:
. .* :: ?:
nor can the preprocessing symbols #and ## (Clause 16).
4Operator functions are usually not called directly; instead they are invoked to evaluate the operators they
implement (13.5.1 13.5.7). They can be explicitly called, however, using the operator-function-id as the
name of the function in the function call syntax (5.2.2). [ Example:
§ 13.5 302
c
ISO/IEC N????
complex z = a.operator+(b); // complex z = a+b;
void* p = operator new(sizeof(int)*n);
— end example ]
5The allocation and deallocation functions, operator new,operator new[],operator delete and operator
delete[], are described completely in 3.7.4. The attributes and restrictions found in the rest of this
subclause do not apply to them unless explicitly stated in 3.7.4.
6An operator function shall either be a non-static member function or be a non-member function and have
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.
7The 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.
8An operator function cannot have default arguments (8.3.6), 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.
9Operators not mentioned explicitly in subclauses 13.5.3 through 13.5.7 act as ordinary unary and binary
operators obeying the rules of 13.5.1 or 13.5.2.
13.5.1 Unary operators [over.unary]
1A prefix unary operator shall be implemented by a non-static member function (9.3) 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 13.3.1.2 determine which, if any, interpretation is used. See 13.5.7 for an explanation of the postfix
unary operators ++ and --.
2The unary and binary forms of the same operator are considered to have the same name. [ Note: Con-
sequently, a unary operator can hide a binary operator from an enclosing scope, and vice versa. — end
note ]
13.5.2 Binary operators [over.binary]
1A binary operator shall be implemented either by a non-static member function (9.3) 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 13.3.1.2 determine which, if any, interpretation is used.
13.5.3 Assignment [over.ass]
1An 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 (12.8), a base class assignment operator is always hidden by the copy assignment operator of the
derived class.
2Any assignment operator, even the copy and move assignment operators, can be virtual. [ Note: For a derived
class Dwith a base class Bfor which a virtual copy/move assignment has been declared, the copy/move
assignment operator in Ddoes 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&);
§ 13.5.3 303
c
ISO/IEC N????
};
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 ]
13.5.4 Function call [over.call]
1operator() 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-listopt )
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 xof type Tif T::operator()(T1, T2, T3) exists and if
the operator is selected as the best match function by the overload resolution mechanism (13.3.3).
13.5.5 Subscripting [over.sub]
1operator[] shall be a non-static member function with exactly one parameter. It implements the subscript-
ing syntax
postfix-expression [expression ]
or
postfix-expression [braced-init-list ]
Thus, a subscripting expression x[y] is interpreted as x.operator[](y) for a class object xof type
Tif T::operator[](T1) exists and if the operator is selected as the best match function by the overload
resolution mechanism (13.3.3). [ 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 ]
13.5.6 Class member access [over.ref]
1operator-> shall be a non-static member function taking no parameters. It implements the class member
access syntax that uses ->.
postfix-expression -> templateopt id-expression
postfix-expression -> pseudo-destructor-name
An expression x->m is interpreted as (x.operator->())->m for a class object xof type Tif T::operator->()
exists and if the operator is selected as the best match function by the overload resolution mechanism (13.3).
13.5.7 Increment and decrement [over.inc]
1The user-defined function called operator++ implements the prefix and postfix ++ operator. If this function
is a 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 member function with one parameter
§ 13.5.7 304
c
ISO/IEC N????
(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.139 [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 ]
2The prefix and postfix decrement operators -- are handled analogously.
13.5.8 User-defined literals [over.literal]
literal-operator-id:
operator string-literal identifier
operator user-defined-string-literal
1The 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’. The ud-suffix of the user-defined-string-
literal or the identifier in a literal-operator-id is called a literal suffix identifier. [ Note: some literal suffix
identifiers are reserved for future standardization; see 17.6.4.3.5.— end note ]
2A 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 (11.3)), an explicit instantiation or specialization of a
function template, or a using-declaration (7.3.3). 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.
3The 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
139) Calling operator++ explicitly, as in expressions like a.operator++(2), has no special properties: The argument to
operator++ is 2.
§ 13.5.8 305
c
ISO/IEC N????
const char32_t*, std::size_t
If a parameter has a default argument (8.3.6), the program is ill-formed.
4Araw literal operator is a literal operator with a single parameter whose type is const char*.
5The 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
(14.5.3) with element type char.
6Literal operators and literal operator templates shall not have C language linkage.
7[Note: Literal operators and literal operator templates are usually invoked implicitly through user-defined
literals (2.14.8). 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 tem-
plates 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 ]
8[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, but reserved (17.6.4.3.5)
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
— end example ]
13.6 Built-in operators [over.built]
1The candidate operator functions that represent the built-in operators defined in Clause 5are specified in
this subclause. These candidate functions participate in the operator overload resolution process as described
in 13.3.1.2 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 13.3.1.2, 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 5, 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 ]
2In this subclause, the term promoted integral type is used to refer to those integral types which are preserved
by integral promotion (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 ]
3For every pair (T,VQ), where Tis an arithmetic type, and VQ is either volatile or empty, there exist
candidate operator functions of the form
VQ T & operator++(VQ T &);
Toperator++(VQ T &, int);
4For every pair (T,VQ), where Tis an arithmetic type other than bool, and VQ is either volatile or empty,
there exist candidate operator functions of the form
§ 13.6 306
c
ISO/IEC N????
VQ T & operator--(VQ T &);
Toperator--(VQ T &, int);
5For every pair (T,VQ), where Tis a cv-qualified or cv-unqualified object type, and VQ is either volatile
or empty, 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);
6For every cv-qualified or cv-unqualified object type T, there exist candidate operator functions of the form
T& operator*(T*);
7For every function type Tthat does not have cv-qualifiers or a ref-qualifier, there exist candidate operator
functions of the form
T& operator*(T*);
8For every type Tthere exist candidate operator functions of the form
T* operator+(T*);
9For every promoted arithmetic type T, there exist candidate operator functions of the form
Toperator+(T);
Toperator-(T);
10 For every promoted integral type T, there exist candidate operator functions of the form
Toperator(T);
11 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, Tis an object type or a function type, and CV1 and CV2 are cv-qualifier-seqs, 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.
12 For every pair of promoted arithmetic types Land 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 Land R.
13 For every cv-qualified or cv-unqualified object type Tthere 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*);
14 For every T, where Tis a pointer to object type, there exist candidate operator functions of the form
§ 13.6 307
c
ISO/IEC N????
std::ptrdiff_t operator-(T,T);
15 For every T, where Tis 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);
16 For every pointer to member type Tor type std::nullptr_t there exist candidate operator functions of
the form
bool operator==(T,T);
bool operator!=(T,T);
17 For every pair of promoted integral types Land 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);
Loperator<<(L,R);
Loperator>>(L,R);
where LR is the result of the usual arithmetic conversions between types Land R.
18 For every triple (L,VQ,R), where Lis an arithmetic type, VQ is either volatile or empty, and Ris 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);
19 For every pair (T,VQ), where Tis any type and VQ is either volatile or empty, there exist candidate
operator functions of the form
T*VQ & operator=(T*VQ &, T*);
20 For every pair (T,VQ), where Tis an enumeration or pointer to member type and VQ is either volatile
or empty, there exist candidate operator functions of the form
VQ T & operator=(VQ T &, T);
21 For every pair (T,VQ), where Tis a cv-qualified or cv-unqualified object type and VQ is either volatile
or empty, there exist candidate operator functions of the form
T*VQ & operator+=(T*VQ &, std::ptrdiff_t);
T*VQ & operator-=(T*VQ &, std::ptrdiff_t);
22 For every triple (L,VQ,R), where Lis an integral type, VQ is either volatile or empty, and Ris 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);
§ 13.6 308
c
ISO/IEC N????
23 There also exist candidate operator functions of the form
bool operator!(bool);
bool operator&&(bool, bool);
bool operator||(bool, bool);
24 For every pair of promoted arithmetic types Land 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 Land 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 ]
25 For every type T, where Tis a pointer, pointer-to-member, or scoped enumeration type, there exist candidate
operator functions of the form
Toperator?:(bool, T,T);
§ 13.6 309
c
ISO/IEC N????
14 Templates [temp]
1Atemplate defines a family of classes or functions 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 (14.2). — 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
be an alias-declaration.
Atemplate-declaration is a declaration. 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.1415926535897932385);
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 }, { -1, 0 } };
};
— end example ]
2Atemplate-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 (14.5.5). — end note ]
3In a template-declaration, explicit specialization, or explicit instantiation the init-declarator-list in the dec-
laration shall contain at most one declarator. When such a declaration is used to declare a class template,
no declarator is permitted.
Templates 310
c
ISO/IEC N????
4A template name has linkage (3.5). A non-member function template can have internal linkage; any other
template name shall have external linkage. Specializations (explicit or implicit) of a template that has
internal linkage are distinct from all specializations in other translation units. A template, a template ex-
plicit specialization (14.7.3), 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 (3.2). [ Note: De-
fault arguments for function templates and for member functions of class templates are considered definitions
for the purpose of template instantiation (14.5) and must also obey the one definition rule. — end note ]
5A class template shall not have the same name as any other template, class, function, variable, enumeration,
enumerator, namespace, or type in the same scope (3.3), except as specified in (14.5.5). Except that a
function template can be overloaded either by (non-template) functions with the same name or by other
function templates with the same name (14.8.3), a template name declared in namespace scope or in class
scope shall be unique in that scope.
6A 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 (14.7.1) unless
the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is
required.
14.1 Template parameters [temp.param]
1The syntax for template-parameters is:
template-parameter:
type-parameter
parameter-declaration
type-parameter:
class ...opt identifieropt
class identifieropt =type-id
typename ...opt identifieropt
typename identifieropt =type-id
template < template-parameter-list > class ...opt identifieropt
template < template-parameter-list > class identifieropt =id-expression
[Note: The >token following the template-parameter-list of a type-parameter may be the product of replacing
a>> token by two consecutive >tokens (14.2). — end note ]
2There is no semantic difference between class and typename in a template-parameter.typename followed
by an unqualified-id names a template type parameter. typename followed by a qualified-id denotes the
type in a non-type 140 parameter-declaration. A storage class shall not be specified in a template-parameter
declaration. Types shall not be defined in a template-parameter declaration. [ Note: A template parameter
may be a class 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 ]
3Atype-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if
declared with class or typename) or template-name (if declared with template) in the scope of the template
declaration. [ Note: Because of the name lookup rules, a template-parameter that could be interpreted as
140) 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.
§ 14.1 311
c
ISO/IEC N????
either a non-type template-parameter or a type-parameter (because its identifier is the name of an already
existing class) is taken as a type-parameter. For example,
class T { /... /};
int i;
template<class T, T i> void f(T t) {
T t1 = i; // template-parameters Tand i
::T t2 = ::i; // global namespace members Tand i
}
Here, the template fhas a type-parameter called T, rather than an unnamed non-type template-parameter
of class T.— end note ]
4A 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.
5[Note: Other types are disallowed either explicitly below or implicitly by the rules governing the form of
template-arguments (14.3). — end note ] The top-level cv-qualifiers on the template-parameter are ignored
when determining its type.
6A 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 ]
7A non-type template-parameter shall not be declared to have floating point, class, array of runtime bound,
or void type. [ Example:
template<double d> class X; // error
template<double* pd> class Y; // OK
template<double& rd> class Z; // OK
— end example ]
8A non-type template-parameter of type “array of T” or “function returning T” is adjusted to be of type
“pointer to T” or “pointer to function returning T”, respectively. [ Example:
template<int* a> struct R { /... /};
template<int b[5]> struct S { /... /};
int p;
R<&p> w; // OK
§ 14.1 312
c
ISO/IEC N????
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 ]
9Adefault template-argument is a template-argument (14.3) specified after =in a template-parameter. A de-
fault template-argument may be specified for any kind of template-parameter (type, non-type, template) that
is not a template parameter pack (14.5.3). A default template-argument may be specified in a template dec-
laration. 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.
10 The set of default template-arguments available for use with a template declaration or definition is obtained
by merging the default arguments from the definition (if in scope) and all declarations in scope in the same
way default function arguments are (8.3.6). [ 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 ]
11 If a template-parameter of a class template or alias template has a default template-argument, each subse-
quent 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 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
of the function template or has a default argument (14.8.2). [ Example:
template<class T1 = int, class T2> class B; // error
// Ucan 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 ]
12 Atemplate-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 ]
13 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 ]
§ 14.1 313
c
ISO/IEC N????
14 Atemplate-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 ]
15 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 (8.3.5), then the template-parameter is a template parameter
pack (14.5.3). 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 Twithin the same template parameter list
— end example ]
14.2 Names of template specializations [temp.names]
1A template specialization (14.7) can be referred to by a template-id:
simple-template-id:
template-name <template-argument-listopt >
template-id:
simple-template-id
operator-function-id <template-argument-listopt >
literal-operator-id <template-argument-listopt >
template-name:
identifier
template-argument-list:
template-argument ...opt
template-argument-list ,template-argument ...opt
template-argument:
constant-expression
type-id
id-expression
§ 14.2 314
c
ISO/IEC N????
[Note: The name lookup rules (3.4) are used to associate the use of a name with a template declaration;
that is, to identify a name as a template-name.— end note ]
2For a template-name to be explicitly qualified by the template arguments, the name must be known to refer
to a template.
3After name lookup (3.4) 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 >141 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 ]
4When the name of a member template specialization appears after .or -> in a postfix-expression or after a
nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent
or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of
the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template.
Otherwise the name is assumed to name a non-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 ]
5A name prefixed by the keyword template shall be a template-id or the name shall refer to a class 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);
};
141) 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.
§ 14.2 315
c
ISO/IEC N????
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 ]
6Asimple-template-id that names a class template specialization is a class-name (Clause 9).
7Atemplate-id that names an alias template specialization is a type-name.
14.3 Template arguments [temp.arg]
1There 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 (14.5.3), 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 ]
2In 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.142 [Example:
template<class T> void f();
template<int I> void f();
void g() {
142) 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.
§ 14.3 316
c
ISO/IEC N????
f<int()>(); // int() is a type-id: call the first f()
}
— end example ]
3The 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: Sis accessible
// X<Y::S> has a static member of type Y::S
// OK: even though Y::S is private
};
X<Y::S> y; // error: Snot 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: Ahas no access to B::S
— end example ]
4When 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 ]
5An explicit destructor call (12.4) 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
}
§ 14.3 317
c
ISO/IEC N????
— end example ]
6If 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.
7When 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.
8Atemplate-argument followed by an ellipsis is a pack expansion (14.5.3).
14.3.1 Template type arguments [temp.arg.type]
1Atemplate-argument for a template-parameter which is a type shall be a type-id.
2[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 (3.9). — end note ]
3If a declaration acquires a function type through a type dependent on a template-parameter and this causes a
declaration that does not use the syntactic form of a function declarator to have function type, 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 ]
14.3.2 Template non-type arguments [temp.arg.nontype]
1Atemplate-argument for a non-type, non-template template-parameter shall be one of:
— for a non-type template-parameter of integral or enumeration type, a converted constant expres-
sion (5.19) of the type of the template-parameter; or
the name of a non-type template-parameter; or
a constant expression (5.19) that designates the address of an object with static storage duration and
external or internal linkage or a function with external or internal linkage, including function templates
and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as
&id-expression, except that the &may be omitted if the name refers to a function or array and shall
be omitted if the corresponding template-parameter is a reference; or
§ 14.3.2 318
c
ISO/IEC N????
a constant expression that evaluates to a null pointer value (4.10); or
a constant expression that evaluates to a null member pointer value (4.11); or
a pointer to member expressed as described in 5.3.1; or
an address constant expression of type std::nullptr_t.
2[Note: A string literal (2.14.5) does not satisfy the requirements of any of these categories and thus 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 ]
3[Note: Addresses of array elements and names or addresses of non-static class members are not acceptable
template-arguments. [ 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; // error: &S::s must be used
X<&S::s> x6; // OK: address of static member
— end example ]— end note ]
4[Note: Temporaries, unnamed lvalues, and named lvalues with no linkage are not acceptable template-
arguments 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 ]
5The following conversions are performed on each expression used as a non-type template-argument. If a
non-type template-argument cannot be converted to the type of the corresponding template-parameter then
the program is ill-formed.
For a non-type template-parameter of integral or enumeration type, conversions permitted in a con-
verted constant expression (5.19) are applied.
for a non-type template-parameter of type pointer to object, qualification conversions (4.4) and the
array-to-pointer conversion (4.2) are applied; if the template-argument is of type std::nullptr_t, the
null pointer conversion (4.10) is applied. [ Note: In particular, neither the null pointer conversion for a
zero-valued integer literal (4.10) nor the derived-to-base conversion (4.10) are applied. Although 0is a
§ 14.3.2 319
c
ISO/IEC N????
valid template-argument for a non-type template-parameter of integral type, it is not a valid template-
argument for a non-type template-parameter of pointer type. However, both (int*)0 and nullptr
are valid template-arguments for a non-type template-parameter of type “pointer to int. — end note ]
For a non-type template-parameter of type reference to object, no conversions apply. The type referred
to by the reference may be more cv-qualified than the (otherwise identical) type of the template-
argument. The template-parameter is bound directly to the template-argument, which shall be an
lvalue.
For a non-type template-parameter of type pointer to function, the function-to-pointer conversion (4.3)
is applied; if the template-argument is of type std::nullptr_t, the null pointer conversion (4.10) is
applied. If the template-argument represents a set of overloaded functions (or a pointer to such), the
matching function is selected from the set (13.4).
For a non-type template-parameter of type reference to function, no conversions apply. If the template-
argument represents a set of overloaded functions, the matching function is selected from the set (13.4).
For a non-type template-parameter of type pointer to member function, if the template-argument is of
type std::nullptr_t, the null member pointer conversion (4.11) is applied; otherwise, no conversions
apply. If the template-argument represents a set of overloaded member functions, the matching member
function is selected from the set (13.4).
For a non-type template-parameter of type pointer to data member, qualification conversions (4.4) are
applied; if the template-argument is of type std::nullptr_t, the null member pointer conversion (4.11)
is applied.
[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)
— end example ]
14.3.3 Template template arguments [temp.arg.template]
1Atemplate-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
§ 14.3.3 320
c
ISO/IEC N????
parameter; partial specializations are not considered even if their parameter lists match that of the template
template parameter.
2Any partial specializations (14.5.5) 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 special-
ization 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 is 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 ]
[Example:
template<class T> class A { /... /};
template<class T, class U = T> class B { /... /};
template <class ... Types> class C { /... /};
template<template<class> class P> class X { /... /};
template<template<class ...> class Q> class Y { /... /};
X<A> xa; // OK
X<B> xb; // ill-formed: default arguments for the parameters of a template argument are ignored
X<C> xc; // ill-formed: a template parameter pack does not match a template parameter
Y<A> ya; // OK
Y<B> yb; // OK
Y<C> yc; // OK
— end example ]
3Atemplate-argument matches a template template-parameter (call it P) when each of the template parameters
in the template-parameter-list of the template-argument’s corresponding class template or alias template (call
it A) matches the corresponding template parameter in the template-parameter-list of P. When P’s template-
parameter-list contains a template parameter pack (14.5.3), the template parameter pack will match zero
or more template parameters or template parameter packs in the template-parameter-list of Awith 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> 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;
§ 14.3.3 321
c
ISO/IEC N????
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: Cdoes not match TT in partial specialization
eval<D<int, 17>> eD; // error: Ddoes not match TT in partial specialization
eval<E<int, float>> eE; // error: Edoes not match TT in partial specialization
— end example ]
14.4 Type equivalence [temp.type]
1Two template-ids refer to the same class, function, or variable if
their template-names, operator-function-ids, or literal-operator-ids refer to the same template and
their corresponding type template-arguments are the same type and
their corresponding non-type template arguments of integral or enumeration type have identical values
and
their corresponding non-type template-arguments of pointer type refer to the same external object or
function or are both the null pointer value and
their corresponding non-type template-arguments of pointer-to-member type refer to the same class
member or are both the null member pointer value and
their corresponding non-type template-arguments of reference type refer to the same external object
or function and
their corresponding template template-arguments refer to the same template.
[Example:
template<class E, int size> class buffer { /... /};
buffer<char,2*512> x;
buffer<char,1024> y;
declares xand yto 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 yand zto be of the same type. — end example ]
2If an expression einvolves a template parameter, decltype(e)denotes a unique dependent type. Two such
decltype-specifiers refer to the same type only if their expressions are equivalent (14.5.6.1). [ Note: however,
it may be aliased, e.g., by a typedef-name.— end note ]
§ 14.4 322
c
ISO/IEC N????
14.5 Template declarations [temp.decls]
1Atemplate-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 (14.5.5).
— end note ]
2For purposes of name lookup and instantiation, default arguments and exception-specifications of function
templates and default arguments and exception-specifications of member functions of class templates are
considered definitions; each default argument or exception-specification is a separate definition which is
unrelated to the function template definition or to any other default arguments or exception-specifications.
3Because an alias-declaration cannot declare a template-id, it is not possible to partially or explicitly specialize
an alias template.
14.5.1 Class templates [temp.class]
1A class template defines the layout and operations for an unbounded set of related types. [ Example: a single
class template List might provide a common definition for list of int, list of float, and list of pointers to
Shapes. — end example ]
[Example: An array class template might be declared 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]; }
};
2The prefix template <class T> specifies that a template is being declared and that a type-name Twill be
used in the declaration. In other words, Array is a parameterized type with Tas its parameter. — end
example ]
3When 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();
};
§ 14.5.1 323
c
ISO/IEC N????
template<class ... Types> void B<Types ...>::f3() { } // OK
template<class ... Types> void B<Types>::f4() { } // error
— end example ]
4In 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 (7.1.6.3).
14.5.1.1 Member functions of class templates [temp.mem.func]
1A 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 ]
2The 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 ]
14.5.1.2 Member classes of class templates [temp.mem.class]
1A class member of a class template may be defined outside the class template definition in which it is declared.
[Note: The class member must be defined before its first use that requires an instantiation (14.7.1). For
example,
template<class T> struct A {
class B;
};
A<int>::B* b1; // OK: requires Ato 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 ]
14.5.1.3 Static data members of class templates [temp.static]
1A 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;
§ 14.5.1.3 324
c
ISO/IEC N????
};
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 ]
2An 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 ]
14.5.1.4 Enumeration members of class templates [temp.mem.enum]
1An 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 ]
14.5.2 Member templates [temp.mem]
1A 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 ]
2A local class of non-closure type shall not have member templates. Access control rules (Clause 11) apply to
member template names. A destructor shall not be a member template. A normal (non-template) member
function 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:
§ 14.5.2 325
c
ISO/IEC N????
template <class T> struct A {
void f(int);
template <class T2> void f(T2);
};
template <> void A<int>::f(int) { } // non-template member
template <> template <> void A<int>::f<>(int) { } // template member
int main() {
A<char> ac;
ac.f(1); // non-template
ac.f(’c’); // template
ac.f<>(1); // template
}
— end example ]
3A 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 ]
4A 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 ]
5A 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
§ 14.5.2 326
c
ISO/IEC N????
without using a function name, there is no way to provide an explicit template argument list for these
function templates. — end note ]
6A 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 (14.8.2.3), the resulting specialization is used as if found by name lookup.
7Ausing-declaration in a derived class cannot refer to a specialization of a conversion function template in a
base class.
8Overload resolution (13.3.3.2) and partial ordering (14.5.6.2) are used to select the best conversion function
among multiple specializations of conversion function templates and/or non-template conversion functions.
14.5.3 Variadic templates [temp.variadic]
1Atemplate 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 ]
2Afunction 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 ]
3Aparameter pack is either a template parameter pack or a function parameter pack.
4Apack 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:
In a function parameter pack (8.3.5); the pattern is the parameter-declaration without the ellipsis.
In a template parameter pack that is a pack expansion (14.1):
if the template parameter pack is a parameter-declaration; the pattern is the parameter-declaration
without the ellipsis;
if the template parameter pack is a type-parameter with a template-parameter-list; the pattern is
the corresponding type-parameter without the ellipsis.
In an initializer-list (8.5); the pattern is an initializer-clause.
In a base-specifier-list (Clause 10); the pattern is a base-specifier.
In a mem-initializer-list (12.6.2) for a mem-initializer whose mem-initializer-id denotes a base class;
the pattern is the mem-initializer.
In a template-argument-list (14.3); the pattern is a template-argument.
In a dynamic-exception-specification (15.4); the pattern is a type-id.
In an attribute-list (7.6.1); the pattern is an attribute.
In an alignment-specifier (7.6.2); the pattern is the alignment-specifier without the ellipsis.
§ 14.5.3 327
c
ISO/IEC N????
In a capture-list (5.1.2); the pattern is a capture.
In a sizeof... expression (5.3.3); the pattern is an identifier.
[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 ]
5A 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 ]
6The instantiation of a pack expansion that is not a sizeof... expression produces a list E1,E2, ..., EN, where
Nis the number of elements in the pack expansion parameters. Each Eiis generated by instantiating the
pattern and replacing each pack expansion parameter with its ith element. All of the Eibecome 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 Nis 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...);
}
§ 14.5.3 328
c
ISO/IEC N????
template void f<>(); // OK: X<> has no base classes
// xis a variable of type X<> that is value-initialized
— end example ]
7The instantiation of a sizeof... expression (5.3.3) produces an integral constant containing the number
of elements in the parameter pack it expands.
14.5.4 Friends [temp.friend]
1A 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 an ordinary (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 speci-
fied class or namespace, the friend declaration refers to the deduced specialization of that function
template (14.8.2.6), otherwise,
the name shall be an unqualified-id that declares (or redeclares) an ordinary (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 ]
2A 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
};
§ 14.5.4 329
c
ISO/IEC N????
— end example ]
3A template friend declaration specifies that all specializations of that template, whether they are implicitly
instantiated (14.7.1), partially specialized (14.5.5) or explicitly specialized (14.7.3), 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 ]
4When a function is defined in a friend function declaration in a class template, the function is instantiated
when the function is odr-used. The same restrictions on multiple declarations and definitions that apply to
non-template function declarations and definitions also apply to these implicit definitions.
5A 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 class template is a friend of the class granting friendship.
For explicit 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 ]
6[Note: A friend declaration may first declare a member of an enclosing namespace scope (14.6.5). — end
note ]
7A friend template shall not be declared in a local class.
8Friend declarations shall not declare partial specializations. [ Example:
template<class T> class A { };
class X {
template<class T> friend class A<T*>; // error
§ 14.5.4 330
c
ISO/IEC N????
};
— end example ]
9When a friend declaration refers to a specialization of a function template, the function parameter declara-
tions shall not include default arguments, nor shall the inline specifier be used in such a declaration.
14.5.5 Class template partial specializations [temp.class.spec]
1Aprimary 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 (14.5.5.1). 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.
2Each class template partial specialization is a distinct template and definitions shall be provided for the
members of a template partial specialization (14.5.5.3).
3[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
The first declaration declares the primary (unspecialized) class template. The second and subsequent
declarations declare partial specializations of the primary template. — end example ]
4The 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 ]
5A class template partial specialization may be declared or redeclared in any namespace scope in which its
definition may be defined (14.5.1 and 14.5.2). [ Example:
template<class T> struct A {
struct C {
template<class T2> struct B { };
};
};
// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
struct A<T>::C::B<T2*> { };
A<short>::C::B<int*> absip; // uses partial specialization
— end example ]
6Partial 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
§ 14.5.5 331
c
ISO/IEC N????
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 ]
7A non-type argument is non-specialized if it is the name of a non-type parameter. All other non-type
arguments are specialized.
8Within the argument list of a class template partial specialization, the following restrictions apply:
A partially specialized non-type argument expression shall not involve a template parameter of the
partial specialization except when the argument expression is a simple identifier. [ Example:
template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {}; // error
template <int I, int J> struct B {};
template <int I> struct B<I, I> {}; // OK
— end example ]
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 argument list of the specialization shall not be identical to the implicit argument list of the primary
template.
The specialization shall be more specialized than the primary template (14.5.5.2).
The template parameter list of a specialization shall not contain default template argument values.143
An argument shall not contain an unexpanded parameter pack. If an argument is a pack expan-
sion (14.5.3), it shall be the last argument in the template argument list.
143) There is no way in which they could be used.
§ 14.5.5 332
c
ISO/IEC N????
14.5.5.1 Matching of class template partial specializations [temp.class.spec.match]
1When 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 (14.5.5.2) are used to deter-
mine 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.
2A 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 (14.8.2). [ Example:
A<int, int, 1> a1; // uses #1
A<int, int*, 1> a2; // uses #2, Tis int,Iis 1
A<int, char*, 5> a3; // uses #4, Tis char
A<int, char*, 1> a4; // uses #5, T1 is int,T2 is char,Iis 1
A<int*, int*, 2> a5; // ambiguous: matches #3 and #5
— end example ]
3A non-type template argument can also be deduced from the value of an actual template argument of a
non-type parameter of the primary template. [ Example: the declaration of a2 above. — end example ]
4In 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.
14.5.5.2 Partial ordering of class template specializations [temp.class.order]
1For two class template partial specializations, the first is at least as specialized as the second if, given the
following rewrite to two function templates, the first function template is at least as specialized as the second
according to the ordering rules for function templates (14.5.6.2):
the first function template has the same template parameters as the first partial specialization and has
a single function parameter whose type is a class template specialization with the template arguments
of the first partial specialization, and
the second function template has the same template parameters as the second partial specialization
and has a single function parameter whose type is a class template specialization with the template
arguments of the second partial specialization.
2[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 I, int J> void f(X<I, J, int>); // A
template<int I> void f(X<I, I, int>); // B
The partial specialization #2 is more specialized than the partial specialization #1 because the function
template Bis more specialized than the function template Aaccording to the ordering rules for function
templates. — end example ]
§ 14.5.5.2 333
c
ISO/IEC N????
14.5.5.3 Members of class template specializations [temp.class.spec.mfunc]
1The 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 special-
ization. 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 template
template<class T, int I> struct A {
void f();
};
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 ffor A<T,2>
// the primary template is not used here
}
— end example ]
2If 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 (14.7.1,
14.7.2), 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 {
§ 14.5.5.3 334
c
ISO/IEC N????
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 ]
14.5.6 Function templates [temp.fct]
1A 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 ]
2A function template can be overloaded with other function templates and with normal (non-template)
functions. A normal function is not related to a function template (i.e., it is never considered to be a special-
ization), even if it has the same name and type as a potentially generated function template specialization.144
14.5.6.1 Function template overloading [temp.over.link]
1It is possible to overload function templates so that two different function template specializations have the
same type. [ Example:
// file1.c
template<class T>
void f(T*);
void g(int* p) {
f(p); // calls f<int>(int*)
}
// file2.c
template<class T>
void f(T);
void h(int* p) {
f(p); // calls f<int*>(int*)
}
— end example ]
2Such specializations are distinct functions and do not violate the one definition rule (3.2).
3The signature of a function template is defined in 1.3. The names of the template parameters are significant
only for establishing the relationship between the template parameters and the rest of the signature. [ Note:
Two distinct function templates may have identical function return types and function parameter lists, even
if overload resolution alone cannot distinguish them.
template<class T> void f();
template<int I> void f(); // OK: overloads the first template
// distinguishable with an explicit template argument list
— end note ]
4When an expression that references a template parameter is used in the function parameter list or the return
type in the declaration of a function template, the expression that references the template parameter is part
of the signature of the function template. This is necessary to permit a declaration of a function template
in one translation unit to be linked with another declaration of the function template in another translation
unit and, conversely, to ensure that function templates that are intended to be distinct are not linked with
one another. [ Example:
144) 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 (3.2) in a program, it must be defined; it will not be implicitly
instantiated using the function template definition.
§ 14.5.6.1 335
c
ISO/IEC N????
template <int I, int J> A<I+J> f(A<I>, A<J>); // #1
template <int K, int L> A<K+L> f(A<K>, A<L>); // same as #1
template <int I, int J> A<I-J> f(A<I>, A<J>); // different from #1
— end example ] [ Note: Most expressions that use template parameters use non-type template parameters,
but it is possible for an expression to reference a type parameter. For example, a template type parameter
can be used in the sizeof operator. — end note ]
5Two expressions involving template parameters are considered equivalent if two function definitions con-
taining the expressions would satisfy the one definition rule (3.2), except that the tokens used to name the
template parameters may differ as long as a token used to name a template parameter in one expression is
replaced by another token that names the same template parameter in the other expression. For determining
whether two dependent names (14.6.2) are equivalent, only the name itself is considered, not the result of
name lookup in the context of the template. If multiple declarations of the same function template differ in
the result of this name lookup, the result for the first declaration is used. [ Example:
template <int I, int J> void f(A<I+J>); // #1
template <int K, int L> void f(A<K+L>); // same as #1
template <class T> decltype(g(T())) h();
int g(int);
template <class T> decltype(g(T())) h() // redeclaration of h() uses the earlier lookup
{ return g(T()); } // ...although the lookup here does find g(int)
int i = h<int>(); // template argument substitution fails; g(int)
// was not in scope at the first declaration of h()
— end example ] Two expressions involving template parameters that are not equivalent are functionally
equivalent if, for any given set of template arguments, the evaluation of the expression results in the same
value.
6Two function templates are equivalent if they are declared in the same scope, have the same name, have
identical template parameter lists, and have return types and parameter lists that are equivalent using the
rules described above to compare expressions involving template parameters. Two function templates are
functionally equivalent if they are equivalent except that one or more expressions that involve template
parameters in the return types and parameter lists are functionally equivalent using the rules described
above to compare expressions involving template parameters. If a program contains declarations of function
templates that are functionally equivalent but not equivalent, the program is ill-formed; no diagnostic is
required.
7[Note: This rule guarantees that equivalent declarations will be linked with one another, while not requiring
implementations to use heroic efforts to guarantee that functionally equivalent declarations will be treated
as distinct. For example, the last two declarations are functionally equivalent and would cause a program
to be ill-formed:
// Guaranteed to be the same
template <int I> void f(A<I>, A<I+10>);
template <int I> void f(A<I>, A<I+10>);
// Guaranteed to be different
template <int I> void f(A<I>, A<I+10>);
template <int I> void f(A<I>, A<I+11>);
// Ill-formed, no diagnostic required
template <int I> void f(A<I>, A<I+10>);
template <int I> void f(A<I>, A<I+1+2+3+4>);
§ 14.5.6.1 336
c
ISO/IEC N????
— end note ]
14.5.6.2 Partial ordering of function templates [temp.func.order]
1If a function template is overloaded, the use of a function template specialization might be ambiguous
because template argument deduction (14.8.2) 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:
during overload resolution for a call to a function template specialization (13.3.3);
when the address of a function template specialization is taken;
when a placement operator delete that is a function template specialization is selected to match a
placement operator new (3.7.4.2,5.3.4);
when a friend function declaration (14.5.4), an explicit instantiation (14.7.2) or an explicit specializa-
tion (14.7.3) refers to a function template specialization.
2Partial 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.
3To produce the transformed template, for each type, non-type, or template template parameter (including
template parameter packs (14.5.3) 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. If only one of
the function templates is a non-static member of some class A, that function template is considered to have
a new first parameter inserted in its function parameter list. Given cv as the cv-qualifiers of the function
template (if any), the new parameter is of type “rvalue reference to cv A” if the optional ref-qualifier of the
function template is &&, or of type “lvalue reference to cv A otherwise. [ Note: This allows a non-static
member to be ordered with respect to a nonmember function and for the results to be equivalent to the
ordering of two equivalent nonmembers. — 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 ]
4Using the transformed function template’s function type, perform type deduction against the other template
as described in 14.8.2.4.
[Example:
template<class T> struct A { A(); };
template<class T> void f(T);
§ 14.5.6.2 337
c
ISO/IEC N????
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 ]
5[Note: Since partial ordering in a call context considers only parameters for which there are explicit call argu-
ments, 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
§ 14.5.6.2 338
c
ISO/IEC N????
void h(int i) {
f(&i); // error: ambiguous
g(&i); // OK: calls #3
}
— end example ]— end note ]
14.5.7 Alias templates [temp.alias]
1Atemplate-declaration in which the declaration is an alias-declaration (Clause 7) declares the identifier to
be a alias template. An alias template is a name for a family of types. The name of the alias template is a
template-name.
2When 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 ]
3The 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 ]
14.6 Name resolution [temp.res]
1Three kinds of names can be used within a template definition:
The name of the template itself, and names declared within the template itself.
Names dependent on a template-parameter (14.6.2).
Names from scopes which are visible within the template definition.
§ 14.6 339
c
ISO/IEC N????
2A 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 Bdeclared 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:
// multiply T::A by a7; ill-formed,
// no visible declaration of a7
B* a8; // Bis not a type name:
// multiply Bby a8; ill-formed,
// no visible declarations of Band a8
}
};
— end example ]
3When a qualified-id is intended to refer to a type that is not a member of the current instantiation (14.6.2.1)
and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword typename, forming
atypename-specifier. If the qualified-id in a typename-specifier does not denote a type, the program is ill-
formed.
typename-specifier:
typename nested-name-specifier identifier
typename nested-name-specifier templateopt simple-template-id
4If 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, the specialization is ill-formed. The usual qualified name
lookup (3.4.3) 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
}
§ 14.6 340
c
ISO/IEC N????
— end example ]
5A qualified name used as the name in a mem-initializer-id, a base-specifier, 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 ]
6If, for a given set of template arguments, a specialization of a template is instantiated that refers to a
qualified-id that denotes a type, 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 ]
7Within 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. [ Note: such names can be found using unqualified name
lookup (3.4.1), class member lookup (3.4.3.1) into the current instantiation (14.6.2.1), or class member access
expression lookup (3.4.5) when the type of the object expression is the current instantiation (14.6.2.2). — end
note ] [ Example:
template<class T> struct A {
typedef int B;
B b; // OK, no typename required
};
— end example ]
8Knowing which names are type names allows the syntax of every template to be checked. No diagnostic
shall be issued for a template for which a valid specialization can be generated. If no valid specialization can
be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic
required. If every valid specialization of a variadic template requires an empty template parameter pack,
the template is ill-formed, no diagnostic required. If 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 done, and
if the completeness of that type affects whether or not the program is well-formed or affects the semantics of
the program, the program is ill-formed; no diagnostic is required. [ Note: If a template is instantiated, errors
will be diagnosed according to the other rules in this Standard. Exactly when these errors are diagnosed is
a quality of implementation issue. — end note ] [ Example:
int j;
template<class T> class X {
§ 14.6 341
c
ISO/IEC N????
void f(T t, int i, char* p) {
t = i; // diagnosed if X::f is instantiated
// and the assignment to tis 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 ]
9When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1,
3.4.2) are used for non-dependent names. The lookup of names dependent on the template parameters is
postponed until the actual template argument is known (14.6.2). [ 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, iis the local variable ideclared 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 Tis (14.6.2). — end example ]
10 If a name does not depend on a template-parameter (as defined in 14.6.2), 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
§ 14.6 342
c
ISO/IEC N????
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 ]
11 [Note: For purposes of name lookup, default arguments and exception-specifications of function templates
and default arguments and exception-specifications of member functions of class templates are considered
definitions (14.5). — end note ]
14.6.1 Locally declared names [temp.local]
1Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). 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 <>.
2Within 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 ]
3The 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
§ 14.6.1 343
c
ISO/IEC N????
— end example ]
4A lookup that finds an injected-class-name (10.2) 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 ]
5When 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 ]
6Atemplate-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 ]
7In 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
}
§ 14.6.1 344
c
ISO/IEC N????
— end example ]
8In 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; // Cis the template parameter, not N::C
}
— end example ]
9In 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 base class which does not depend on a template-parameter (14.6.2), 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 (3.3.10). [ 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 aisn’t a type name
};
— end example ]
14.6.2 Dependent names [temp.dep]
1Inside 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. Expressions may be type-dependent (on the type of a template
parameter) or value-dependent (on the value of a non-type template parameter). In an expression of the
form:
postfix-expression (expression-listopt )
where the postfix-expression is an unqualified-id, the unqualified-id denotes a dependent name if
any of the expressions in the expression-list is a pack expansion (14.5.3),
any of the expressions in the expression-list is a type-dependent expression (14.6.2.2), or
if the unqualified-id is a template-id in which any of the template arguments depends on a template
parameter.
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 (14.6.4.1) in both the
context of the template definition and the context of the point of instantiation.
2[Example:
§ 14.6.2 345
c
ISO/IEC N????
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 ]
3In the definition of a class or class template, if a base class depends on a template-parameter, the base class
scope 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; // ahas type double
};
The type name Ain 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 Bdefined 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 Ado not affect the binding of names in
Y<A>.— end example ]
14.6.2.1 Dependent types [temp.dep.type]
1A 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 9) 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
§ 14.6.2.1 346
c
ISO/IEC N????
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 (14.5.3) whose pattern is the name of the parameter pack.
2The 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 (14.5.3), the nth template argument is a pack expansion (14.5.3) whose pattern
is the name of the template parameter pack.
3A 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; // Ais 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; // Bis 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 ]
4A name is a member of the current instantiation if it is
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
§ 14.6.2.1 347
c
ISO/IEC N????
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 (5.2.5) for which the type
of the object expression is the current instantiation, and the id-expression, when looked up (3.4.5),
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]; // irefers 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; // irefers 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.
5A name is a member of an unknown specialization if it is
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 instan-
tiation 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 (5.2.5) 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.
6If 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
§ 14.6.2.1 348
c
ISO/IEC N????
// a member of an unknown specialization
}
};
— end example ]
7If, 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.
[Note: the result of name lookup differs only when the member of the current instantiation was found in a
non-dependent base class of the current instantiation and a member with the same name is also introduced
by the substitution for a dependent base class of the current instantiation. — end note ]
8A 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 constructed from any dependent type or whose size is specified by a constant expression
that 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
denoted by decltype(expression), where expression is type-dependent (14.6.2.2).
9[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 ]
14.6.2.2 Type-dependent expressions [temp.dep.expr]
1Except as described below, an expression is type-dependent if any subexpression is type-dependent.
2this is type-dependent if the class type of the enclosing member function is dependent (14.6.2.1).
3An id-expression is type-dependent if it contains
an identifier associated by name lookup with one or more declarations declared with a dependent type,
a template-id that is dependent,
a conversion-function-id that specifies a dependent type, or
a nested-name-specifier or a qualified-id that names a member of an unknown specialization;
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(14.5.1.3). 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:
§ 14.6.2.2 349
c
ISO/IEC N????
simple-type-specifier (expression-listopt )
::opt new new-placementopt new-type-id new-initializeropt
::opt new new-placementopt (type-id )new-initializeropt
dynamic_cast < type-id > ( expression )
static_cast < type-id > ( expression )
const_cast < type-id > ( expression )
reinterpret_cast < type-id > ( expression )
(type-id )cast-expression
4Expressions 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 )
::opt delete cast-expression
::opt delete [ ] cast-expression
throw assignment-expressionopt
noexcept ( expression )
[Note: For the standard library macro offsetof, see 18.2.— end note ]
5A class member access expression (5.2.5) 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 yof the class of x(or the class pointed to by xp).
However, if xor xp refers to a dependent type that is not the current instantiation, the type of yis always
dependent. If xor xp refers to a non-dependent type or refers to the current instantiation, the type of yis
the type of the class member access expression. — end note ]
14.6.2.3 Value-dependent expressions [temp.dep.constexpr]
1Except as described below, a constant expression is value-dependent if any subexpression is value-dependent.
2An id-expression is value-dependent if:
it is a name declared with a dependent type,
it is the name of a non-type template parameter,
it names a member of an unknown specialization,
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 )
§ 14.6.2.3 350
c
ISO/IEC N????
[Note: For the standard library macro offsetof, see 18.2.— end note ]
3Expressions of the following form are value-dependent if either the type-id or simple-type-specifier is depen-
dent or the expression or cast-expression is value-dependent:
simple-type-specifier (expression-listopt )
static_cast < type-id > ( expression )
const_cast < type-id > ( expression )
reinterpret_cast < type-id > ( expression )
(type-id )cast-expression
4Expressions of the following form are value-dependent:
sizeof ... ( identifier )
5An expression of the form &qualified-id where the qualified-id names a dependent member of the current
instantiation is value-dependent.
14.6.2.4 Dependent template arguments [temp.dep.temp]
1A type template-argument is dependent if the type it specifies is dependent.
2A non-type template-argument is dependent if its type is dependent or the constant expression it specifies
is value-dependent.
3Furthermore, 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.
4A 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.
14.6.3 Non-dependent names [temp.nondep]
1Non-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 ]
14.6.4 Dependent name resolution [temp.dep.res]
1In 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 (14.6.4.1) and from the definition context.
14.6.4.1 Point of instantiation [temp.point]
1For 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
§ 14.6.4.1 351
c
ISO/IEC N????
because it is referenced from within another template specialization and the context from which it is ref-
erenced 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.
2If 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.
3For an exception-specification of a function template specialization or specialization of a member function
of a class template, if the exception-specification 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 exception-specification is the point of instantiation of the specialization that requires it.
Otherwise, the point of instantiation for such an exception-specification immediately follows the namespace
scope declaration or definition that requires the exception-specification.
4For 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.
5If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of
instantiation of its enclosing class template specialization.
6An explicit instantiation definition is an instantiation point for the specialization or specializations specified
by the explicit instantiation.
7The 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.
8A 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 (3.2), the program is ill-formed, no diagnostic required.
14.6.4.2 Candidate functions [temp.dep.candidate]
1For a function call where the postfix-expression is a dependent name, the candidate functions are found using
the usual lookup rules (3.4.1,3.4.2) except that:
For the part of the lookup using unqualified name lookup (3.4.1), only function declarations from the
template definition context are found.
For the part of the lookup using associated namespaces (3.4.2), 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 name-
spaces 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.
§ 14.6.4.2 352
c
ISO/IEC N????
14.6.5 Friend names declared within a class template [temp.inject]
1Friend 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.
2As with non-template classes, the names of namespace-scope friend functions of a class template specializa-
tion are not visible during an ordinary lookup unless explicitly declared at namespace scope (11.3). Such
names may be found under the rules for associated classes (3.4.2).145 [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 ]
14.7 Template instantiation and specialization [temp.spec]
1The act of instantiating a function, a class, a member of a class template or a member template is referred
to as template instantiation.
2A 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.
3An 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
// Uis 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;
145) Friend declarations do not introduce new names into any scope, either when the template is declared or when it is
instantiated.
§ 14.7 353
c
ISO/IEC N????
};
template<> int B<>::x = 1; // specialize for T == int
— end example ]
4An instantiated template specialization can be either implicitly instantiated (14.7.1) for a given argument
list or be explicitly instantiated (14.7.2). A specialization is a class, function, or class member that is either
instantiated or explicitly specialized (14.7.3).
5For 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 3.2), 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.
6Each 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 sof type int and X<char*> has a static member sof type char*.— end
example ]
14.7.1 Implicit instantiation [temp.inst]
1Unless a class template specialization has been explicitly instantiated (14.7.2) or explicitly specialized (14.7.3),
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 se-
mantics of the program. The implicit instantiation of a class template specialization causes the implicit
instantiation of the declarations, but not of the definitions, default arguments, or exception-specifications of
the class member functions, member classes, scoped member enumerations, static data members and mem-
ber templates; 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 redecla-
ration of a member is valid according to 9.2, 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. — end example ]
2Unless 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
§ 14.7.1 354
c
ISO/IEC N????
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.
3Unless a function template specialization has been explicitly instantiated or explicitly specialized, the func-
tion template specialization is implicitly instantiated when the specialization 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.
4[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 ]
5Unless a variable template specialization has been explicitly instantiated or explicitly specialized, the vari-
able 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.
6A class template specialization is implicitly instantiated if the class type is used in a context that requires
a completely-defined object type or if the completeness of the class type might affect 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 conversion
between pointer to class types 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 ]
§ 14.7.1 355
c
ISO/IEC N????
7If the overload resolution process can determine the correct function to call 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 ]
8If an implicit instantiation of a class template specialization is required and the template is declared but not
defined, the program is ill-formed. [ Example:
template<class T> class X;
X<char> ch; // error: definition of Xrequired
— end example ]
9The implicit instantiation of a class template does not cause any static data members of that class to be
implicitly instantiated.
10 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 (14.8.3).
11 An implementation shall not implicitly instantiate a function template, a variable template, a member tem-
plate, a non-virtual member function, a member class, or a static data member of a class template that
does not require instantiation. 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 in-
stantiated. 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.
12 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) {
§ 14.7.1 356
c
ISO/IEC N????
int i = m.get("Nicholas");
}
a call of lt.get() from Map<const char*,int>::get() would place List<int>::get() in the name-
space Nrather than in the global namespace. — end example ]
13 If a function template fis 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. This analysis is called default argument instantiation. The instantiated default argument
is then used as the argument of f.
14 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 ]
15 The exception-specification of a function template specialization is not instantiated along with the function
declaration; it is instantiated when needed (15.4). If such an exception-specification 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 exception-specification is done as if it were being done as part of
instantiating the declaration of the specialization at that point.
16 [Note: 14.6.4.1 defines the point of instantiation of a template specialization. — end note ]
17 There is an implementation-defined quantity that specifies the limit on the total depth of recursive instan-
tiations, 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 ]
14.7.2 Explicit instantiation [temp.explicit]
1A 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.
2The syntax for explicit instantiation is:
explicit-instantiation:
externopt template declaration
There are two forms of explicit instantiation: an explicit instantiation definition and an explicit instan-
tiation declaration. An explicit instantiation declaration begins with the extern keyword.
§ 14.7.2 357
c
ISO/IEC N????
3If 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 (7.3.1), any namespace from its enclosing namespace
set. [ Note: Regarding qualified names in declarators, see 8.3.— 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 ]
4A 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 12),
the program is ill-formed.
5For 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.
6An 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 Ynot visible
// in the global namespace
using N::Y;
template class Y<int>; // error: explicit instantiation outside of the
// namespace of the template
§ 14.7.2 358
c
ISO/IEC N????
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 ]
7A 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 (14.8.2). [ 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 ]
8An 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 ]
9An 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.
10 Except for inline functions, declarations with types deduced from their initializer or return value (7.1.6.4),
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 (3.2) 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 ]
11 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 (14.7.1) in the translation unit shall be the subject of an explicit instantiation definition some-
where 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.
12 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 ]
13 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.
§ 14.7.2 359
c
ISO/IEC N????
— end example ]
14.7.3 Explicit specialization [temp.expl.spec]
1An 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 ]
2An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit
specialization whose declarator-id is not qualified shall be declared in the nearest enclosing namespace of
the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set. Such a
declaration may also be a definition. If the declaration is not a definition, the specialization may be defined
later (7.3.1.2).
3A 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: Xnot a template
template<class T> class X;
template<> class X<char*> { /... /}; // OK: Xis a template
§ 14.7.3 360
c
ISO/IEC N????
— end example ]
4A 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 12), the program is ill-formed.
5A 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();
};
§ 14.7.3 361
c
ISO/IEC N????
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 ]
6If a template, a member template or a member of a class template is explicitly specialized then that special-
ization 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>&),Tis 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 ]
7The placement of explicit specialization declarations for function templates, class templates, member func-
tions 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, member functions of member templates of class templates, member functions of mem-
ber 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, member class 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.
8A template explicit specialization is in the scope of the namespace in which the template was defined.
[Example:
namespace N {
§ 14.7.3 362
c
ISO/IEC 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 same namespace
— end example ]
9Asimple-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 (3.9). [ Example:
template<class T> class X; // Xis 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 ]
10 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 ]
11 A function with the same name as a template and a type that exactly matches that of a template special-
ization is not an explicit specialization (14.5.6).
12 An explicit specialization of a function template is inline only if it is declared with the inline specifier or
defined as deleted, and independently of whether its function 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 ]
13 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 ]
14 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
§ 14.7.3 363
c
ISO/IEC N????
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 ]
15 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 ]
16 In an explicit specialization declaration for a member of a class template or a member template that ap-
pears 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 en-
closing 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<> pre-
ceding 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>
§ 14.7.3 364
c
ISO/IEC N????
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 Ais not
— end example ]
17 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.
18 An explicit specialization declaration shall not be a friend declaration.
19 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 special-
ization 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 ]
14.8 Function template specializations [temp.fct.spec]
1A 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 14.8.2), or obtained from default template arguments.
2Each 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 sof type int and f<char*>(char**) has a static variable sof
type char*.— end example ]
14.8.1 Explicit template argument specification [temp.arg.explicit]
1Template 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>&)
}
§ 14.8.1 365
c
ISO/IEC N????
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 ]
2A 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.
3Trailing template arguments that can be deduced (14.8.2) or obtained from default template-arguments may
be omitted from the list of explicit template-arguments. A trailing template parameter pack (14.5.3) 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); // Yis deduced to be double
int j = f(5.6); // ill-formed: Xcannot be deduced
f<void>(f<int, bool>); // Yfor outer fdeduced 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); // Yis deduced to be double, Zis deduced to an empty sequence
f<void>(g<int, bool>); // Yfor outer fis deduced to be
// int (*)(bool),Zis deduced to an empty sequence
}
— end example ]
4[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 normal (i.e., non-template) function 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 ]
5Template 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
§ 14.8.1 366
c
ISO/IEC N????
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); // Zis deduced to be double
f<int>("aa",3.0); // Yis deduced to be const char*, and
// Zis deduced to be double
f("aa",3.0); // error: Xcannot be deduced
f2<char, short, int, long>(); // OK
}
— end example ]
6Implicit conversions (Clause 4) 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 ]
7[Note: Because the explicit template argument list follows the function template name, and because con-
version 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 ]
8[Note: For simple function names, argument dependent lookup (3.4.2) 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 (3.4.1). 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;
§ 14.8.1 367
c
ISO/IEC N????
f<3>(b); // well-formed because C::f is visible; then
// A::f is found by argument dependent lookup
}
— end example ]— end note ]
9Template 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 ]
14.8.2 Template argument deduction [temp.deduct]
1When 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 ]
2When 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 deduc-
tion 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 14.3.2, otherwise
type deduction fails.
The specified template argument values are substituted for the corresponding template parameters as
specified below.
3After this substitution is performed, the function parameter type adjustments described in 8.3.5 are per-
formed. [ 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:
§ 14.8.2 368
c
ISO/IEC N????
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),tis non const
f<int>(1);
// #2: function type is f(int),tis const
f<const int>(1);
// #3: function type is g(int),xis const
g<int>(1);
// #4: function type is g(int),xis const
g<const int>(1);
// #5: function type is h(int, const int*)
h<const int>(1,0);
}
— end example ]
4[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 ]
5The 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: Tcannot 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.
6At 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 tem-
plate 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.
7The 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
§ 14.8.2 369
c
ISO/IEC N????
in lexical order and stops when a condition that causes deduction to fail is encountered. [ Note: The equiva-
lent substitution in exception specifications is done only when the exception-specification 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 ]
8If 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 evaluation of the substituted types
and expressions can result in side effects such as the instantiation of class template specializations and/or
function template specializations, the generation of implicitly-defined functions, etc. Such side 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 ]
§ 14.8.2 370
c
ISO/IEC N????
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); // Adoes not contain a member Y
f<B>(0); // The Ymember of Bis not a type
g<C>(0); // The Nmember of Cis not a non-type
h<D>(0); // The TT member of Dis 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 Tis 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 1to int*
§ 14.8.2 371
c
ISO/IEC N????
— 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 (10.4).
— end note ]
9Except as described above, the use of an invalid value shall not cause type deduction to fail. [ Example:
In the following example 1000 is converted to signed char and results in an implementation-defined value
as specified in (4.7). In other words, both templates are considered even though 1000, when converted to
signed char, results in an implementation-defined value.
template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1>(0); // ambiguous
int i2 = f<1000>(0); // ambiguous
— end example ]
14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]
1Template argument deduction is done by comparing each function template parameter type (call it P) with
the type of the corresponding argument of the call (call it A) as described below. If removing references
and cv-qualifiers from Pgives std::initializer_list<P0>for some P0and the argument is an initializer
list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P0as a function
template parameter type and the initializer element as its argument. Otherwise, an initializer list argument
causes the parameter to be considered a non-deduced context (14.8.2.5). [ Example:
template<class T> void f(std::initializer_list<T>);
f({1,2,3}); // Tdeduced to int
f({1,"asdf"}); // error: Tdeduced to both int and const char*
template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T
— end example ] For a function parameter pack that occurs at the end of the parameter-declaration-list,
the type Aof each remaining argument of the call is compared with the type Pof 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. When a function parameter pack
appears in a non-deduced context (14.8.2.5), 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
}
§ 14.8.2.1 372
c
ISO/IEC N????
— end example ]
2If Pis not a reference type:
If Ais an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is
used in place of Afor type deduction; otherwise,
If Ais a function type, the pointer type produced by the function-to-pointer standard conversion (4.3)
is used in place of Afor type deduction; otherwise,
If Ais a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction.
3If Pis a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction. If Pis a
reference type, the type referred to by Pis used for type deduction. If Pis an rvalue reference to a cv-
unqualified template parameter and the argument is an lvalue, the type “lvalue reference to A” is used in
place of Afor type deduction. [ Example:
template <class T> int f(T&&);
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
— end example ]
4In general, the deduction process attempts to find template argument values that will make the deduced A
identical to A(after the type Ais transformed as described above). However, there are three cases that allow
a difference:
If the original Pis 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 Acan be another pointer or pointer to member type that can be converted to the
deduced Avia a qualification conversion (4.4).
If Pis a class and Phas the form simple-template-id, then the transformed Acan be a derived class of
the deduced A. Likewise, if Pis 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.
[Note: as specified in 14.8.1, implicit conversions will be performed on a function argument to convert
it to the type of the corresponding function parameter if the parameter contains no template-parameters
that participate in template argument deduction. Such conversions are also allowed, in addition to the ones
described in the preceding list. — end note ]
5These 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 ]
6When P is a function type, pointer to function 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
§ 14.8.2.1 373
c
ISO/IEC N????
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.
7[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 ]
8[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 ]
9[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 ]
14.8.2.2 Deducing template arguments taking the address of a function template
[temp.deduct.funcaddr]
1Template arguments can be deduced from the type specified when taking the address of an overloaded
function (13.4). The function template’s function type and the specified type are used as the types of Pand
A, and the deduction is done as described in 14.8.2.5.
14.8.2.3 Deducing conversion function template arguments [temp.deduct.conv]
1Template 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 8.5,13.3.1.5, and 13.3.1.6
for the determination of that type) as described in 14.8.2.5.
2If Pis a reference type, the type referred to by Pis used in place of Pfor type deduction and for any further
references to or transformations of Pin the remainder of this section.
3If Ais not a reference type:
If Pis an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is
used in place of Pfor type deduction; otherwise,
If Pis a function type, the pointer type produced by the function-to-pointer standard conversion (4.3)
is used in place of Pfor type deduction; otherwise,
If Pis a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction.
§ 14.8.2.3 374
c
ISO/IEC N????
4If Ais a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction. If Ais a
reference type, the type referred to by Ais used for type deduction.
5In general, the deduction process attempts to find template argument values that will make the deduced A
identical to A. However, there are two cases that allow a difference:
If the original Ais a reference type, Acan be more cv-qualified than the deduced A(i.e., the type
referred to by the reference)
The deduced Acan be another pointer or pointer to member type that can be converted to Avia a
qualification conversion.
6These alternatives are considered only if type deduction would otherwise fail. If they yield more than one
possible deduced A, the type deduction fails.
7When 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 Ais a type
cv1,0“pointer to . . .cv1,n1“pointer to” cv1,nT1
and Pis a type
cv2,0“pointer to . . .cv2,n1“pointer to” cv2,nT2
The cv-unqualified T1 and T2 are used as the types of Aand Prespectively for type deduction. [ Example:
struct A {
template <class T> operator T***();
};
A a;
const int * const * const * p1 = a; // Tis deduced as int, not const int
— end example ]
14.8.2.4 Deducing template arguments during partial ordering [temp.deduct.partial]
1Template argument deduction is done by comparing certain types associated with the two function templates
being compared.
2Two 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 14.5.6.2.— 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.
3The 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.146
In the context of a call to a conversion function, the return types of the conversion function templates
are used.
In other contexts (14.5.6.2) the function template’s function type is used.
146) Default arguments are not considered to be arguments in this context; they only become arguments after a function has
been selected.
§ 14.8.2.4 375
c
ISO/IEC N????
4Each type nominated above from the parameter template and the corresponding type from the argument
template are used as the types of Pand A.
5Before the partial ordering is done, certain transformations are performed on the types used for partial
ordering:
If Pis a reference type, Pis replaced by the type referred to.
If Ais a reference type, Ais replaced by the type referred to.
6If both Pand Awere 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.
7Remove any top-level cv-qualifiers:
If Pis a cv-qualified type, Pis replaced by the cv-unqualified version of P.
If Ais a cv-qualified type, Ais replaced by the cv-unqualified version of A.
8If Awas transformed from a function parameter pack and Pis not a parameter pack, type deduction fails.
Otherwise, using the resulting types Pand A, the deduction is then done as described in 14.8.2.5. If P
is a function parameter pack, the type Aof each remaining parameter type of the argument template is
compared with the type Pof 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. 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 ]
9If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transfor-
mations above) and both Pand Awere 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 argument type is considered to be more specialized than the other; otherwise,
if the type from the argument template is more cv-qualified than the type from the parameter template
(as described above), the argument type is considered to be more specialized than the other; otherwise,
neither type is more specialized than the other.
10 If for each type being considered a given template is at least as specialized for all types and more specialized
for some set of types and the other template is not more specialized for any types or is not at least as
specialized for any types, then the given template is more specialized than the other template. Otherwise,
neither template is more specialized than the other.
11 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:
§ 14.8.2.4 376
c
ISO/IEC N????
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 ]
12 [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 ]
14.8.2.5 Deducing template arguments from a type [temp.deduct.type]
1Template 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.
2In some cases, the deduction is done using a single set of types Pand A, in other cases, there will be a set
of corresponding types Pand 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.
3A given type Pcan 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.
4In most cases, the types, templates, and non-type values that are used to compose Pparticipate 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.
5The non-deduced contexts are:
The nested-name-specifier of a type that was specified using a qualified-id.
§ 14.8.2.5 377
c
ISO/IEC N????
The expression of a decltype-specifier.
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 (13.4), and one or more of the following apply:
more than one function matches the function parameter type (resulting in an ambiguous deduc-
tion), 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 (8.5.4) but the parameter
does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list
type. [ 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-clause.
6When 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 Tand T2 are non-deduced. Likewise, if a type is
specified as A<I+J>::X<T>,I,J, and Tare non-deduced. If a type is specified as void f(typename A<T>::B,
A<T>), the Tin A<T>::B is non-deduced but the Tin A<T> is deduced. — end example ]
7[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: Tcould be Aor B
f(b,a); // error: Tcould be Aor B
f(a,a); // OK: Tis A
f(b,b); // OK: Tis B
}
Here is an example where two template arguments are deduced from a single function parameter/argu-
ment 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: Tis int and Uis float
§ 14.8.2.5 378
c
ISO/IEC N????
f(g2); // error: Tcould be char or int
f(g3); // error: Ucould 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 ]
8A template type argument T, a template template argument TT or a template non-type argument ican be
deduced if Pand Ahave 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)
Ttype ::*
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<>
§ 14.8.2.5 379
c
ISO/IEC N????
where (T) represents a parameter-type-list 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 iand <> represents template argument lists where no argument contains a
Tor an i.
9If Phas a form that contains <T> or <i>, then each argument Piof the respective template argument list
Pis compared with the corresponding argument Aiof the corresponding template argument list of A. If
the template argument list of Pcontains a pack expansion that is not the last template argument, the
entire template argument list is a non-deduced context. If Piis a pack expansion, then the pattern of Pi
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 Pi. During
partial ordering (14.8.2.4), if Aiwas originally a pack expansion:
if Pdoes not contain a template argument corresponding to Aithen Aiis ignored;
otherwise, if Piis 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 ]
10 Similarly, if Phas a form that contains (T), then each parameter type Piof the respective parameter-type-
list of Pis compared with the corresponding parameter type Aiof the corresponding parameter-type-list
of A. If Pand Aare function types that originated from deduction when taking the address of a function
template (14.8.2.2) or when deducing template arguments from a function declaration (14.8.2.6) and Piand
Aiare parameters of the top-level parameter-type-list of Pand A, respectively, Piis adjusted if it is an rvalue
reference to a cv-unqualified template parameter and Aiis an lvalue reference, in which case the type of Pi
is changed to be the template parameter type (i.e., T&& is changed to simply T). [ Note: As a result, when Pi
is T&& and Aiis X&, the adjusted Piwill be T, causing Tto 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 Piis 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 compar-
ison deduces template arguments for subsequent positions in the template parameter packs expanded by the
function parameter pack. During partial ordering (14.8.2.4), if Aiwas originally a function parameter pack:
if Pdoes not contain a function parameter type corresponding to Aithen Aiis ignored;
otherwise, if Piis not a function parameter pack, template argument deduction fails.
§ 14.8.2.5 380
c
ISO/IEC N????
[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 ]
11 These forms can be used in the same way as Tis 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 Tis char[6].— end example ]
12 Template arguments cannot be deduced from function arguments involving constructs other than the ones
specified above.
13 A template type argument cannot be deduced from the type of a non-type template-argument.
14 [Example:
template<class T, T i> void f(double a[10][i]);
int v[10][20];
f(v); // error: argument for template-parameter Tcannot be deduced
— end example ]
15 [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: ideduced to be 20
f1<20>(v); // OK
f2(v); // error: cannot deduce template-argument i
f2<10>(v); // OK
f3(v); // OK: ideduced to be 10
}
16 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
}
§ 14.8.2.5 381
c
ISO/IEC N????
— end example ]— end note ] [ Note: Template parameters do not participate in template argument deduc-
tion if they are used only in non-deduced contexts. For example,
template<int i, typename T>
T deduce(typename A<T>::X x, // Tis not deduced here
T t, // but Tis deduced here
typename B<i>::Y y); // iis not deduced here
A<int> a;
B<77> b;
int x = deduce<77>(a.xm, 62, b.ym);
// Tis deduced to be int,a.xm must be convertible to
// A<int>::X
// iis explicitly specified to be 77,b.ym must be convertible
// to B<77>::Y
— end note ]
17 If, in the declaration of a function template with a non-type template-parameter, the non-type template-
parameter is used in an expression in the function parameter-list and, if the corresponding template-argument
is deduced, the template-argument type shall match the type of the template-parameter exactly, except that
atemplate-argument deduced from an array bound may be of any integral type.147 [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 ]
18 Atemplate-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
}
147) 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 non-zero.
§ 14.8.2.5 382
c
ISO/IEC N????
— end example ]
19 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 ]
20 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 ]
21 [Note: Template argument deduction involving parameter packs (14.5.3) 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; Tis 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 ]
14.8.2.6 Deducing template arguments from a function declaration [temp.deduct.decl]
1In 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 (14.7.2), explicit specializations (14.7.3), and certain friend declarations (14.5.4).
This is also done to determine whether a deallocation function template specialization matches a placement
operator new (3.7.4.2,5.3.4). In all these cases, Pis the type of the function template being considered
as a potential match and Ais either the function type from the declaration or the type of the deallocation
function that would match the placement operator new as described in 5.3.4. The deduction is done as
described in 14.8.2.5.
2If, for the set of function templates so considered, there is either no match or more than one match after
partial ordering has been considered (14.5.6.2), deduction fails and, in the declaration cases, the program is
ill-formed.
14.8.3 Overload resolution [temp.over]
1A function template can be overloaded either by (non-template) functions of its name or by (other) function
§ 14.8.3 383
c
ISO/IEC N????
templates of the same name. When a call to that name is written (explicitly, or implicitly using the operator
notation), template argument deduction (14.8.2) and checking of any explicit template arguments (14.3) 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, 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 13.3.3.148
[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)
}
2Adding 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.
3Here 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)
}
4Here is an example involving conversions on a function argument not involved in template-parameter deduc-
tion:
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))
}
148) 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 13.3.3 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.
§ 14.8.3 384
c
ISO/IEC N????
— end example ]
5Only 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*>
}
6The call of fis well-formed even if the template fis 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 ]
§ 14.8.3 385
c
ISO/IEC N????
15 Exception handling [except]
1Exception 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.
try-block:
try compound-statement handler-seq
function-try-block:
try ctor-initializeropt compound-statement handler-seq
handler-seq:
handler handler-seqopt
handler:
catch ( exception-declaration )compound-statement
exception-declaration:
attribute-specifier-seqopt type-specifier-seq declarator
attribute-specifier-seqopt type-specifier-seq abstract-declaratoropt
...
throw-expression:
throw assignment-expressionopt
The optional attribute-specifier-seq in an exception-declaration appertains to the formal parameter of the
catch clause (15.3).
2Atry-block is a statement (Clause 6). A throw-expression is of type void. [ Note: Within this Clause “try
block” is taken to mean both try-block and function-try-block.— end note ]
3Agoto 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;
Exception handling 386
c
ISO/IEC N????
} 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 raised while destroying t2 will result in executing handler 2 ; any exception raised
while destroying t1 will result in executing handler 1.— end example ]
4Afunction-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 ]
15.1 Throwing an exception [except.throw]
1Throwing an exception transfers control to a handler. [ Note: An exception can be thrown from one of
the following contexts: throw-expression (see below), allocation functions (3.7.4.1), dynamic_cast (5.2.7),
typeid (5.2.8), new-expression (5.3.4), array of runtime bound (8.3.4), and standard library functions (17.5.1.4).
— 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);
}
§ 15.1 387
c
ISO/IEC N????
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 ]
2When an exception is thrown, control is transferred to the nearest handler with a matching type (15.3);
“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.
3Throwing an exception copy-initializes (8.5,12.8) a temporary object, called the exception object. The
temporary is an lvalue and is used to initialize the variable named in the matching handler (15.3). If the
type of the exception object would be an incomplete type or a pointer to an incomplete type other than
(possibly cv-qualified) void the program is ill-formed. Evaluating a throw-expression with an operand throws
an exception; 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 returning T” to “pointer to
T” or “pointer to function returning T,” respectively.
4The memory for the exception object is allocated in an unspecified way, except as noted in 3.7.4.1. If a
handler exits by rethrowing, control is passed to another handler for the same exception. The exception
object is destroyed after either the last remaining active handler for the exception exits by any means other
than rethrowing, or the last object of type std::exception_ptr (18.8.5) that refers to the exception object is
destroyed, whichever is later. In the former case, the destruction occurs when the handler exits, immediately
after the destruction of the object declared in the exception-declaration in the handler, if any. In the latter
case, the destruction occurs before the destructor of std::exception_ptr returns. 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 18.8.5 and 30.6.— end note ]
5When the thrown object is a class object, the constructor selected for the copy-initialization and the de-
structor shall be accessible, even if the copy/move operation is elided (12.8).
6An exception is considered caught when a handler for that exception becomes active (15.3). [ Note: An
exception can have active handlers and still be considered uncaught if it is rethrown. — end note ]
7If the exception handling mechanism, after completing the initialization of the exception object but before
the activation of a handler for the exception, calls a function that exits via an exception, std::terminate
is called (15.5.1). [ Example:
struct C {
C() { }
C(const C&) {
if (std::uncaught_exception()) {
throw 0; // throw during copy to handler’s exception-declaration object (15.3)
}
}
};
int main() {
try {
throw C(); // calls std::terminate() if construction of the handler’s
// exception-declaration object is not elided (12.8)
} catch(C) { }
}
— end example ]
§ 15.1 388
c
ISO/IEC N????
8Athrow-expression with no operand rethrows the currently handled exception (15.3). The exception is
reactivated with the existing exception object; no new exception object is created. The exception is no
longer considered to be caught; therefore, the value of std::uncaught_exception() will again be true.
[Example: code that must be executed because of an exception yet cannot completely handle the exception
can be written like this:
try {
// ...
} catch (...) { // catch all exceptions
// respond (partially) to exception
throw; // pass the exception to some
// other handler
}
— end example ]
9If no exception is presently being handled, executing a throw-expression with no operand calls std::
terminate() (15.5.1).
15.2 Constructors and destructors [except.ctor]
1As control passes from the point where an exception is thrown to a handler, destructors are invoked for all
automatic objects constructed since the try block was entered. The automatic objects are destroyed in the
reverse order of the completion of their construction.
2An object of any storage duration whose initialization or destruction is terminated by an exception will
have destructors executed for all of its fully constructed subobjects (excluding the variant members of a
union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution
and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object
has completed execution and a delegating constructor for that object exits with an exception, the object’s
destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation
function (3.7.4.2,5.3.4,12.5), if any, is called to free the storage occupied by the object.
3The process of calling destructors for automatic objects constructed on the path from a try block to the
point where an exception is thrown is called “stack unwinding. If a destructor called during stack unwinding
exits with an exception, std::terminate is called (15.5.1). [ Note: So destructors should generally catch
exceptions and not let them propagate out of the destructor. — end note ]
15.3 Handling an exception [except.handle]
1The 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*.
2A handler of type “array of T” or “function returning T” is adjusted to be of type “pointer to T” or “pointer
to function returning T”, respectively.
3Ahandler is a match for an exception object of type Eif
The handler is of type cv Tor cv T& and Eand Tare the same type (ignoring the top-level cv-qualifiers),
or
the handler is of type cv Tor cv T& and Tis an unambiguous public base class of E, or
the handler is of type cv Tor const T& where Tis a pointer type and Eis a pointer type that can be
converted to Tby either or both of
a standard pointer conversion (4.10) not involving conversions to pointers to private or protected
or ambiguous classes
a qualification conversion
§ 15.3 389
c
ISO/IEC N????
the handler is of type cv Tor const T& where Tis a pointer or pointer to member type and Eis
std::nullptr_t.
[Note: Athrow-expression whose operand is an integer literal with value zero does not match a handler
of pointer or pointer to member type. — 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 ]
4The handlers for a try block are tried in order of appearance. That makes it possible to write handlers that
can never be executed, for example by placing a handler for a derived class after a handler for a corresponding
base class.
5A... 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.
6If 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.
7A handler is considered active when initialization is complete for the formal 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() or std::unexpected() is entered due to a throw. A handler
is no longer considered active when the catch clause exits or when std::unexpected() exits after being
entered due to a throw.
8The exception with the most recently activated handler that is still active is called the currently handled
exception.
9If 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 (15.5.1).
10 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.
11 The fully constructed base classes and members of an object shall be destroyed before entering the handler
of a function-try-block of a constructor for that object. Similarly, if a delegating constructor for an object
exits with an exception after the non-delegating constructor for that object has completed execution, the
object’s destructor shall be executed before entering the handler of a function-try-block of a constructor for
that object. The base classes and non-variant members of an object shall be destroyed before entering the
handler of a function-try-block of a destructor for that object (12.4).
12 The scope and lifetime of the parameters of a function or constructor extend into the handlers of a function-
try-block.
13 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 main(). Exceptions
§ 15.3 390
c
ISO/IEC N????
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.
14 If a return statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.
15 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, a function returns when control reaches the end of a handler for
the function-try-block (6.6.3). Flowing off the end of a function-try-block is equivalent to a return with no
value; this results in undefined behavior in a value-returning function (6.6.3).
16 If the exception-declaration specifies a name, it declares a variable which is copy-initialized (8.5) from the
exception object. If the exception-declaration denotes an object type but does not specify a name, a tem-
porary (12.2) is copy-initialized (8.5) from the exception object. The lifetime of the variable or temporary
ends when the handler exits, after the destruction of any automatic objects initialized within the handler.
17 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.
15.4 Exception specifications [except.spec]
1A function declaration lists exceptions that its function might directly or indirectly throw by using an
exception-specification as a suffix of its declarator.
exception-specification:
dynamic-exception-specification
noexcept-specification
dynamic-exception-specification:
throw ( type-id-listopt )
type-id-list:
type-id ...opt
type-id-list ,type-id ...opt
noexcept-specification:
noexcept ( constant-expression )
noexcept
In a noexcept-specification, the constant-expression, if supplied, shall be a constant expression (5.19) that
is contextually converted to bool (Clause 4). A noexcept-specification noexcept is equivalent to noexcept(
true).
2An exception-specification shall appear only on a function declarator for a function type, pointer to function
type, reference to function type, or pointer to member function type that is the top-level type of a declaration
or definition, or on such a type appearing as a parameter or return type in a function declarator. An
exception-specification shall not appear in a typedef declaration or alias-declaration. [ Example:
void f() throw(int); // OK
void (*fp)() throw (int); // OK
void g(void pfa() throw(int)); // OK
typedef int (*pf)() throw(int); // ill-formed
— end example ]
A type denoted in an exception-specification shall not denote an incomplete type or an rvalue reference
type. A type denoted in an exception-specification shall not denote a pointer or reference to an incomplete
type, other than cv void*. A type cv T, “array of T”, or “function returning T” denoted in an exception-
specification is adjusted to type T, “pointer to T”, or “pointer to function returning T”, respectively.
3Two exception-specifications are compatible if:
both are non-throwing (see below), regardless of their form,
both have the form noexcept(constant-expression)and the constant-expressions are equivalent, or
both are dynamic-exception-specifications that have the same set of adjusted types.
§ 15.4 391
c
ISO/IEC N????
4If any declaration of a function has an exception-specification that is not a noexcept-specification allowing
all exceptions, all declarations, including the definition and any explicit specialization, of that function shall
have a compatible exception-specification. If any declaration of a pointer to function, reference to function,
or pointer to member function has an exception-specification, all occurrences of that declaration shall have
a compatible exception-specification In an explicit instantiation an exception-specification may be specified,
but is not required. If an exception-specification is specified in an explicit instantiation directive, it shall be
compatible with the exception-specifications of other declarations of that function. A diagnostic is required
only if the exception-specifications are not compatible within a single translation unit.
5If a virtual function has an exception-specification, all declarations, including the definition, of any function
that overrides that virtual function in any derived class shall only allow exceptions that are allowed by the
exception-specification of the base class virtual function. [ Example:
struct B {
virtual void f() throw (int, double);
virtual void g();
};
struct D: B {
void f(); // ill-formed
void g() throw (int); // OK
};
The declaration of D::f is ill-formed because it allows all exceptions, whereas B::f allows only int and
double.— end example ] A similar restriction applies to assignment to and initialization of pointers to
functions, pointers to member functions, and references to functions: the target entity shall allow at least
the exceptions allowed by the source value in the assignment or initialization. [ Example:
class A { /... /};
void (*pf1)(); // no exception specification
void (*pf2)() throw(A);
void f() {
pf1 = pf2; // OK: pf1 is less restrictive
pf2 = pf1; // error: pf2 is more restrictive
}
— end example ]
6In such an assignment or initialization, exception-specifications on return types and parameter types shall
be compatible. In other assignments or initializations, exception-specifications shall be compatible.
7An exception-specification can include the same type more than once and can include classes that are related
by inheritance, even though doing so is redundant. [ Note: An exception-specification can also include the
class std::bad_exception (18.8.2). — end note ]
8A function is said to allow an exception of type Eif the constant-expression in its noexcept-specification
evaluates to false or its dynamic-exception-specification contains a type Tfor which a handler of type T
would be a match (15.3) for an exception of type E.
9Whenever an exception is thrown and the search for a handler (15.3) encounters the outermost block of a
function with an exception-specification that does not allow the exception, then,
if the exception-specification is a dynamic-exception-specification, the function std::unexpected() is
called (15.5.2),
otherwise, the function std::terminate() is called (15.5.1).
[Example:
§ 15.4 392
c
ISO/IEC N????
class X { };
class Y { };
class Z: public X { };
class W { };
void f() throw (X, Y) {
int n = 0;
if (n) throw X(); // OK
if (n) throw Z(); // also OK
throw W(); // will call std::unexpected()
}
— end example ]
[Note: A function can have multiple declarations with different non-throwing exception-specifications;
for this purpose, the one on the function definition is used. — end note ]
10 The function unexpected() may throw an exception that will satisfy the exception-specification for which
it was invoked, and in this case the search for another handler will continue at the call of the function with
this exception-specification (see 15.5.2), or it may call std::terminate().
11 An implementation shall not reject an expression merely because when executed it throws or might throw
an exception that the containing function does not allow. [ Example:
extern void f() throw(X, Y);
void g() throw(X) {
f(); // OK
}
the call to fis well-formed even though when called, fmight throw exception Ythat gdoes not allow.
— end example ]
12 A function with no exception-specification or with an exception-specification of the form noexcept(constant-
expression )where the constant-expression yields false allows all exceptions. An exception-specification is
non-throwing if it is of the form throw(),noexcept, or noexcept(constant-expression )where the constant-
expression yields true. A function with a non-throwing exception-specification does not allow any exceptions.
13 An exception-specification is not considered part of a function’s type.
14 An inheriting constructor (12.9) and an implicitly declared special member function (Clause 12) have an
exception-specification. If fis an inheriting constructor or an implicitly declared default constructor, copy
constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its im-
plicit exception-specification specifies the type-id Tif and only if Tis allowed by the exception-specification
of a function directly invoked by f’s implicit definition; fallows all exceptions if any function it directly
invokes allows all exceptions, and fhas the exception-specification noexcept(true) if every function it di-
rectly invokes allows no exceptions. [ Note: It follows that fhas the exception-specification noexcept(true)
if it invokes no other functions. — end note ] [ Note: An instantiation of an inheriting constructor tem-
plate has an implied exception-specification as if it were a non-template inheriting constructor. — end note ]
[Example:
struct A {
A();
A(const A&) throw();
A(A&&) throw();
~A() throw(X);
};
struct B {
B() throw();
B(const B&) = default; // Declaration of B::B(const B&) noexcept(true)
B(B&&) throw(Y);
§ 15.4 393
c
ISO/IEC N????
~B() throw(Y);
};
struct D : public A, public B {
// Implicit declaration of D::D();
// Implicit declaration of D::D(const D&) noexcept(true);
// Implicit declaration of D::D(D&&) throw(Y);
// Implicit declaration of D::D() throw(X, Y);
};
Furthermore, if A::˜A() or B::˜B() were virtual, D::˜D() would not be as restrictive as that of A::˜A,
and the program would be ill-formed since a function that overrides a virtual function from a base class shall
have an exception-specification at least as restrictive as that in the base class. — end example ]
15 A deallocation function (3.7.4.2) with no explicit exception-specification is treated as if it were specified with
noexcept(true).
16 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 (3.4,13.3,13.4);
the function is odr-used (3.2) 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 exception-specification 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 exception-specification of a specialization of a function template or member
function of a class template is instantiated only when needed.
17 In a dynamic-exception-specification, a type-id followed by an ellipsis is a pack expansion (14.5.3).
18 [Note: The use of dynamic-exception-specifications is deprecated (see Annex D). — end note ]
15.5 Special functions [except.special]
1The functions std::terminate() (15.5.1) and std::unexpected() (15.5.2) are used by the exception han-
dling mechanism for coping with errors related to the exception handling mechanism itself. The function
std::current_exception() (18.8.5) and the class std::nested_exception (18.8.6) can be used by a pro-
gram to capture the currently handled exception.
15.5.1 The std::terminate() function [except.terminate]
1In some situations exception handling must be abandoned for less subtle error handling techniques. [ Note:
These situations are:
when the exception handling mechanism, after completing the initialization of the exception object
but before activation of a handler for the exception (15.1), calls a function that exits via an exception,
or
when the exception handling mechanism cannot find a handler for a thrown exception (15.3), or
§ 15.5.1 394
c
ISO/IEC N????
when the search for a handler (15.3) encounters the outermost block of a function with a noexcept-
specification that does not allow the exception (15.4), or
when the destruction of an object during stack unwinding (15.2) terminates by throwing an exception,
or
when initialization of a non-local variable with static or thread storage duration (3.6.2) exits via an
exception, or
when destruction of an object with static or thread storage duration exits via an exception (3.6.3), or
when execution of a function registered with std::atexit or std::at_quick_exit exits via an ex-
ception (18.5), or
when a throw-expression with no operand attempts to rethrow an exception and no exception is being
handled (15.1), or
when std::unexpected throws an exception which is not allowed by the previously violated dynamic-
exception-specification, and std::bad_exception is not included in that dynamic-exception-specifica-
tion (15.5.2), or
when the implementation’s default unexpected exception handler is called (D.11.1), or
when the function std::nested_exception::rethrow_nested is called for an object that has captured
no exception (18.8.6), or
when execution of the initial function of a thread exits via an exception (30.3.1.2), or
when the destructor or the copy assignment operator is invoked on an object of type std::thread
that refers to a joinable thread (30.3.1.3,30.3.1.4).
— end note ]
2In such cases, std::terminate() is called (18.8.3). 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 (15.3) encounters the outermost block of a function with a
noexcept-specification that does not allow the exception (15.4), 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().
15.5.2 The std::unexpected() function [except.unexpected]
1If a function with a dynamic-exception-specification throws an exception that is not listed in the dynamic-
exception-specification, the function std::unexpected() is called (D.11) immediately after completing the
stack unwinding for the former function.
2[Note: By default, std::unexpected() calls std::terminate(), but a program can install its own handler
function (D.11.2). In either case, the constraints in the following paragraph apply. — end note ]
3The std::unexpected() function shall not return, but it can throw (or re-throw) an exception. If it
throws a new exception which is allowed by the exception specification which previously was violated, then
the search for another handler will continue at the call of the function whose exception specification was
violated. If it throws or rethrows an exception that the dynamic-exception-specification does not allow
then the following happens: If the dynamic-exception-specification does not include the class std::bad_-
exception (18.8.2) then the function std::terminate() is called, otherwise the thrown exception is replaced
by an implementation-defined object of the type std::bad_exception and the search for another handler
will continue at the call of the function whose dynamic-exception-specification was violated.
§ 15.5.2 395
c
ISO/IEC N????
4Thus, a dynamic-exception-specification guarantees that only the listed exceptions will be thrown. If the
dynamic-exception-specification includes the type std::bad_exception then any exception not on the list
may be replaced by std::bad_exception within the function std::unexpected().
15.5.3 The std::uncaught_exception() function [except.uncaught]
1The function std::uncaught_exception() returns true after completing the initialization of the exception
object (15.1) until completing the activation of a handler for the exception (15.3,18.8.4). This includes stack
unwinding. If the exception is rethrown (15.1), std::uncaught_exception() returns true from the point
of rethrow until the rethrown exception is caught again.
§ 15.5.3 396
c
ISO/IEC N????
16 Preprocessing directives [cpp]
1Apreprocessing 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.149 A new-line character ends the preprocessing
directive even if it occurs within what would otherwise be an invocation of a function-like macro.
preprocessing-file:
groupopt
group:
group-part
group group-part
group-part:
if-section
control-line
text-line
# non-directive
if-section:
if-group elif-groupsopt else-groupopt endif-line
if-group:
# if constant-expression new-line groupopt
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
elif-groups:
elif-group
elif-groups elif-group
elif-group:
# elif constant-expression new-line groupopt
else-group:
# else new-line groupopt
endif-line:
# endif new-line
control-line:
# include pp-tokens new-line
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt )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-tokensopt new-line
# pragma pp-tokensopt new-line
#new-line
text-line:
pp-tokensopt new-line
149) 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 16.3.2,
for example).
Preprocessing directives 397
c
ISO/IEC N????
non-directive:
pp-tokens new-line
lparen:
a(character not immediately preceded by white-space
identifier-list:
identifier
identifier-list ,identifier
replacement-list:
pp-tokensopt
pp-tokens:
preprocessing-token
pp-tokens preprocessing-token
new-line:
the new-line character
2A text line shall not begin with a #preprocessing token. A non-directive shall not begin with any of the
directive names appearing in the syntax.
3When in a group that is skipped (16.1), the directive syntax is relaxed to allow any sequence of preprocessing
tokens to occur between the directive name and the following new-line character.
4The 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).
5The 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.
6The 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 ]
16.1 Conditional inclusion [cpp.cond]
1The expression that controls conditional inclusion shall be an integral constant expression except that iden-
tifiers (including those lexically identical to keywords) are interpreted as described below150 and it may
contain unary operator expressions of the form
defined identifier
or
defined ( identifier )
which evaluate to 1if 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), 0if it is not.
2Each 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 (2.7).
3Preprocessing directives of the forms
# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt
150) 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.
§ 16.1 398
c
ISO/IEC N????
check whether the controlling constant expression evaluates to nonzero.
4Prior 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 the defined unary operator
have been performed, all remaining identifiers and keywords151, except for true and false, are replaced
with the pp-number 0, and then each preprocessing token is converted into a token. The resulting tokens
comprise the controlling constant expression which is evaluated according to the rules of 5.19 using arithmetic
that has at least the ranges specified in 18.3. 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 (18.4).152 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.153 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.
5Preprocessing directives of the forms
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
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.
6Each 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. 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.154
16.2 Source file inclusion [cpp.include]
1A#include directive shall identify a header or source file that can be processed by the implementation.
2A 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.
3A 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
151) An alternative token (2.6) is not an identifier, even when its spelling consists entirely of letters and underscores. Therefore
it is not subject to this replacement.
152) 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 (2.2).
153) 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)
154) 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.
§ 16.2 399
c
ISO/IEC N????
# include < h-char-sequence>new-line
with the identical contained sequence (including >characters, if any) from the original directive.
4A 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 (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.155 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.
5The implementation shall provide unique mappings for sequences consisting of one or more nondigits or
digits (2.11) followed by a period (.) and a single nondigit. The first character shall not be a digit. The
implementation may ignore distinctions of alphabetical case.
6A#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.
7[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 implementa-
tion, 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 ]
8[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 ]
16.3 Macro replacement [cpp.replace]
1Two 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.
2An identifier currently defined as an object-like macro 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 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.
3There shall be white-space between the identifier and the replacement list in the definition of an object-like
macro.
4If 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
155) Note that adjacent string literals are not concatenated into a single string literal (see the translation phases in 2.2); thus,
an expansion that results in two string literals is an invalid directive.
§ 16.3 400
c
ISO/IEC N????
than there are parameters in the macro definition (excluding the ...). There shall exist a )preprocessing
token that terminates the invocation.
5The identifier _ _ VA_ARGS _ _ shall occur only in the replacement-list of a function-like macro that uses the
ellipsis notation in the parameters.
6A parameter identifier in a function-like macro shall be uniquely declared within its scope.
7The 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.
8If 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.
9A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name156 to be replaced
by the replacement list of preprocessing tokens that constitute the remainder of the directive.157 The
replacement list is then rescanned for more macro names as specified below.
10 A preprocessing directive of the form
# define identifier lparen identifier-listopt )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 subse-
quent 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.
11 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,158 the behavior is undefined.
12 If there is a ... immediately preceding the )in the function-like macro definition, then the trailing argu-
ments, 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 ...).
16.3.1 Argument substitution [cpp.subst]
1After 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.
156) Since, by macro-replacement time, all character literals and string literals are preprocessing tokens, not sequences possibly
containing identifier-like subsequences (see 2.2, translation phases), they are never scanned for macro names or parameters.
157) An alternative token (2.6) 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.
158) Despite the name, a non-directive is a preprocessing directive.
§ 16.3.1 401
c
ISO/IEC N????
2An 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.
16.3.2 The #operator [cpp.stringize]
1Each #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.
2Acharacter string literal is a string-literal with no prefix. 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.
16.3.3 The ## operator [cpp.concat]
1A## preprocessing token shall not occur at the beginning or at the end of a replacement list for either form
of macro definition.
2If, 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.159
3For 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 prepro-
cessing 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"
159) Placemarker preprocessing tokens do not appear in the syntax because they are temporary entities that exist only within
translation phase 4.
§ 16.3.3 402
c
ISO/IEC N????
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 ]
16.3.4 Rescanning and further replacement [cpp.rescan]
1After 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.
2If 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 prepro-
cessing 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.
3The 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 16.9 below.
16.3.5 Scope of macro definitions [cpp.scope]
1A macro definition lasts (independent of block structure) until a corresponding #undef directive is encoun-
tered or (if none is encountered) until the end of the translation unit. Macro definitions have no significance
after translation phase 4.
2A 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.
3[Example: The simplest use of this facility is to define a “manifest constant,” as in
#define TABSIZE 100
int table[TABSIZE];
— end example ]
4[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 ]
5[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
§ 16.3.5 403
c
ISO/IEC N????
#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 ]
6[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 ]
7[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
§ 16.3.5 404
c
ISO/IEC N????
int j[] = { 123, 45, 67, 89,
10, 11, 12, };
— end example ]
8[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 ]
9[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 ]
16.4 Line control [cpp.line]
1The string literal of a #line directive, if present, shall be a character string literal.
2The line number of the current source line is one greater than the number of new-line characters read or
introduced in translation phase 1 (2.2) while processing the source file to the current token.
3A 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.
4A preprocessing directive of the form
# line digit-sequence "s-char-sequenceopt "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.
5A 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
§ 16.4 405
c
ISO/IEC N????
does not match one of the two previous forms, the behavior is undefined; otherwise, the result is processed
as appropriate.
16.5 Error directive [cpp.error]
1A preprocessing directive of the form
# error pp-tokensopt new-line
causes the implementation to produce a diagnostic message that includes the specified sequence of pre-
processing tokens, and renders the program ill-formed.
16.6 Pragma directive [cpp.pragma]
1A preprocessing directive of the form
# pragma pp-tokensopt 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.
16.7 Null directive [cpp.null]
1A preprocessing directive of the form
#new-line
has no effect.
16.8 Predefined macro names [cpp.predefined]
1The following macro names shall be defined by the implementation:
_ _ cplusplus
The name _ _ cplusplus is defined to the value 201103L when compiling a C++ translation unit.160
_ _ 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).161
_ _ LINE _ _
The presumed line number (within the current source file) of the current source line (an integer
constant).161
_ _ STDC_HOSTED _ _
The integer constant 1if the implementation is a hosted implementation or the integer constant 0if
it is not.
_ _ 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.
2The following macro names are conditionally defined by the implementation:
_ _ STDC _ _
Whether _ _ STDC _ _ is predefined and if so, what its value is, are implementation-defined.
160) It is intended that future versions of this 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.
161) The presumed source file name and line number can be changed by the #line directive.
§ 16.8 406
c
ISO/IEC N????
_ _ STDC_MB_MIGHT_NEQ_WC _ _
The integer constant 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 constant 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 constant 1, if and only if the implementation has strict pointer
safety (3.7.4.3).
_ _ STDCPP_THREADS _ _
Defined, and has the value integer constant 1, if and only if a program can have more than one thread
of execution (1.10).
3The values of the predefined macros (except for _ _ FILE _ _ and _ _ LINE _ _) remain constant throughout
the translation unit.
4If 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.
16.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 Lprefix, 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 ]
§ 16.9 407
c
ISO/IEC N????
17 Library introduction [library]
17.1 General [library.general]
1This 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.
2The following subclauses describe the definitions (17.3), method of description (17.5), and organization (17.6.1)
of the library. Clause 17.6, Clauses 18 through 30, and Annex Dspecify the contents of the library, as well as
library requirements and constraints on both well-formed C++ programs and conforming implementations.
3Detailed specifications for each of the components in the library are in Clauses 1830, as shown in Table 13.
Table 13 — Library categories
Clause Category
18 Language support library
19 Diagnostics library
20 General utilities library
21 Strings library
22 Localization library
23 Containers library
24 Iterators library
25 Algorithms library
26 Numerics library
27 Input/output library
28 Regular expressions library
29 Atomic operations library
30 Thread support library
4The language support library (Clause 18) provides components that are required by certain parts of the C++
language, such as memory allocation (5.3.4,5.3.5) and exception processing (Clause 15).
5The diagnostics library (Clause 19) provides a consistent framework for reporting errors in a C++ program,
including predefined exception classes.
6The general utilities library (Clause 20) includes components used by other library elements, such as a
predefined storage allocator for dynamic storage management (3.7.4), and components used as infrastructure
in C++ programs, such as a tuples, function wrappers, and time facilities.
7The strings library (Clause 21) 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.
8The localization library (Clause 22) provides extended internationalization support for text processing.
9The containers (Clause 23), iterators (Clause 24), and algorithms (Clause 25) libraries provide a C++ program
with access to a subset of the most widely used algorithms and data structures.
10 The numerics library (Clause 26) 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.
11 The input/output library (Clause 27) 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,
§ 17.1 408
c
ISO/IEC N????
locales, and iterators.
12 The regular expressions library (Clause 28) provides regular expression matching and searching.
13 The atomic operations library (Clause 29) allows more fine-grained concurrent access to shared data than
is possible with locks.
14 The thread support library (Clause 30) provides components to create and manage threads, including mutual
exclusion and interthread communication.
17.2 The C standard library [library.c]
1The C++ standard library also makes available the facilities of the C standard library, suitably adjusted to
ensure static type safety.
2The descriptions of many library functions rely on the C standard library for the signatures and semantics
of those functions. In all such cases, any use of the restrict qualifier shall be omitted.
17.3 Definitions [definitions]
17.3.1 [defns.arbitrary.stream]
arbitrary-positional stream
a stream (described in Clause 27) 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 ]
17.3.2 [defns.block]
block
place a thread in the blocked state
17.3.3 [defns.blocked]
blocked thread
a thread that is waiting for some condition (other than the availability of a processor) to be satisfied before
it can continue execution162
17.3.4 [defns.character]
character
<Clauses 21,22,27, and 28> 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 ]
17.3.5 [defns.character.container]
character container type
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 (3.9) type. — end note ]
17.3.6 [defns.comparison]
comparison function
an operator function (13.5) for any of the equality (5.10) or relational (5.9) operators
17.3.7 [defns.component]
component
a group of library entities directly related as members, parameters, or return types
162) This definition is taken from POSIX.
§ 17.3 409
c
ISO/IEC N????
[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 ]
17.3.8 [defns.deadlock]
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
17.3.9 [defns.default.behavior.impl]
default behavior
<implementation> any specific behavior provided by the implementation, within the scope of the required
behavior
17.3.10 [defns.default.behavior.func]
default behavior
<specification> a description of replacement function and handler function semantics
17.3.11 [defns.direct-non-list-init]
direct-non-list-initialization
A direct-initialization that is not list-initialization.
17.3.12 [defns.handler]
handler function
anon-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 18).
— end note ]
17.3.13 [defns.iostream.templates]
iostream class templates
templates, defined in Clause 27, 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 ]
17.3.14 [defns.modifier]
modifier function
a class member function (9.3) other than a constructor, assignment operator, or destructor that alters the
state of an object of the class
17.3.15 [defns.move.constr]
move construction
direct-initialization of an object of some type with an rvalue of the same type
17.3.16 [defns.move.assign]
move assignment
assignment of an rvalue of some object type to a modifiable lvalue of the same type
17.3.17 [defns.obj.state]
object state
§ 17.3 410
c
ISO/IEC N????
the current value of all non-static class members of an object (9.2)
[Note: The state of an object can be obtained by using one or more observer functions.— end note ]
17.3.18 [defns.ntcts]
NTCTS
a sequence of values that have character type that precede the terminating null character type value charT()
17.3.19 [defns.observer]
observer function
a class member function (9.3) 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 (9.3.2). — end note ]
17.3.20 [defns.referenceable]
referenceable type
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 ]
17.3.21 [defns.replacement]
replacement function
anon-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 (2.2) and resolving the definitions of all translation units (3.5). — end note ]
17.3.22 [defns.repositional.stream]
repositional stream
a stream (described in Clause 27) that can seek to a position that was previously encountered
17.3.23 [defns.required.behavior]
required behavior
a description of replacement function and handler function semantics applicable to both the behavior pro-
vided 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 ]
17.3.24 [defns.reserved.function]
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 ]
17.3.25 [defns.stable]
stable algorithm
an algorithm that preserves, as appropriate to the particular algorithm, the order of elements
[Note: Requirements for stable algorithms are given in 17.6.5.7.— end note ]
17.3.26 [defns.traits]
traits class
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
§ 17.3 411
c
ISO/IEC N????
[Note: Traits classes defined in Clauses 21,22 and 27 are character traits, which provide the character
handling support needed by the string and iostream classes. — end note ]
17.3.27 [defns.unblock]
unblock
place a thread in the unblocked state
17.3.28 [defns.valid]
valid but unspecified state
an object state 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 xof 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 ]
17.4 Additional definitions [defns.additional]
11.3 defines additional terms used elsewhere in this International Standard.
17.5 Method of description (Informative) [description]
1This subclause describes the conventions used to specify the C++ standard library. 17.5.1 describes the
structure of the normative Clauses 18 through 30 and Annex D.17.5.2 describes other editorial conventions.
17.5.1 Structure of each clause [structure]
17.5.1.1 Elements [structure.elements]
1Each library clause contains the following elements, as applicable:163
— Summary
— Requirements
Detailed specifications
References to the Standard C library
17.5.1.2 Summary [structure.summary]
1The 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.
2Paragraphs labeled “Note(s):” or “Example(s):” are informative, other paragraphs are normative.
3The contents of the summary and the detailed specifications include:
— macros
— values
— types
classes and class templates
functions and function templates
— objects
163) 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.
§ 17.5.1.2 412
c
ISO/IEC N????
17.5.1.3 Requirements [structure.requirements]
1Requirements 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
2The string and iostream components use an explicit representation of operations required of template argu-
ments. They use a class template char_traits to define these constraints.
3Interface 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 xof class X,++x is defined.
That is, whether the operator is a member is unspecified.
4Requirements 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 25) that uses the well-defined
expression requirements is described in terms of the valid expressions for its formal type parameters.
5Template argument requirements are sometimes referenced by name. See 17.5.2.1.
6In some cases the semantic requirements are presented as C++ code. Such code is intended as a specifica-
tion of equivalence of a construct to another construct, not necessarily as the way the construct must be
implemented.164
17.5.1.4 Detailed specifications [structure.specifications]
1The detailed specifications each contain the following elements:
name and brief description
synopsis (class definition or function prototype, as appropriate)
restrictions on template arguments, if any
description of class invariants
description of function semantics
2Descriptions of class member functions follow the order (as appropriate):165
constructor(s) and destructor
copying, moving & assignment functions
comparison functions
modifier functions
observer functions
operators and other non-member functions
3Descriptions of function semantics contain the following elements (as appropriate):166
164) Although in some cases the code given is unambiguously the optimum implementation.
165) 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.
166) 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.
§ 17.5.1.4 413
c
ISO/IEC N????
Requires: the preconditions for calling the function
Effects: the actions performed by the function
Synchronization: the synchronization operations (1.10) 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.
Notes: non-normative comments about the function
4Whenever the Effects: element specifies that the semantics of some function Fare 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:,Postconditions:,Returns:,Throws:,Complexity:,
Remarks:,Error conditions:, and Notes: specified for the function invocations contained in the code sequence.
The value returned from Fis specified by F’s Returns: element, or if Fhas no Returns: element, a non-void
return from Fis specified by the Returns: elements 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.
5For non-reserved replacement and handler functions, Clause 18 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.
6If the formulation of a complexity requirement calls for a negative number of operations, the actual require-
ment is zero operations.167
7Complexity requirements specified in the library clauses are upper bounds, and implementations that provide
better complexity guarantees satisfy the requirements.
8Error conditions specify conditions where a function may fail. The conditions are listed, together with a
suitable explanation, as the enum class errc constants (19.5).
17.5.1.5 C library [structure.see.also]
1Paragraphs labeled “See also: contain cross-references to the relevant portions of this International Stan-
dard and the ISO C standard, which is incorporated into this International Standard by reference.
17.5.2 Other conventions [conventions]
1This subclause describes several editorial conventions used to describe the contents of the C++ standard
library. These conventions are for describing implementation-defined types (17.5.2.1), and member func-
tions (17.5.2.2).
17.5.2.1 Type descriptions [type.descriptions]
17.5.2.1.1 General [type.descriptions.general]
1The Requirements subclauses may describe names that are used to specify constraints on template argu-
167) This simplifies the presentation of complexity requirements in some cases.
§ 17.5.2.1.1 414
c
ISO/IEC N????
ments.168 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.
2Certain types defined in Clause 27 are used to describe implementation-defined types. They are based on
other types, but with added constraints.
17.5.2.1.2 Enumerated types [enumerated.types]
1Several types defined in Clause 27 are enumerated types. Each enumerated type may be implemented as an
enumeration or as a synonym for an enumeration.169
2The enumerated type enumerated can be written:
enum enumerated {V0 ,V1 ,V2 ,V3 , ..... };
static const enumerated C0 (V0 );
static const enumerated C1 (V1 );
static const enumerated C2 (V2 );
static const enumerated C3 (V3 );
.....
3Here, the names C0 ,C1 , etc. represent enumerated elements for this particular enumerated type. All such
elements have distinct values.
17.5.2.1.3 Bitmask types [bitmask.types]
1Several types defined in Clauses 18 through 30 and Annex Dare bitmask types. Each bitmask type can be im-
plemented as an enumerated type that overloads certain operators, as an integer type, or as a bitset (20.7).
2The 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 {
V0 = 1 << 0, V1 = 1 << 1, V2 = 1 << 2, V3 = 1 << 3, .....
};
constexpr bitmask C0 (V0 );
constexpr bitmask C1 (V1 );
constexpr bitmask C2 (V2 );
constexpr bitmask C3 (V3 );
.....
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){
168) Examples from 17.6.3 include: EqualityComparable,LessThanComparable,CopyConstructible. Examples from 24.2 in-
clude: InputIterator,ForwardIterator,Function,Predicate.
169) Such as an integer type, with constant integer values (3.9.1).
§ 17.5.2.1.3 415
c
ISO/IEC N????
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;
}
3Here, the names C0 ,C1 , etc. represent bitmask elements for this particular bitmask type. All such elements
have distinct values such that, for any pair Ci and Cj,Ci &Ci is nonzero and Ci &Cj is zero.
4The following terms apply to objects and values of bitmask types:
To set a value Yin an object Xis to evaluate the expression X|=Y.
To clear a value Yin an object Xis to evaluate the expression X&= Y.
The value Y is set in the object Xif the expression X&Yis nonzero.
17.5.2.1.4 Character sequences [character.seq]
1The 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.170
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 18 through 30 and
Annex Dby 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*),171 or by a change to a locale object, as
described in Clauses 22.3 and 27.
A character sequence is an array object (8.3.4)Athat can be declared as T A [N], where Tis any of
the types char,unsigned char, or signed char (3.9.1), 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.
17.5.2.1.4.1 Byte strings [byte.strings]
1Anull-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.172
2The length of an ntbs is the number of elements that precede the terminating null character. An empty
ntbs has a length of zero.
3The value of an ntbs is the sequence of values of the elements up to and including the terminating null
character.
170) Note that this definition differs from the definition in ISO C 7.1.1.
171) declared in <clocale> (22.6).
172) Many of the objects manipulated by function signatures declared in <cstring> (21.8) 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.
§ 17.5.2.1.4 416
c
ISO/IEC N????
4Astatic ntbs is an ntbs with static storage duration.173
17.5.2.1.4.2 Multibyte strings [multibyte.strings]
1Anull-terminated multibyte string, or ntmbs, is an ntbs that constitutes a sequence of valid multibyte
characters, beginning and ending in the initial shift state.174
2Astatic ntmbs is an ntmbs with static storage duration.
17.5.2.2 Functions within classes [functions.within.classes]
1For the sake of exposition, Clauses 18 through 30 and Annex Ddo not describe copy/move constructors,
assignment operators, or (non-virtual) destructors with the same apparent semantics as those that can be
generated by default (12.1,12.4,12.8).
2It is unspecified whether the implementation provides explicit definitions for such member function signa-
tures, or for virtual destructors that can be generated by default.
17.5.2.3 Private members [objects.within.classes]
1Clauses 18 through 30 and Annex Ddo not specify the representation of classes, and intentionally omit
specification of class members (9.2). 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 18 through 30 and
Annex D.
2Objects of certain classes are sometimes required by the external specifications of their classes to store data,
apparently in member objects. For the sake of exposition, some subclauses provide representative declara-
tions, and semantic requirements, for private member objects of classes that meet the external specifications
of the classes. The declarations for such member objects and the definitions of related member types are
followed by a comment that ends with exposition only, as in:
streambuf* sb; // exposition only
3An implementation may use any technique that provides equivalent external behavior.
17.6 Library-wide requirements [requirements]
1This subclause specifies requirements that apply to the entire C++ standard library. Clauses 18 through 30
and Annex Dspecify the requirements of individual entities within the library.
2Requirements specified in terms of interactions between threads do not apply to programs having only a
single thread of execution.
3Within this subclause, 17.6.1 describes the library’s contents and organization, 17.6.2 describes how well-
formed C++ programs gain access to library entities, 17.6.3 describes constraints on types and functions
used with the C++ standard library, 17.6.4 describes constraints on well-formed C++ programs, and 17.6.5
describes constraints on conforming implementations.
17.6.1 Library contents and organization [organization]
117.6.1.1 describes the entities defined in the C++ standard library. 17.6.1.2 lists the standard library headers
and some constraints on those headers. 17.6.1.3 lists requirements for a freestanding implementation of the
C++ standard library.
17.6.1.1 Library contents [contents]
1The C++ standard library provides definitions for the following types of entities: macros, values, types,
templates, classes, functions, objects.
2All library entities except macros, operator new and operator delete are defined within the namespace
std or namespaces nested within namespace std.175 It is unspecified whether names declared in a specific
namespace are declared directly in that namespace or in an inline namespace inside that namespace.176
173) A string literal, such as "abc", is a static ntbs.
174) 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.
175) The C standard library headers (Annex D.5) also define names within the global namespace, while the C++ headers for C
library facilities (17.6.1.2) may also define names within the global namespace.
176) This gives implementers freedom to use inline namespaces to support multiple configurations of the library.
§ 17.6.1.1 417
c
ISO/IEC N????
3Whenever a name xdefined in the standard library is mentioned, the name xis 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.
17.6.1.2 Headers [headers]
1Each element of the C++ standard library is declared or defined (as appropriate) in a header.177
2The C++ standard library provides 55 C++ library headers, as shown in Table 14.
Table 14 — C++ library headers
<algorithm> <forward_list> <limits> <random> <system_error>
<array> <fstream> <list> <ratio> <thread>
<atomic> <functional> <locale> <regex> <tuple>
<bitset> <future> <map> <scoped_allocator> <type_traits>
<chrono> <initializer_list> <memory> <set> <typeindex>
<codecvt> <iomanip> <mutex> <sstream> <typeinfo>
<complex> <ios> <new> <stack> <unordered_map>
<condition_variable> <iosfwd> <numeric> <stdexcept> <unordered_set>
<deque> <iostream> <optional> <streambuf> <utility>
<dynarray> <istream> <ostream> <string> <valarray>
<exception> <iterator> <queue> <strstream> <vector>
3The facilities of the C standard Library are provided in 26 additional headers, as shown in Table 15.
Table 15 — 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>
4Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same
as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode
TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for
names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is
unspecified whether these names are first declared within the global namespace scope and are then injected
into namespace std by explicit using-declarations (7.3.3).
5Names 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 ]
6Names that are defined as functions in C shall be defined as functions in the C++ standard library.178
7Identifiers that are keywords or operators in C++ shall not be defined as macros in C++ standard library
headers.179
177) A header is not necessarily a source file, nor are the sequences delimited by <and >in header names necessarily valid
source file names (16.2).
178) 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.
179) In particular, including the standard header <iso646.h> or <ciso646> has no effect.
§ 17.6.1.2 418
c
ISO/IEC N????
8D.5, C standard library headers, describes the effects of using the name.h (C header) form in a C++ pro-
gram.180
17.6.1.3 Freestanding implementations [compliance]
1Two kinds of implementations are defined: hosted and freestanding (1.4). For a hosted implementation, this
International Standard describes the set of available headers.
2A freestanding implementation has an implementation-defined set of headers. This set shall include at least
the headers shown in Table 16.
Table 16 — C++ headers for freestanding implementations
Subclause Header(s)
<ciso646>
18.2 Types <cstddef>
18.3 Implementation properties <cfloat> <limits> <climits>
18.4 Integer types <cstdint>
18.5 Start and termination <cstdlib>
18.6 Dynamic memory management <new>
18.7 Type identification <typeinfo>
18.8 Exception handling <exception>
18.9 Initializer lists <initializer_list>
18.10 Other runtime support <cstdalign> <cstdarg> <cstdbool>
20.11 Type traits <type_traits>
29 Atomics <atomic>
3The supplied version of the header <cstdlib> shall declare at least the functions abort,atexit,at_quick_-
exit,exit, and quick_exit (18.5). The other headers listed in this table shall meet the same requirements
as for a hosted implementation.
17.6.2 Using the library [using]
17.6.2.1 Overview [using.overview]
1This section describes how a C++ program gains access to the facilities of the C++ standard library. 17.6.2.2
describes effects during translation phase 4, while 17.6.2.3 describes effects during phase 8 (2.2).
17.6.2.2 Headers [using.headers]
1The 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 (16.2).
2A translation unit may include library headers in any order (Clause 2). 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.181
3A translation unit shall include a header only outside of any external 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.
17.6.2.3 Linkage [using.linkage]
1Entities in the C++ standard library have external linkage (3.5). Unless otherwise specified, objects and
functions have the default extern "C++" linkage (7.5).
180) 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.
181) This is the same as the Standard C library.
§ 17.6.2.3 419
c
ISO/IEC N????
2Whether 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.182
3Objects 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 (17.6.4.6), run-time changes (17.6.4.7).
17.6.3 Requirements on types and expressions [utility.requirements]
117.6.3.1 describes requirements on types and expressions used to instantiate templates defined in the C++
standard library. 17.6.3.2 describes the requirements on swappable types and swappable expressions. 17.6.3.3
describes the requirements on pointer-like types that support null values. 17.6.3.4 describes the requirements
on hash function objects. 17.6.3.5 describes the requirements on storage allocators.
17.6.3.1 Template argument requirements [utility.arg.requirements]
1The template definitions in the C++ standard library refer to various named requirements whose details are
set out in tables 1724. In these tables, Tis an object or reference type to be supplied by a C++ program
instantiating a template; a,b, and care values of type (possibly const)T;sand tare modifiable lvalues of
type T;udenotes an identifier; rv is an rvalue of type T; and vis an lvalue of type (possibly const)Tor an
rvalue of type const T.
2In 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 (8.5) if one of those signatures is called
using the default argument (8.3.6).
Table 17 — EqualityComparable requirements [equalitycomparable]
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 18 — LessThanComparable requirements [lessthancomparable]
Expression Return type Requirement
a<b convertible to
bool
<is a strict weak ordering relation (25.4)
182) The only reliable way to declare an object or function signature from the Standard C library is by including the header
that declares it, notwithstanding the latitude granted in 7.1.7 of the C Standard.
§ 17.6.3.1 420
c
ISO/IEC N????
Table 19 — DefaultConstructible requirements [defaultconstructible]
Expression Post-condition
T t; object tis default-initialized
T u{}; object uis value-initialized
T() a temporary object of type Tis value-initialized
T{}
Table 20 — MoveConstructible requirements [moveconstructible]
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 compo-
nent 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 21 — CopyConstructible requirements (in addition to MoveConstructible)[copyconstructible]
Expression Post-condition
Tu=v; the value of vis unchanged and is equivalent to u
T(v) the value of vis unchanged and is equivalent to T(v)
Table 22 — MoveAssignable requirements [moveassignable]
Expression Return type Return value Post-condition
t = rv T& t 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. The operations listed in those requirements must work as
specified whether rv has been moved from or not. — end note ]
Table 23 — CopyAssignable requirements (in addition to MoveAssignable)[copyassignable]
Expression Return type Return value Post-condition
t = v T& t t is equivalent to v, the value of
vis unchanged
Table 24 — Destructible requirements [destructible]
Expression Post-condition
u.T() All resources owned by uare reclaimed, no exception is propagated.
§ 17.6.3.1 421
c
ISO/IEC N????
17.6.3.2 Swappable requirements [swappable.requirements]
1This subclause provides definitions for swappable types and expressions. In these definitions, let tdenote
an expression of type T, and let udenote an expression of type U.
2An object tis swappable with an object uif 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 thas the value originally held by uand
the object referred to by uhas the value originally held by t.
3The 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 (13.3) on a candidate set that includes:
the two swap function templates defined in <utility> (20.2) and
the lookup set produced by argument-dependent lookup (3.4.2).
[Note: If Tand Uare 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 ]
4An rvalue or lvalue tis swappable if and only if tis swappable with any rvalue or lvalue, respectively, of
type T.
5A type Xsatisfying any of the iterator requirements (24.2) satisfies the requirements of ValueSwappable if,
for any dereferenceable object xof 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 Tshall 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) {
§ 17.6.3.2 422
c
ISO/IEC N????
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() {
inti=1,j=2;
lv_swap(i, j);
assert(i == 2 && j == 1);
N::Aa1={5},a2={-5};
value_swap(a1, proxy(a2));
assert(a1.m == -5 && a2.m == 5);
}
— end example ]
17.6.3.3 NullablePointer requirements [nullablepointer.requirements]
1ANullablePointer type is a pointer-like type that supports null values. A type Pmeets the requirements
of NullablePointer if:
Psatisfies the requirements of EqualityComparable,DefaultConstructible,CopyConstructible,
CopyAssignable, and Destructible,
lvalues of type Pare swappable (17.6.3.2),
the expressions shown in Table 25 are valid and have the indicated semantics, and
Psatisfies all the other requirements of this subclause.
2A value-initialized object of type Pproduces the null value of the type. The null value shall be equivalent
only to itself. A default-initialized object of type Pmay have an indeterminate value. [ Note: Operations
involving indeterminate values may cause undefined behavior. — end note ]
3An object pof type Pcan be contextually converted to bool (Clause 4). The effect shall be as if p !=
nullptr had been evaluated in place of p.
4No operation which is part of the NullablePointer requirements shall exit via an exception.
5In Table 25,udenotes an identifier, tdenotes a non-const lvalue of type P,aand bdenote values of type
(possibly const)P, and np denotes a value of type (possibly const)std::nullptr_t.
Table 25 — NullablePointer requirements [nullablepointer]
Expression Return type Operational semantics
P u(np); post: u == nullptr
P u = np;
P(np) post: P(np) == nullptr
t = np P& post: 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
§ 17.6.3.3 423
c
ISO/IEC N????
17.6.3.4 Hash requirements [hash.requirements]
1A type Hmeets the Hash requirements if:
it is a function object type (20.10),
it satisfies the requirements of CopyConstructible and Destructible (17.6.3.1), and
the expressions shown in Table 26 are valid and have the indicated semantics.
2Given Key is an argument type for function objects of type H, in Table 26 his a value of type (possibly
const)H,uis an lvalue of type Key, and kis a value of a type convertible to (possibly const)Key.
Table 26 — Hash requirements [hash]
Expression Return type Requirement
h(k) size_t The value returned shall depend only on the argument k.
[Note: Thus all evaluations of the expression h(k) with the
same value for kyield the same result. — end note ] [ Note:
For two different values t1 and t2, the probability that
h(t1) and h(t2) compare equal should be very small, ap-
proaching 1.0 / numeric_limits<size_t>::max().
end note ]
h(u) size_t Shall not modify u.
17.6.3.5 Allocator requirements [allocator.requirements]
1The library describes a standard set of requirements for allocators, which are class-type objects that encap-
sulate 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 al-
location and deallocation primitives for it. All of the string types (Clause 21), containers (Clause 23) (except
array), string buffers and string streams (Clause 27), and match_results (Clause 28) are parameterized in
terms of allocators.
2The template struct allocator_traits (20.8.8) supplies a uniform interface to all allocator types. Table 27
describes the types manipulated through allocators. Table 28 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 28 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 27 and 28, the use of move and forward
always refers to std::move and std::forward, respectively.
Table 27 — Descriptive variable definitions
Variable Definition
T, U, C any non-const object type (3.9)
Va type convertible to T
Xan Allocator class for type T
Ythe corresponding Allocator class for type U
XX the type allocator_traits<X>
YY the type allocator_traits<Y>
ta value of type const T&
§ 17.6.3.5 424
c
ISO/IEC N????
Table 27 — Descriptive variable definitions (continued)
Variable Definition
a, a1, a2 values of type X&
a3 an rvalue of type X
ba value of type Y
ca pointer of type C* through which indirection is valid
pa value of type XX::pointer, obtained by calling
a1.allocate, where a1 == a
qa value of type XX::const_pointer obtained by
conversion from a value p.
wa value of type XX::void_pointer obtained by conversion
from a value p
za value of type XX::const_void_pointer obtained by
conversion from a value qor a value w
ra value of type T& obtained by the expression *p.
sa value of type const T& obtained by the expression *q or
by conversion from a value r.
ua 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.
va value of type V
na value of type XX::size_type.
Args a template parameter pack
args a function parameter pack with the pattern Args&&
Table 28 — 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
§ 17.6.3.5 425
c
ISO/IEC N????
Table 28 — Allocator requirements (continued)
Expression Return type Assertion/note Default
pre-/post-condition
X::size_type unsigned integer type a type that can represent the
size of the largest object in the
allocation model.
make_-
unsigned<X::
difference_-
type>::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
YFor 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 pre: (*p).m is well-defined.
equivalent to (*p).m
q->m type of T::m pre: (*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>(z)
X::const_pointer static_cast<X
::const_pointer>(z) == q
a.allocate(n) X::pointer Memory is allocated for n
objects of type Tbut objects
are not constructed. allocate
may raise an appropriate
exception.183[Note: If n == 0,
the return value is unspecified.
— end note ]
a.allocate(n, u) X::pointer Same as a.allocate(n). The
use of uis unspecified, but it is
intended as an aid to locality.
a.allocate(n)
a.deallocate(p,n) (not used) All n T objects in the area
pointed to by pshall be
destroyed prior to this call. n
shall match the value passed to
allocate to obtain this
memory. Does not throw
exceptions. [ Note:pshall not be
singular. — end note ]
a.max_size() X::size_type the largest value that can
meaningfully be passed to
X::allocate()
numeric_-
limits<size_-
type>::max()
§ 17.6.3.5 426
c
ISO/IEC N????
Table 28 — Allocator requirements (continued)
Expression Return type Assertion/note Default
pre-/post-condition
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 a1(a);
X a1 = a;
Shall not exit via an exception.
post: a1 == a
X a(b); Shall not exit via an exception.
post: Y(a) == b,a == X(b)
X a1(move(a));
X a1 = move(a);
Shall not exit via an exception.
post: a1 equals the prior value
of a.
X a(move(b)); Shall not exit via an exception.
post: aequals the prior value of
X(b).
a.construct(c,
args)
(not used) Effect: Constructs an object of
type Cat c
::new
((void*)c)
C(forward<
Args>
(args)...)
a.destroy(c) (not used) Effect: Destroys the object at c c->˜C()
a.select_on_-
container_copy_-
construction()
XTypically returns either aor
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 Xshould be copied when
the client container is
copy-assigned.
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 Xshould be moved
when the client container is
move-assigned.
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 Xshould be swapped
when the client container is
swapped.
false_type
3Note 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
183) 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.
§ 17.6.3.5 427
c
ISO/IEC N????
same type as SomeAllocator<U>, where SomeAllocator<T>::value_type is Tand 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.
4An allocator type Xshall satisfy the requirements of CopyConstructible (17.6.3.1). The X::pointer,
X::const_pointer,X::void_pointer, and X::const_void_pointer types shall satisfy the requirements
of NullablePointer (17.6.3.3). No constructor, comparison operator, copy operation, move operation, or
swap operation on these types shall exit via an exception. X::pointer and X::const_pointer shall also
satisfy the requirements for a random access iterator (24.2).
5An allocator may constrain the types on which it can be instantiated and the arguments for which its
construct member may be called. If a type cannot be used with a particular allocator, the allocator class
or the call to construct may fail to instantiate.
[Example: the following is an allocator class template supporting the minimal interface that satisfies the
requirements of Table 28:
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 ]
6If 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
std::bad_alloc.— end note ]
17.6.4 Constraints on programs [constraints]
17.6.4.1 Overview [constraints.overview]
1This 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 (17.6.4.2.1), its use of
various reserved names (17.6.4.3), its use of headers (17.6.4.4), its use of standard library classes as base
classes (17.6.4.5), its definitions of replacement functions (17.6.4.6), and its installation of handler functions
during execution (17.6.4.7).
17.6.4.2 Namespace use [namespace.constraints]
17.6.4.2.1 Namespace std [namespace.std]
1The 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
§ 17.6.4.2.1 428
c
ISO/IEC N????
and the specialization meets the standard library requirements for the original template and is not explicitly
prohibited.184
2The 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.
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.
3A translation unit shall not declare namespace std to be an inline namespace (7.3.1).
17.6.4.2.2 Namespace posix [namespace.posix]
1The 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.
17.6.4.3 Reserved names [reserved.names]
1The C++ standard library reserves the following kinds of names:
— macros
global names
names with external linkage
2If 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.
17.6.4.3.1 Macro names [macro.names]
1A translation unit that includes a standard library header shall not #define or #undef names declared in
any standard library header.
2A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed
in Table 3, or to the attribute-tokens described in 7.6.
17.6.4.3.2 Global names [global.names]
1Certain sets of names and function signatures are always reserved to the implementation:
Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase
letter (2.12) is reserved to the implementation for any use.
Each name that begins with an underscore is reserved to the implementation for use as a name in the
global namespace.
17.6.4.3.3 External linkage [extern.names]
1Each name declared as an object with external linkage in a header is reserved to the implementation to
designate that library object with external linkage,185 both in namespace std and in the global namespace.
184) 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 the Standard.
185) The list of such reserved names includes errno, declared or defined in <cerrno>.
§ 17.6.4.3.3 429
c
ISO/IEC N????
2Each global function signature declared with external linkage in a header is reserved to the implementation
to designate that function signature with external linkage. 186
3Each name from the Standard C 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.
4Each function signature from the Standard C library declared with external linkage is reserved to the
implementation for use as a function signature with both extern "C" and extern "C++" linkage, 187 or as
a name of namespace scope in the global namespace.
17.6.4.3.4 Types [extern.types]
1For each type T from the Standard C library,188 the types ::T and std::T are reserved to the implementation
and, when defined, ::T shall be identical to std::T.
17.6.4.3.5 User-defined literal suffixes [usrlit.suffix]
1Literal suffix identifiers that do not start with an underscore are reserved for future standardization.
17.6.4.4 Headers [alt.headers]
1If 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 (16.2), the behavior is undefined.
17.6.4.5 Derived classes [derived.classes]
1Virtual member function signatures defined for a base class in the C++ standard library may be overridden
in a derived class defined in the program (10.3).
17.6.4.6 Replacement functions [replacement.functions]
1Clauses 18 through 30 and Annex Ddescribe 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 (17.3).
2A C++ program may provide the definition for any of eight dynamic memory allocation function signatures
declared in header <new> (3.7.4,18.6):
operator new(std::size_t)
operator new(std::size_t, const std::nothrow_t&)
operator new[](std::size_t)
operator new[](std::size_t, const std::nothrow_t&)
operator delete(void*)
operator delete(void*, const std::nothrow_t&)
operator delete[](void*)
operator delete[](void*, const std::nothrow_t&)
3The program’s definitions are used instead of the default versions supplied by the implementation (18.6).
Such replacement occurs prior to program startup (3.2,3.6). The program’s definitions shall not be specified
as inline. No diagnostic is required.
186) 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>.
187) The function signatures declared in <cuchar>,<cwchar>, and <cwctype> are always reserved, notwithstanding the restric-
tions imposed in subclause 4.5.1 of Amendment 1 to the C Standard for these headers.
188) 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.
§ 17.6.4.6 430
c
ISO/IEC N????
17.6.4.7 Handler functions [handler.functions]
1The C++ standard library provides default versions of the following handler functions (Clause 18):
unexpected_handler
terminate_handler
2A 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):
set_new_handler
set_unexpected
set_terminate
See also: subclauses 18.6.2, Storage allocation errors, and 18.8, Exception handling.
3A C++ program can get a pointer to the current handler function by calling the following functions:
get_new_handler
get_unexpected
get_terminate
4Calling 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.
17.6.4.8 Other functions [res.on.functions]
1In 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++ pro-
gram. If these components do not meet their requirements, the Standard places no requirements on the
implementation.
2In particular, the effects are undefined in the following cases:
for replacement functions (18.6.1), if the installed replacement function does not implement the se-
mantics of the applicable Required behavior: paragraph.
for handler functions (18.6.2.4,18.8.3.1,D.11.1), 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 (17.6.3.5,23.2,
24.2,26.2). 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 (3.9) is used as a template argument when instantiating a template component,
unless specifically allowed for that component.
§ 17.6.4.8 431
c
ISO/IEC N????
17.6.4.9 Function arguments [res.on.arguments]
1Each 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 Ais bound, the argument binds to an lvalue reference (14.8.2.1) 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
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 ]
17.6.4.10 Shared objects and the library [res.on.objects]
1The 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 17.6.5.9. [ 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 ]
2[Note: In particular, the program is required to ensure that completion of the constructor of any object of
a class type defined in the standard library happens before any other member function invocation on that
object and, unless otherwise specified, to ensure that completion of any member function invocation other
than destruction on such an object happens before destruction of that object. This applies even to objects
such as mutexes intended for thread synchronization. — end note ]
17.6.4.11 Requires paragraph [res.on.required]
1Violation 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.
17.6.5 Conforming implementations [conforming]
17.6.5.1 Overview [conforming.overview]
1This section describes the constraints upon, and latitude of, implementations of the C++ standard library.
2An implementation’s use of headers is discussed in 17.6.5.2, its use of macros in 17.6.5.3, global functions
in 17.6.5.4, member functions in 17.6.5.5, data race avoidance in 17.6.5.9, access specifiers in 17.6.5.10, class
derivation in 17.6.5.11, and exceptions in 17.6.5.12.
17.6.5.2 Headers [res.on.headers]
1A 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.
2Certain 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 (3.2).
3The C standard headers (D.5) shall include only their corresponding C++ standard header, as described
in 17.6.1.2.
17.6.5.3 Restrictions on macro definitions [res.on.macro.definitions]
1The names and global function signatures described in 17.6.1.1 are reserved to the implementation.
§ 17.6.5.3 432
c
ISO/IEC N????
2All 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.
17.6.5.4 Global and non-member functions [global.functions]
1It is unspecified whether any global or non-member functions in the C++ standard library are defined as
inline (7.1.2).
2A call to a global or non-member function signature described in Clauses 18 through 30 and Annex Dshall
behave as if the implementation declared no additional global or non-member function signatures.189
3An implementation shall not declare a global or non-member function signature with additional default
arguments.
4Unless otherwise specified, global and non-member functions in the standard library shall not use functions
from another namespace which are found through argument-dependent name lookup (3.4.2). [ Note: The
phrase “unless otherwise specified” is intended to allow argument-dependent lookup in cases like that of
ostream_iterators: Effects:
*out_stream << value;
if (delim != 0)
*out_stream << delim;
return (*this);
— end note ]
17.6.5.5 Member functions [member.functions]
1It is unspecified whether any member functions in the C++ standard library are defined as inline (7.1.2).
2An implementation may declare additional non-virtual member function signatures within a class:
by adding arguments with default values to a member function signature;190 [Note: An implementation
may not add arguments with default values to virtual, global, or non-member functions. — end note ]
by replacing a member function signature with default values by two or more member function signa-
tures with equivalent behavior; and
by adding a member function signature for a member function name.
3A call to a member function signature described in the C++ standard library behaves as if the implementation
declares no additional member function signatures.191
17.6.5.6 constexpr functions and constructors [constexpr.functions]
1Within any header that provides any non-defining declarations of constexpr functions or constructors an
implementation shall provide corresponding definitions.
17.6.5.7 Requirements for stable algorithms [algorithm.stable]
1When 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).
189) A valid C++ program always calls the expected library global or non-member function. An implementation may also
define additional global or non-member functions that would otherwise not be called by a valid C++ program.
190) Hence, the address of a member function of a class in the C++ standard library has an unspecified type.
191) A valid C++ program always calls the expected library member function, or one with equivalent behavior. An implemen-
tation may also define additional member functions that would otherwise not be called by a valid C++ program.
§ 17.6.5.7 433
c
ISO/IEC N????
17.6.5.8 Reentrancy [reentrancy]
1Except where explicitly specified in this standard, it is implementation-defined which functions in the Stan-
dard C++ library may be recursively reentered.
17.6.5.9 Data race avoidance [res.on.data.races]
1This section specifies requirements that implementations shall meet to prevent data races (1.10). Every
standard library function shall meet each requirement unless otherwise specified. Implementations may
prevent data races in cases other than those specified below.
2A C++ standard library function shall not directly or indirectly access objects (1.10) accessible by threads
other than the current thread unless the objects are accessed directly or indirectly via the function’s argu-
ments, including this.
3A C++ standard library function shall not directly or indirectly modify objects (1.10) 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.
4[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 ]
5A 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.
6Operations 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 ]
7Implementations may share their own internal objects between threads if the objects are not visible to users
and are protected against data races.
8Unless otherwise specified, C++ standard library functions shall perform all operations solely within the
current thread if those operations have effects that are visible (1.10) to users.
9[Note: This allows implementations to parallelize operations if there are no visible side effects. — end note ]
17.6.5.10 Protection within classes [protection.within.classes]
1It is unspecified whether any function signature or class described in Clauses 18 through 30 and Annex Dis
afriend of another class in the C++ standard library.
17.6.5.11 Derived classes [derivation]
1An implementation may derive any class in the C++ standard library from a class with a name reserved to
the implementation.
2Certain 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.
3In any case:
Every base class described as virtual shall be virtual;
Every base class described as non-virtual shall not be virtual;
Unless explicitly stated otherwise, types with distinct names shall be distinct types.192
17.6.5.12 Restrictions on exception handling [res.on.exception.handling]
1Any 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. An implementation may strengthen the exception-specification
for a non-virtual function by adding a non-throwing noexcept-specification.
192) There is an implicit exception to this rule for types that are described as synonyms for basic integral types, such as
size_t (18.2) and streamoff (27.5.2).
§ 17.6.5.12 434
c
ISO/IEC N????
2A function may throw an object of a type not listed in its Throws clause if its type is derived from a type
named in the Throws clause and would be caught by an exception handler for the base type.
3Functions from the C standard library shall not throw exceptions193 except when such a function calls a
program-supplied function that throws an exception.194
4Destructor 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. Any other functions
defined in the C++ standard library that do not have an exception-specification may throw implementation-
defined exceptions unless otherwise specified.195 An implementation may strengthen this implicit exception-
specification by adding an explicit one.196
17.6.5.13 Restrictions on storage of pointers [res.on.pointer.storage]
1Objects 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 (3.7.4.3). [ 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 ]
17.6.5.14 Value of error codes [value.error.codes]
1Certain functions in the C++ standard library report errors via a std::error_code (19.5.2.1) object. That
object’s category() member shall return std::system_category() for errors originating from the oper-
ating 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 de-
fined 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 ]
17.6.5.15 Moved-from state of library types [lib.types.movedfrom]
1Objects of types defined in the C++ standard library may be moved from (12.8). 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.
193) 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.
194) The functions qsort() and bsearch() (25.5) meet this condition.
195) 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 (18.6.2.1). Library implementations should report errors by throwing exceptions of or derived from the standard
exception classes (18.6.2.1,18.8,19.2).
196) That is, an implementation may provide an explicit exception-specification that defines the subset of “any” exceptions
thrown by that function. This implies that the implementation may list implementation-defined types in such an exception-
specification.
§ 17.6.5.15 435
c
ISO/IEC N????
18 Language support library
[language.support]
18.1 General [support.general]
1This 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.
2The 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 29.
Table 29 — Language support library summary
Subclause Header(s)
18.2 Types <cstddef>
<limits>
18.3 Implementation properties <climits>
<cfloat>
18.4 Integer types <cstdint>
18.5 Start and termination <cstdlib>
18.6 Dynamic memory management <new>
18.7 Type identification <typeinfo>
18.8 Exception handling <exception>
18.9 Initializer lists <initializer_list>
<csignal>
<csetjmp>
<cstdalign>
18.10 Other runtime support <cstdarg>
<cstdbool>
<cstdlib>
<ctime>
18.2 Types [support.types]
1Table 30 describes the header <cstddef>.
Table 30 — Header <cstddef> synopsis
Type Name(s)
Macros:NULL offsetof
Types:ptrdiff_t size_t
max_align_t nullptr_t
§ 18.2 436
c
ISO/IEC N????
2The contents are the same as the Standard C library header <stddef.h>, with the following changes:
3The macro NULL is an implementation-defined C++ null pointer constant in this International Standard
(4.10).197
4The macro offsetof(type,member-designator) accepts a restricted set of type arguments in this International
Standard. If type is not a standard-layout class (Clause 9), the results are undefined.198 The expression
offsetof(type,member-designator) is never type-dependent (14.6.2.2) and it is value-dependent (14.6.2.3)
if and only if type is dependent. The result of applying the offsetof macro to a field that is 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.
5The 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 5.7.
6The type size_t is an implementation-defined unsigned integer type that is large enough to contain the size
in bytes of any object.
7[Note: It is recommended that implementations choose types for ptrdiff_t and size_t whose integer
conversion ranks (4.13) are no greater than that of signed long int unless a larger size is necessary to
contain all the possible values. — end note ]
8The 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.
9nullptr_t is defined as follows:
namespace std {
typedef decltype(nullptr) nullptr_t;
}
The type for which nullptr_t is a synonym has the characteristics described in 3.9.1 and 4.10. [ Note:
Although nullptr’s address cannot be taken, the address of another nullptr_t object that is an lvalue can
be taken. — end note ]
See also: Alignment (3.11), Sizeof (5.3.3), Additive operators (5.7), Free store (12.5), and ISO C 7.1.6.
18.3 Implementation properties [support.limits]
18.3.1 In general [support.limits.general]
1The headers <limits> (18.3.2), <climits>, and <cfloat> (18.3.3) supply characteristics of implementation-
dependent arithmetic types (3.9.1).
18.3.2 Numeric limits [limits]
18.3.2.1 Class template numeric_limits [limits.numeric]
1The numeric_limits class template provides a C++ program with information about various properties of
the implementation’s representation of the arithmetic types.
2Specializations 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.
3For 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.
4Non-arithmetic standard types, such as complex<T> (26.4.2), shall not have specializations.
18.3.2.2 Header <limits> synopsis [limits.syn]
namespace std {
template<class T> class numeric_limits;
enum float_round_style;
enum float_denorm_style;
197) Possible definitions include 0and 0L, but not (void*)0.
198) Note that offsetof is required to work as specified even if unary operator& is overloaded for any of the types involved.
§ 18.3.2.2 437
c
ISO/IEC N????
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>;
}
18.3.2.3 Class template numeric_limits [numeric.limits]
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(); }
§ 18.3.2.3 438
c
ISO/IEC N????
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>;
}
1The default numeric_limits<T> template shall have all members, but with 0 or false values.
2The 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.
18.3.2.4 numeric_limits members [numeric.limits.members]
static constexpr T min() noexcept;
1Minimum finite value.199
2For floating types with denormalization, returns the minimum positive normalized value.
3Meaningful for all specializations in which is_bounded != false, or is_bounded == false && is_-
signed == false.
static constexpr T max() noexcept;
4Maximum finite value.200
5Meaningful for all specializations in which is_bounded != false.
static constexpr T lowest() noexcept;
6A finite value xsuch that there is no other finite value ywhere y<x.201
7Meaningful for all specializations in which is_bounded != false.
static constexpr int digits;
8Number of radix digits that can be represented without change.
9For integer types, the number of non-sign bits in the representation.
10 For floating point types, the number of radix digits in the mantissa.202
static constexpr int digits10;
199) Equivalent to CHAR_MIN,SHRT_MIN,FLT_MIN,DBL_MIN, etc.
200) Equivalent to CHAR_MAX,SHRT_MAX,FLT_MAX,DBL_MAX, etc.
201) 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.
202) Equivalent to FLT_MANT_DIG,DBL_MANT_DIG,LDBL_MANT_DIG.
§ 18.3.2.4 439
c
ISO/IEC N????
11 Number of base 10 digits that can be represented without change.203
12 Meaningful for all specializations in which is_bounded != false.
static constexpr int max_digits10;
13 Number of base 10 digits required to ensure that values which differ are always differentiated.
14 Meaningful for all floating point types.
static constexpr bool is_signed;
15 True if the type is signed.
16 Meaningful for all specializations.
static constexpr bool is_integer;
17 True if the type is integer.
18 Meaningful for all specializations.
static constexpr bool is_exact;
19 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.
20 Meaningful for all specializations.
static constexpr int radix;
21 For floating types, specifies the base or radix of the exponent representation (often 2).204
22 For integer types, specifies the base of the representation.205
23 Meaningful for all specializations.
static constexpr T epsilon() noexcept;
24 Machine epsilon: the difference between 1 and the least value greater than 1 that is representable.206
25 Meaningful for all floating point types.
static constexpr T round_error() noexcept;
26 Measure of the maximum rounding error.207
static constexpr int min_exponent;
203) Equivalent to FLT_DIG,DBL_DIG,LDBL_DIG.
204) Equivalent to FLT_RADIX.
205) Distinguishes types with bases other than 2 (e.g. BCD).
206) Equivalent to FLT_EPSILON,DBL_EPSILON,LDBL_EPSILON.
207) Rounding error is described in ISO/IEC 10967-1 Language independent arithmetic - Part 1 Section 5.2.8 and Annex A
Rationale Section A.5.2.8 - Rounding constants.
§ 18.3.2.4 440
c
ISO/IEC N????
27 Minimum negative integer such that radix raised to the power of one less than that integer is a
normalized floating point number.208
28 Meaningful for all floating point types.
static constexpr int min_exponent10;
29 Minimum negative integer such that 10 raised to that power is in the range of normalized floating
point numbers.209
30 Meaningful for all floating point types.
static constexpr int max_exponent;
31 Maximum positive integer such that radix raised to the power one less than that integer is a repre-
sentable finite floating point number.210
32 Meaningful for all floating point types.
static constexpr int max_exponent10;
33 Maximum positive integer such that 10 raised to that power is in the range of representable finite
floating point numbers.211
34 Meaningful for all floating point types.
static constexpr bool has_infinity;
35 True if the type has a representation for positive infinity.
36 Meaningful for all floating point types.
37 Shall be true for all specializations in which is_iec559 != false.
static constexpr bool has_quiet_NaN;
38 True if the type has a representation for a quiet (non-signaling) “Not a Number.212
39 Meaningful for all floating point types.
40 Shall be true for all specializations in which is_iec559 != false.
static constexpr bool has_signaling_NaN;
41 True if the type has a representation for a signaling “Not a Number.213
42 Meaningful for all floating point types.
43 Shall be true for all specializations in which is_iec559 != false.
208) Equivalent to FLT_MIN_EXP,DBL_MIN_EXP,LDBL_MIN_EXP.
209) Equivalent to FLT_MIN_10_EXP,DBL_MIN_10_EXP,LDBL_MIN_10_EXP.
210) Equivalent to FLT_MAX_EXP,DBL_MAX_EXP,LDBL_MAX_EXP.
211) Equivalent to FLT_MAX_10_EXP,DBL_MAX_10_EXP,LDBL_MAX_10_EXP.
212) Required by LIA-1.
213) Required by LIA-1.
§ 18.3.2.4 441
c
ISO/IEC N????
static constexpr float_denorm_style has_denorm;
44 denorm_present if the type allows denormalized values (variable number of exponent bits)214,denorm_-
absent if the type does not allow denormalized values, and denorm_indeterminate if it is indetermi-
nate at compile time whether the type allows denormalized values.
45 Meaningful for all floating point types.
static constexpr bool has_denorm_loss;
46 True if loss of accuracy is detected as a denormalization loss, rather than as an inexact result.215
static constexpr T infinity() noexcept;
47 Representation of positive infinity, if available.216
48 Meaningful for all specializations for which has_infinity != false. Required in specializations for
which is_iec559 != false.
static constexpr T quiet_NaN() noexcept;
49 Representation of a quiet “Not a Number,” if available.217
50 Meaningful for all specializations for which has_quiet_NaN != false. Required in specializations for
which is_iec559 != false.
static constexpr T signaling_NaN() noexcept;
51 Representation of a signaling “Not a Number,” if available.218
52 Meaningful for all specializations for which has_signaling_NaN != false. Required in specializations
for which is_iec559 != false.
static constexpr T denorm_min() noexcept;
53 Minimum positive denormalized value.219
54 Meaningful for all floating point types.
55 In specializations for which has_denorm == false, returns the minimum positive normalized value.
static constexpr bool is_iec559;
56 True if and only if the type adheres to IEC 559 standard.220
57 Meaningful for all floating point types.
214) Required by LIA-1.
215) See IEC 559.
216) Required by LIA-1.
217) Required by LIA-1.
218) Required by LIA-1.
219) Required by LIA-1.
220) International Electrotechnical Commission standard 559 is the same as IEEE 754.
§ 18.3.2.4 442
c
ISO/IEC N????
static constexpr bool is_bounded;
58 True if the set of values representable by the type is finite.221 [Note: All fundamental types (3.9.1)
are bounded. This member would be false for arbitrary precision types. — end note ]
59 Meaningful for all specializations.
static constexpr bool is_modulo;
60 True if the type is modulo.222 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.
61 On most machines, this is false for floating types, true for unsigned integers, and true for signed
integers.
62 Meaningful for all specializations.
static constexpr bool traps;
63 true if, at program startup, there exists a value of the type that would cause an arithmetic operation
using that value to trap.223
64 Meaningful for all specializations.
static constexpr bool tinyness_before;
65 true if tinyness is detected before rounding.224
66 Meaningful for all floating point types.
static constexpr float_round_style round_style;
67 The rounding style for the type.225
68 Meaningful for all floating point types. Specializations for integer types shall return round_toward_-
zero.
18.3.2.5 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
};
}
221) Required by LIA-1.
222) Required by LIA-1.
223) Required by LIA-1.
224) Refer to IEC 559. Required by LIA-1.
225) Equivalent to FLT_ROUNDS. Required by LIA-1.
§ 18.3.2.5 443
c
ISO/IEC N????
1The 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
18.3.2.6 Type float_denorm_style [denorm.style]
namespace std {
enum float_denorm_style {
denorm_indeterminate = -1,
denorm_absent = 0,
denorm_present = 1
};
}
1The presence or absence of denormalization (variable number of exponent bits) is characterized by the values:
denorm_indeterminate if it cannot be determined whether or not the type allows denormalized values
denorm_absent if the type does not allow denormalized values
denorm_present if the type does allow denormalized values
18.3.2.7 numeric_limits specializations [numeric.special]
1All members shall be provided for all specializations. However, many values are only required to be mean-
ingful 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.
2[Example:
namespace std {
template<> class numeric_limits<float> {
public:
static constexpr bool is_specialized = true;
inline static constexpr float min() noexcept { return 1.17549435E-38F; }
inline static constexpr float max() noexcept { return 3.40282347E+38F; }
inline 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;
inline static constexpr float epsilon() noexcept { return 1.19209290E-07F; }
inline static constexpr float round_error() noexcept { return 0.5F; }
static constexpr int min_exponent = -125;
static constexpr int min_exponent10 = - 37;
§ 18.3.2.7 444
c
ISO/IEC N????
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;
inline static constexpr float infinity() noexcept { return value ; }
inline static constexpr float quiet_NaN() noexcept { return value ; }
inline static constexpr float signaling_NaN() noexcept { return value ; }
inline 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 ]
3The 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;
§ 18.3.2.7 445
c
ISO/IEC N????
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;
};
}
18.3.3 C library [c.limits]
1Table 31 describes the header <climits>.
Table 31 — Header <climits> synopsis
Type Name(s)
Values:
CHAR_BIT INT_MAX LONG_MAX SCHAR_MIN SHRT_MIN ULLONG_MAX
CHAR_MAX LLONG_MAX LONG_MIN SCHAR_MAX UCHAR_MAX ULONG_MAX
CHAR_MIN LLONG_MIN MB_LEN_MAX SHRT_MAX UINT_MAX USHRT_MAX
INT_MIN
2The contents are the same as the Standard C 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 ]
3Table 32 describes the header <cfloat>.
Table 32 — Header <cfloat> synopsis
Type Name(s)
Values:
DBL_DIG DBL_MIN_EXP FLT_MAX_EXP LDBL_MANT_DIG
DBL_EPSILON DECIMAL_DIG FLT_MIN LDBL_MAX_10_EXP
DBL_MANT_DIG FLT_DIG FLT_MIN_10_EXP LDBL_MAX_EXP
DBL_MAX FLT_EPSILON FLT_MIN_EXP LDBL_MAX
DBL_MAX_10_EXP FLT_EVAL_METHOD FLT_RADIX LDBL_MIN
DBL_MAX_EXP FLT_MANT_DIG FLT_ROUNDS LDBL_MIN_10_EXP
DBL_MIN FLT_MAX LDBL_DIG LDBL_MIN_EXP
DBL_MIN_10_EXP FLT_MAX_10_EXP LDBL_EPSILON
4The contents are the same as the Standard C library header <float.h>.
See also: ISO C 7.1.5, 5.2.4.2.2, 5.2.4.2.1.
18.4 Integer types [cstdint]
18.4.1 Header <cstdint> synopsis [cstdint.syn]
§ 18.4.1 446
c
ISO/IEC N????
namespace std {
typedef signed integer type int8_t; // optional
typedef signed integer type int16_t; // optional
typedef signed integer type int32_t; // optional
typedef signed integer type int64_t; // optional
typedef signed integer type int_fast8_t;
typedef signed integer type int_fast16_t;
typedef signed integer type int_fast32_t;
typedef signed integer type int_fast64_t;
typedef signed integer type int_least8_t;
typedef signed integer type int_least16_t;
typedef signed integer type int_least32_t;
typedef signed integer type int_least64_t;
typedef signed integer type intmax_t;
typedef signed integer type intptr_t; // optional
typedef unsigned integer type uint8_t; // optional
typedef unsigned integer type uint16_t; // optional
typedef unsigned integer type uint32_t; // optional
typedef unsigned integer type uint64_t; // optional
typedef unsigned integer type uint_fast8_t;
typedef unsigned integer type uint_fast16_t;
typedef unsigned integer type uint_fast32_t;
typedef unsigned integer type uint_fast64_t;
typedef unsigned integer type uint_least8_t;
typedef unsigned integer type uint_least16_t;
typedef unsigned integer type uint_least32_t;
typedef unsigned integer type uint_least64_t;
typedef unsigned integer type uintmax_t;
typedef unsigned integer type uintptr_t; // optional
}// namespace std
1The 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
2The header defines all functions, types, and macros the same as 7.18 in the C standard. [ Note: The macros
defined by <cstdint> are provided unconditionally. In particular, the symbols __STDC_LIMIT_MACROS and
__STDC_CONSTANT_MACROS (mentioned in footnotes 219, 220, and 222 in the C standard) play no role in
§ 18.5 447
c
ISO/IEC N????
Table 33 — Header <cstdlib> synopsis
Type Name(s)
Macros:EXIT_FAILURE EXIT_SUCCESS
Functions:_Exit abort atexit
at_quick_exit exit quick_exit
C++.— end note ]
18.5 Start and termination [support.start.term]
1Table 33 describes some of the contents of the header <cstdlib>.
2The contents are the same as the Standard C library header <stdlib.h>, with the following changes:
[[noreturn]] void _Exit(int status) noexcept;
3The function _Exit(int status) has additional behavior in this International Standard:
The program is terminated without executing destructors for objects of automatic, thread, or
static storage duration and without calling functions passed to atexit() (3.6.3).
[[noreturn]] void abort(void) noexcept;
4The function abort() has additional behavior in this International Standard:
The program is terminated without executing destructors for objects of automatic, thread, or
static storage duration and without calling functions passed to atexit() (3.6.3).
extern "C" int atexit(void (*f)(void)) noexcept;
extern "C++" int atexit(void (*f)(void)) noexcept;
5Effects: The atexit() functions register the function pointed to by fto be called without arguments
at normal program termination. It is unspecified whether a call to atexit() that does not happen
before (1.10) a call to exit() will succeed. [ Note: The atexit() functions do not introduce a data
race (17.6.5.9). — end note ]
6Implementation limits: The implementation shall support the registration of at least 32 functions.
7Returns: The atexit() function returns zero if the registration succeeds, non-zero if it fails.
[[noreturn]] void exit(int status)
8The function exit() has additional behavior in this International Standard:
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.226 See 3.6.3 for the order of destructions and calls. (Automatic objects are not
destroyed as a result of calling exit().)227
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 (15.5.1).
226) A function is called for every time it is registered.
227) Objects with automatic storage duration are all destroyed in a program whose function main() contains no automatic
objects and executes the call to exit(). Control can be transferred directly to such a main() by throwing an exception that is
caught in main().
§ 18.5 448
c
ISO/IEC N????
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.228
extern "C" int at_quick_exit(void (*f)(void)) noexcept;
extern "C++" int at_quick_exit(void (*f)(void)) noexcept;
9Effects: The at_quick_exit() functions register the function pointed to by fto be called without
arguments when quick_exit is called. It is unspecified whether a call to at_quick_exit() that
does not happen before (1.10) all calls to quick_exit will succeed. [ Note: The at_quick_exit()
functions do not introduce a data race (17.6.5.9). — 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 ]
10 Implementation limits: The implementation shall support the registration of at least 32 functions.
11 Returns: Zero if the registration succeeds, non-zero if it fails.
[[noreturn]] void quick_exit(int status) noexcept;
12 Effects: Functions registered by calls to at_quick_exit are called in the reverse order of their reg-
istration, 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: at_quick_exit
may call a registered function from 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. See: ISO C 7.20.4.4. — end note ]
See also: 3.6,3.6.3, ISO C 7.10.4.
18.6 Dynamic memory management [support.dynamic]
1The header <new> defines several functions that manage the allocation of dynamic storage in a program. It
also defines components for reporting storage management errors.
Header <new> synopsis
namespace std {
class bad_alloc;
class bad_array_length;
class bad_array_new_length;
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
new_handler get_new_handler() noexcept;
new_handler set_new_handler(new_handler new_p) noexcept;
228) The macros EXIT_FAILURE and EXIT_SUCCESS are defined in <cstdlib>.
§ 18.6 449
c
ISO/IEC N????
}
void* operator new(std::size_t size);
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size);
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, 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: 1.7,3.7.4,5.3.4,5.3.5,12.5,20.8.
18.6.1 Storage allocation and deallocation [new.delete]
1Except where otherwise specified, the provisions of (3.7.4) apply to the library versions of operator new
and operator delete.
18.6.1.1 Single-object forms [new.delete.single]
void* operator new(std::size_t size);
1Effects: The allocation function (3.7.4.1) called by a new-expression (5.3.4) to allocate size bytes of
storage suitably aligned to represent any object of that size.
2Replaceable: a C++ program may define a function with this function signature that displaces the
default version defined by the C++ standard library.
3Required behavior: Return a non-null pointer to suitably aligned storage (3.7.4), or else throw a bad_-
alloc exception. This requirement is binding on a replacement version of this function.
4Default behavior:
Executes a loop: Within the loop, the function first attempts to allocate the requested storage.
Whether the attempt involves a call to the Standard C library function malloc is unspecified.
Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the current
new_handler (18.6.2.6) is a null pointer value, throws bad_alloc.
Otherwise, the function calls the current new_handler function (18.6.2.4). 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;
5Effects: Same as above, except that it is 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.
6Replaceable: a C++ program may define a function with this function signature that displaces the
default version defined by the C++ standard library.
7Required behavior: Return a non-null pointer to suitably aligned storage (3.7.4), or else return a null
pointer. This nothrow version of operator new returns a pointer obtained as if acquired from the
(possibly replaced) ordinary version. This requirement is binding on a replacement version of this
function.
§ 18.6.1.1 450
c
ISO/IEC N????
8Default behavior: Calls operator new(size). If the call returns normally, returns the result of that
call. Otherwise, returns a null pointer.
9[Example:
T* p1 = new T; // throws bad_alloc if it fails
T* p2 = new(nothrow) T; // returns 0if it fails
— end example ]
void operator delete(void* ptr) noexcept;
10 Effects: The deallocation function (3.7.4.2) called by a delete-expression to render the value of ptr
invalid.
11 Replaceable: a C++ program may define a function with this function signature that displaces the
default version defined by the C++ standard library.
12 Requires: ptr shall be a null pointer or its value shall be a value returned by an earlier call to the (possi-
bly replaced) operator new(std::size_t) or operator new(std::size_t,const std::nothrow_-
t&) which has not been invalidated by an intervening call to operator delete(void*).
13 Requires: If an implementation has strict pointer safety (3.7.4.3) then ptr shall be a safely-derived
pointer.
14 Default behavior: If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the earlier
call to operator new.
15 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 calloc,malloc, or realloc, declared in <cstdlib>.
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
16 Effects: The deallocation function (3.7.4.2) 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.
17 Replaceable: a C++ program may define a function with this function signature that displaces the
default version defined by the C++ standard library.
18 Requires: If an implementation has strict pointer safety (3.7.4.3) then ptr shall be a safely-derived
pointer.
19 Default behavior: calls operator delete(ptr).
18.6.1.2 Array forms [new.delete.array]
void* operator new[](std::size_t size);
1Effects: The allocation function (3.7.4.1) called by the array form of a new-expression (5.3.4) to allocate
size bytes of storage suitably aligned to represent any array object of that size or smaller.229
2Replaceable: a C++ program can define a function with this function signature that displaces the
default version defined by the C++ standard library.
229) It is not the direct responsibility of operator new[](std::size_t) or operator delete[](void*) 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[](std::size_t) to obtain space to store
supplemental information.
§ 18.6.1.2 451
c
ISO/IEC N????
3Required behavior: Same as for operator new(std::size_t). This requirement is binding on a re-
placement version of this function.
4Default behavior: Returns operator new(size).
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
5Effects: Same as above, except that it is 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.
6Replaceable: a C++ program can define a function with this function signature that displaces the
default version defined by the C++ standard library.
7Required behavior: Return a non-null pointer to suitably aligned storage (3.7.4), or return a null
pointer. This requirement is binding on a replacement version of this function.
8Default behavior: Calls operator new[](size). If the call returns normally, returns the result of that
call. Otherwise, returns a null pointer.
void operator delete[](void* ptr) noexcept;
9Effects: The deallocation function (3.7.4.2) called by the array form of a delete-expression to render
the value of ptr invalid.
10 Replaceable: a C++ program can define a function with this function signature that displaces the
default version defined by the C++ standard library.
11 Requires: ptr shall be a null pointer or its value shall be the value returned by an earlier call to
operator new[](std::size_t) or operator new[](std::size_t,const std::nothrow_t&) which
has not been invalidated by an intervening call to operator delete[](void*).
12 Requires: If an implementation has strict pointer safety (3.7.4.3) then ptr shall be a safely-derived
pointer.
13 Default behavior: Calls operator delete(ptr).
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
14 Effects: The deallocation function (3.7.4.2) 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.
15 Replaceable: a C++ program may define a function with this function signature that displaces the
default version defined by the C++ standard library.
16 Requires: If an implementation has strict pointer safety (3.7.4.3) then ptr shall be a safely-derived
pointer.
17 Default behavior: calls operator delete[](ptr).
18.6.1.3 Placement forms [new.delete.placement]
1These functions are reserved, a C++ program may not define functions that displace the versions in the
Standard C++ library (17.6.4). The provisions of (3.7.4) do not apply to these reserved placement forms of
operator new and operator delete.
void* operator new(std::size_t size, void* ptr) noexcept;
§ 18.6.1.3 452
c
ISO/IEC N????
2Returns: ptr.
3Remarks: Intentionally performs no other action.
4[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;
5Returns: ptr.
6Remarks: Intentionally performs no other action.
void operator delete(void* ptr, void*) noexcept;
7Effects: Intentionally performs no action.
8Requires: If an implementation has strict pointer safety (3.7.4.3) then ptr shall be a safely-derived
pointer.
9Remarks: 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 (5.3.4).
void operator delete[](void* ptr, void*) noexcept;
10 Effects: Intentionally performs no action.
11 Requires: If an implementation has strict pointer safety (3.7.4.3) then ptr shall be a safely-derived
pointer.
12 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 (5.3.4).
18.6.1.4 Data races [new.delete.dataraces]
1For purposes of determining the existence of data races, the library versions of operator new, user replace-
ment versions of global operator new, the C standard library functions calloc and malloc, the library
versions of operator delete, user replacement versions of operator delete, the C standard library func-
tion free, and the C standard library function realloc shall not introduce a data race (17.6.5.9). 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 (1.10) the next allocation (if any) in this order.
18.6.2 Storage allocation errors [alloc.errors]
18.6.2.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;
virtual const char* what() const noexcept;
};
}
§ 18.6.2.1 453
c
ISO/IEC N????
1The class bad_alloc defines the type of objects thrown as exceptions by the implementation to report a
failure to allocate storage.
bad_alloc() noexcept;
2Effects: Constructs an object of class bad_alloc.
3Remarks: The result of calling what() on the newly constructed object is implementation-defined.
bad_alloc(const bad_alloc&) noexcept;
bad_alloc& operator=(const bad_alloc&) noexcept;
4Effects: Copies an object of class bad_alloc.
virtual const char* what() const noexcept;
5Returns: An implementation-defined ntbs.
18.6.2.2 Class bad_array_length [bad.array.length]
namespace std {
class bad_array_length : public bad_alloc {
public:
bad_array_length() noexcept;
};
}
1The class bad_array_length defines the type of objects thrown as exceptions by the implementation to
report an attempt to allocate an array of runtime bound with a size less than or equal to zero or greater
than an implementation-defined limit (8.3.4).
bad_array_length() noexcept;
2Effects: constructs an object of class bad_array_length.
3Remarks: the result of calling what() on the newly constructed object is implementation-defined.
18.6.2.3 Class bad_array_new_length [new.badlength]
namespace std {
class bad_array_new_length : public bad_alloc {
public:
bad_array_new_length() noexcept;
};
}
1The 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 (5.3.4).
bad_array_new_length() noexcept;
2Effects: constructs an object of class bad_array_new_length.
3Remarks: the result of calling what() on the newly constructed object is implementation-defined.
§ 18.6.2.3 454
c
ISO/IEC N????
18.6.2.4 Type new_handler [new.handler]
typedef void (*new_handler)();
1The type of a handler function to be called by operator new() or operator new[]() (18.6.1) when
they cannot satisfy a request for additional storage.
2Required behavior: Anew_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;
18.6.2.5 set_new_handler [set.new.handler]
new_handler set_new_handler(new_handler new_p) noexcept;
1Effects: Establishes the function designated by new_p as the current new_handler.
2Returns: The previous new_handler.
3Remarks: The initial new_handler is a null pointer.
18.6.2.6 get_new_handler [get.new.handler]
new_handler get_new_handler() noexcept;
1Returns: The current new_handler. [ Note: This may be a null pointer value. — end note ]
18.7 Type identification [support.rtti]
1The header <typeinfo> defines a type associated with type information generated by the implementation.
It also defines two types for reporting dynamic type identification errors.
Header <typeinfo> synopsis
namespace std {
class type_info;
class bad_cast;
class bad_typeid;
}
See also: 5.2.7,5.2.8.
18.7.1 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
};
}
§ 18.7.1 455
c
ISO/IEC N????
1The 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;
2Effects: Compares the current object with rhs.
3Returns: true if the two values describe the same type.
bool operator!=(const type_info& rhs) const noexcept;
4Returns: !(*this == rhs).
bool before(const type_info& rhs) const noexcept;
5Effects: Compares the current object with rhs.
6Returns: true if *this precedes rhs in the implementation’s collation order.
size_t hash_code() const noexcept;
7Returns: 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.
8Remark: an implementation should return different values for two type_info objects which do not
compare equal.
const char* name() const noexcept;
9Returns: An implementation-defined ntbs.
10 Remarks: The message may be a null-terminated multibyte string (17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3,22.4.1.4)
18.7.2 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;
virtual const char* what() const noexcept;
};
}
1The class bad_cast defines the type of objects thrown as exceptions by the implementation to report the
execution of an invalid dynamic-cast expression (5.2.7).
bad_cast() noexcept;
2Effects: Constructs an object of class bad_cast.
3Remarks: The result of calling what() on the newly constructed object is implementation-defined.
§ 18.7.2 456
c
ISO/IEC N????
bad_cast(const bad_cast&) noexcept;
bad_cast& operator=(const bad_cast&) noexcept;
4Effects: Copies an object of class bad_cast.
virtual const char* what() const noexcept;
5Returns: An implementation-defined ntbs.
6Remarks: The message may be a null-terminated multibyte string (17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3,22.4.1.4)
18.7.3 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;
virtual const char* what() const noexcept;
};
}
1The class bad_typeid defines the type of objects thrown as exceptions by the implementation to report a
null pointer in a typeid expression (5.2.8).
bad_typeid() noexcept;
2Effects: Constructs an object of class bad_typeid.
3Remarks: The result of calling what() on the newly constructed object is implementation-defined.
bad_typeid(const bad_typeid&) noexcept;
bad_typeid& operator=(const bad_typeid&) noexcept;
4Effects: Copies an object of class bad_typeid.
virtual const char* what() const noexcept;
5Returns: An implementation-defined ntbs.
6Remarks: The message may be a null-terminated multibyte string (17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3,22.4.1.4)
18.8 Exception handling [support.exception]
1The header <exception> defines several types and functions related to the handling of exceptions in a C++
program.
Header <exception> synopsis
namespace std {
class exception;
class bad_exception;
class nested_exception;
typedef void (*unexpected_handler)();
§ 18.8 457
c
ISO/IEC N????
unexpected_handler get_unexpected() noexcept;
unexpected_handler set_unexpected(unexpected_handler f) noexcept;
[[noreturn]] void unexpected();
typedef void (*terminate_handler)();
terminate_handler get_terminate() noexcept;
terminate_handler set_terminate(terminate_handler f) noexcept;
[[noreturn]] void terminate() noexcept;
bool uncaught_exception() noexcept;
typedef unspecified exception_ptr;
exception_ptr current_exception() noexcept;
[[noreturn]] void rethrow_exception(exception_ptr p);
template<class E> exception_ptr make_exception_ptr(E e) noexcept;
[[noreturn]] template <class T> void throw_with_nested(T&& t);
template <class E> void rethrow_if_nested(const E& e);
}
See also: 15.5.
18.8.1 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;
};
}
1The 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.
2Each standard library class Tthat derives from class exception shall have a publicly accessible copy con-
structor 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 Tand lhs is a copy of rhs, then strcmp(lhs.what(), rhs.what()) shall equal 0.
exception() noexcept;
3Effects: Constructs an object of class exception.
4Remarks: Does not throw any exceptions.
exception(const exception& rhs) noexcept;
exception& operator=(const exception& rhs) noexcept;
5Effects: Copies an exception object.
6Postcondition: If *this and rhs both have dynamic type exception then strcmp(what(), rhs.what())
shall equal 0.
§ 18.8.1 458
c
ISO/IEC N????
virtual ~exception();
7Effects: Destroys an object of class exception.
8Remarks: Does not throw any exceptions.
virtual const char* what() const noexcept;
9Returns: An implementation-defined ntbs.
10 Remarks: The message may be a null-terminated multibyte string (17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3,22.4.1.4). 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.
18.8.2 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;
virtual const char* what() const noexcept;
};
}
1The class bad_exception defines the type of objects thrown as described in (15.5.2).
bad_exception() noexcept;
2Effects: Constructs an object of class bad_exception.
3Remarks: The result of calling what() on the newly constructed object is implementation-defined.
bad_exception(const bad_exception&) noexcept;
bad_exception& operator=(const bad_exception&) noexcept;
4Effects: Copies an object of class bad_exception.
virtual const char* what() const noexcept;
5Returns: An implementation-defined ntbs.
6Remarks: The message may be a null-terminated multibyte string (17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3,22.4.1.4).
18.8.3 Abnormal termination [exception.terminate]
18.8.3.1 Type terminate_handler [terminate.handler]
typedef void (*terminate_handler)();
1The type of a handler function to be called by std::terminate() when terminating exception pro-
cessing.
2Required behavior: Aterminate_handler shall terminate execution of the program without returning
to the caller.
3Default behavior: The implementation’s default terminate_handler calls abort().
§ 18.8.3.1 459
c
ISO/IEC N????
18.8.3.2 set_terminate [set.terminate]
terminate_handler set_terminate(terminate_handler f) noexcept;
1Effects: Establishes the function designated by fas the current handler function for terminating
exception processing.
2Remarks: It is unspecified whether a null pointer value designates the default terminate_handler.
3Returns: The previous terminate_handler.
18.8.3.3 get_terminate [get.terminate]
terminate_handler get_terminate() noexcept;
1Returns: The current terminate_handler. [ Note: This may be a null pointer value. — end note ]
18.8.3.4 terminate [terminate]
[[noreturn]] void terminate() noexcept;
1Remarks: Called by the implementation when exception handling must be abandoned for any of several
reasons (15.5.1), in effect immediately after throwing the exception. May also be called directly by the
program.
2Effects: Calls the current terminate_handler function. [ Note: A default terminate_handler is
always considered a callable handler in this context. — end note ]
18.8.4 uncaught_exception [uncaught]
bool uncaught_exception() noexcept;
1Returns: true after the current thread has initialized an exception object (15.1) until a handler for
the exception (including std::unexpected() or std::terminate()) is activated (15.3). [ Note: This
includes stack unwinding (15.2). — end note ]
2Remarks: When uncaught_exception() returns true, throwing an exception can result in a call of
std::terminate() (15.5.1).
18.8.5 Exception propagation [propagation]
typedef unspecified exception_ptr;
1The type exception_ptr can be used to refer to an exception object.
2exception_ptr shall satisfy the requirements of NullablePointer (17.6.3.3).
3Two non-null values of type exception_ptr are equivalent and compare equal if and only if they refer
to the same exception.
4The default constructor of exception_ptr produces the null value of the type.
5exception_ptr shall not be implicitly convertible to any arithmetic, enumeration, or pointer type.
6[Note: An implementation might use a reference-counted smart pointer as exception_ptr.— end
note ]
7For 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 ]
§ 18.8.5 460
c
ISO/IEC N????
exception_ptr current_exception() noexcept;
8Returns: An exception_ptr object that refers to the currently handled exception (15.3) 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);
9Requires: pshall not be a null pointer.
10 Throws: the exception object to which prefers.
template<class E> exception_ptr make_exception_ptr(E e) noexcept;
11 Effects: Creates an exception_ptr object that refers to a copy of e, as if
try {
throw e;
} catch(...) {
return current_exception();
}
12 [Note: This function is provided for convenience and efficiency reasons. — end note ]
18.8.6 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;
};
[[noreturn]] template<class T> void throw_with_nested(T&& t);
template <class E> void rethrow_if_nested(const E& e);
}
1The 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.
2[Note: nested_exception has a virtual destructor to make it a polymorphic class. Its presence can be
tested for with dynamic_cast.— end note ]
§ 18.8.6 461
c
ISO/IEC N????
nested_exception() noexcept;
3Effects: The constructor calls current_exception() and stores the returned value.
[[noreturn]] void rethrow_nested() const;
4Effects: 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;
5Returns: The stored exception captured by this nested_exception object.
[[noreturn]] template <class T> void throw_with_nested(T&& t);
Let Ube remove_reference<T>::type.
6Requires: Ushall be CopyConstructible.
7Throws: if Uis a non-union class type not derived from nested_exception, an exception of un-
specified type that is publicly derived from both Uand nested_exception and constructed from
std::forward<T>(t), otherwise std::forward<T>(t).
template <class E> void rethrow_if_nested(const E& e);
8Effects: If the dynamic type of eis publicly and unambiguously derived from nested_exception, calls
dynamic_cast<const nested_exception&>(e).rethrow_nested().
18.9 Initializer lists [support.initlist]
1The header <initializer_list> defines one type.
Header <initializer_list> synopsis
namespace std {
template<class E> class initializer_list {
public:
typedef E value_type;
typedef const E& reference;
typedef const E& const_reference;
typedef size_t size_type;
typedef const E* iterator;
typedef const E* const_iterator;
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
};
// 18.9.3 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;
}
§ 18.9 462
c
ISO/IEC N????
2An 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 8.5.4. Copying an initializer list does
not copy the underlying elements. — end note ]
18.9.1 Initializer list constructors [support.initlist.cons]
constexpr initializer_list() noexcept;
1Effects: constructs an empty initializer_list object.
2Postcondition: size() == 0
18.9.2 Initializer list access [support.initlist.access]
constexpr const E* begin() const noexcept;
1Returns: 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;
2Returns: begin() + size()
constexpr size_t size() const noexcept;
3Returns: The number of elements in the array.
4Complexity: constant time.
18.9.3 Initializer list range access [support.initlist.range]
template<class E> constexpr const E* begin(initializer_list<E> il) noexcept;
1Returns: il.begin().
template<class E> constexpr const E* end(initializer_list<E> il) noexcept;
2Returns: il.end().
18.10 Other runtime support [support.runtime]
1Headers <csetjmp> (nonlocal jumps), <csignal> (signal handling), <cstdalign> (alignment), <cstdarg>
(variable arguments), <cstdbool> (_ _ bool_true_false_are_defined). <cstdlib> (runtime environment
getenv(), system()), and <ctime> (system clock clock(), time()) provide further compatibility with C
code.
2The contents of these headers are the same as the Standard C library headers <setjmp.h>,<signal.h>,
<stdalign.h>,<stdarg.h>,<stdbool.h>,<stdlib.h>, and <time.h>, respectively, with the following
changes:
3The 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 identifier of the rightmost parameter
in the variable parameter list of the function definition (the one just before the ...).230 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.
230) Note that va_start is required to work as specified even if unary operator& is overloaded for the type of parmN.
§ 18.10 463
c
ISO/IEC N????
See also: ISO C 4.8.1.1.
4The 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.10.4, 7.8, 7.6, 7.12.
5Calls to the function getenv shall not introduce a data race (17.6.5.9) provided that nothing modifies the
environment. [ Note: Calls to the POSIX functions setenv and putenv modify the environment. — end
note ]
6A call to the setlocale function 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.
7The header <cstdalign> and the header <stdalign.h> shall not define a macro named alignas.
8The header <cstdbool> and the header <stdbool.h> shall not define macros named bool,true, or false.
9The common subset of the C and C++ languages consists of all declarations, definitions, and expressions
that may appear in a well formed C++ program and also in a conforming C program. A POF (“plain
old function”) is a function that uses only features from this common subset, and that does not directly
or indirectly use any function that is not a POF, except that it may use functions defined in Clause 29
that are not member functions. All signal handlers shall have C linkage. A POF that could be used as
a signal handler in a conforming C program does not produce undefined behavior when used as a signal
handler in a C++ program. The behavior of any other function used as a signal handler in a C++ program
is implementation-defined.231
Table 34 — Header <csetjmp> synopsis
Type Name(s)
Macro:setjmp
Type:jmp_buf
Function:longjmp
Table 35 — Header <csignal> synopsis
Type Name(s)
Macros:SIGABRT SIGILL SIGSEGV SIG_DFL
SIG_IGN SIGFPE SIGINT SIGTERM SIG_ERR
Type:sig_atomic_t
Functions:raise signal
Table 36 — Header <cstdalign> synopsis
Type Name(s)
Macro:__alignas_is_defined
231) In particular, a signal handler using exception handling is very likely to have problems. Also, invoking std::exit may cause
destruction of objects, including those of the standard library implementation, which, in general, yields undefined behavior in
a signal handler (see 1.9).
§ 18.10 464
c
ISO/IEC N????
Table 37 — Header <cstdarg> synopsis
Type Name(s)
Macros:va_arg va_end va_start
va_copy
Type:va_list
Table 38 — Header <cstdbool> synopsis
Type Name(s)
Macro:__bool_true_false_are_defined
Table 39 — Header <cstdlib> synopsis
Type Name(s)
Functions:getenv system
Table 40 — Header <ctime> synopsis
Type Name(s)
Macro:CLOCKS_PER_SEC
Type:clock_t
Function:clock
§ 18.10 465
c
ISO/IEC N????
19 Diagnostics library [diagnostics]
19.1 General [diagnostics.general]
1This Clause describes components that C++ programs may use to detect and report error conditions.
2The following subclauses describe components for reporting several kinds of exceptional conditions, docu-
menting program assertions, and a global variable for error number codes, as summarized in Table 41.
Table 41 — Diagnostics library summary
Subclause Header(s)
19.2 Exception classes <stdexcept>
19.3 Assertions <cassert>
19.4 Error numbers <cerrno>
19.5 System error support <system_error>
19.2 Exception classes [std.exceptions]
1The Standard C++ library provides classes to be used to report certain errors (17.6.5.12) in C++ programs.
In the error model reflected in these classes, errors are divided into two broad categories: logic errors and
runtime errors.
2The distinguishing characteristic of logic errors is that they are due to errors in the internal logic of the
program. In theory, they are preventable.
3By 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.
Header <stdexcept> synopsis
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;
}
19.2.1 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);
};
}
§ 19.2.1 466
c
ISO/IEC N????
1The class logic_error defines the type of objects thrown as exceptions to report errors presumably de-
tectable before the program executes, such as violations of logical preconditions or class invariants.
logic_error(const string& what_arg);
2Effects: Constructs an object of class logic_error.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
logic_error(const char* what_arg);
4Effects: Constructs an object of class logic_error.
5Postcondition: strcmp(what(), what_arg) == 0.
19.2.2 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);
};
}
1The class domain_error defines the type of objects thrown as exceptions by the implementation to report
domain errors.
domain_error(const string& what_arg);
2Effects: Constructs an object of class domain_error.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
domain_error(const char* what_arg);
4Effects: Constructs an object of class domain_error.
5Postcondition: strcmp(what(), what_arg) == 0.
19.2.3 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);
};
}
1The class invalid_argument defines the type of objects thrown as exceptions to report an invalid argument.
invalid_argument(const string& what_arg);
2Effects: Constructs an object of class invalid_argument.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
invalid_argument(const char* what_arg);
4Effects: Constructs an object of class invalid_argument.
5Postcondition: strcmp(what(), what_arg) == 0.
§ 19.2.3 467
c
ISO/IEC N????
19.2.4 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);
};
}
1The 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);
2Effects: Constructs an object of class length_error.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
length_error(const char* what_arg);
4Effects: Constructs an object of class length_error.
5Postcondition: strcmp(what(), what_arg) == 0.
19.2.5 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);
};
}
1The 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);
2Effects: Constructs an object of class out_of_range.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
out_of_range(const char* what_arg);
4Effects: Constructs an object of class out_of_range.
5Postcondition: strcmp(what(), what_arg) == 0.
19.2.6 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);
};
}
§ 19.2.6 468
c
ISO/IEC N????
1The 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);
2Effects: Constructs an object of class runtime_error.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
runtime_error(const char* what_arg);
4Effects: Constructs an object of class runtime_error.
5Postcondition: strcmp(what(), what_arg) == 0.
19.2.7 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);
};
}
1The class range_error defines the type of objects thrown as exceptions to report range errors in internal
computations.
range_error(const string& what_arg);
2Effects: Constructs an object of class range_error.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
range_error(const char* what_arg);
4Effects: Constructs an object of class range_error.
5Postcondition: strcmp(what(), what_arg) == 0.
19.2.8 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);
};
}
1The class overflow_error defines the type of objects thrown as exceptions to report an arithmetic overflow
error.
overflow_error(const string& what_arg);
2Effects: Constructs an object of class overflow_error.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
overflow_error(const char* what_arg);
4Effects: Constructs an object of class overflow_error.
5Postcondition: strcmp(what(), what_arg) == 0.
§ 19.2.8 469
c
ISO/IEC N????
19.2.9 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);
};
}
1The class underflow_error defines the type of objects thrown as exceptions to report an arithmetic under-
flow error.
underflow_error(const string& what_arg);
2Effects: Constructs an object of class underflow_error.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
underflow_error(const char* what_arg);
4Effects: Constructs an object of class underflow_error.
5Postcondition: strcmp(what(), what_arg) == 0.
19.3 Assertions [assertions]
1The header <cassert>, described in (Table 42), provides a macro for documenting C++ program assertions
and a mechanism for disabling the assertion checks.
Table 42 — Header <cassert> synopsis
Type Name(s)
Macro:assert
2The contents are the same as the Standard C library header <assert.h>.
See also: ISO C 7.2.
19.4 Error numbers [errno]
1The header <cerrno> is described in Table 43. Its contents 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.
19.5 System error support [syserr]
1This 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.
2Components described in this subclause shall not change the value of errno (19.4). Implementations should
leave the error states provided by other libraries unchanged.
Header <system_error> synopsis
namespace std {
class error_category;
const error_category& generic_category() noexcept;
const error_category& system_category() noexcept;
class error_code;
§ 19.5 470
c
ISO/IEC N????
Table 43 — Header <cerrno> synopsis
Type Name(s)
Macros:ECONNREFUSED EIO ENODEV ENOTEMPTY ERANGE
E2BIG ECONNRESET EISCONN ENOENT ENOTRECOVERABLE EROFS
EACCES EDEADLK EISDIR ENOEXEC ENOTSOCK ESPIPE
EADDRINUSE EDESTADDRREQ ELOOP ENOLCK ENOTSUP ESRCH
EADDRNOTAVAIL EDOM EMFILE ENOLINK ENOTTY ETIME
EAFNOSUPPORT EEXIST EMLINK ENOMEM ENXIO ETIMEDOUT
EAGAIN EFAULT EMSGSIZE ENOMSG EOPNOTSUPP ETXTBSY
EALREADY EFBIG ENAMETOOLONG ENOPROTOOPT EOVERFLOW EWOULDBLOCK
EBADF EHOSTUNREACH ENETDOWN ENOSPC EOWNERDEAD EXDEV
EBADMSG EIDRM ENETRESET ENOSR EPERM errno
EBUSY EILSEQ ENETUNREACH ENOSTR EPIPE
ECANCELED EINPROGRESS ENFILE ENOSYS EPROTO
ECHILD EINTR ENOBUFS ENOTCONN EPROTONOSUPPORT
ECONNABORTED EINVAL ENODATA ENOTDIR EPROTOTYPE
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
§ 19.5 471
c
ISO/IEC N????
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
§ 19.5 472
c
ISO/IEC N????
};
template <> struct is_error_condition_enum<errc> : true_type { }
error_code make_error_code(errc e) noexcept;
error_condition make_error_condition(errc e) noexcept;
// 19.5.4 Comparison operators:
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;
// 19.5.5 Hash support
template <class T> struct hash;
template <> struct hash<error_code>;
}// namespace std
3The 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.
4The is_error_code_enum and is_error_condition_enum may be specialized for user-defined types to indi-
cate that such types are eligible for class error_code and class error_condition automatic conversions,
respectively.
19.5.1 Class error_category [syserr.errcat]
19.5.1.1 Class error_category overview [syserr.errcat.overview]
1The 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;
};
§ 19.5.1.1 473
c
ISO/IEC N????
const error_category& generic_category() noexcept;
const error_category& system_category() noexcept;
}// namespace std
19.5.1.2 Class error_category virtual members [syserr.errcat.virtuals]
virtual ~error_category();
1Effects: Destroys an object of class error_category.
virtual const char* name() const noexcept = 0;
2Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
3Returns: error_condition(ev, *this).
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
4Returns: default_error_condition(code) == condition.
virtual bool equivalent(const error_code& code, int condition) const noexcept;
5Returns: *this == code.category() && code.value() == condition.
virtual string message(int ev) const = 0;
6Returns: A string that describes the error condition denoted by ev.
19.5.1.3 Class error_category non-virtual members [syserr.errcat.nonvirtuals]
constexpr error_category() noexcept;
1Effects: Constructs an object of class error_category.
bool operator==(const error_category& rhs) const noexcept;
2Returns: this == &rhs.
bool operator!=(const error_category& rhs) const noexcept;
3Returns: !(*this == rhs).
bool operator<(const error_category& rhs) const noexcept;
4Returns: less<const error_category*>()(this, &rhs).
[Note: less (20.10.5) provides a total ordering for pointers. — end note ]
§ 19.5.1.3 474
c
ISO/IEC N????
19.5.1.4 Program defined classes derived from error_category [syserr.errcat.derived]
virtual const char* name() const noexcept = 0;
1Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
2Returns: An object of type error_condition that corresponds to ev.
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
3Returns: 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;
4Returns: true if, for the category of error represented by *this,code is considered equivalent to
condition; otherwise, false.
19.5.1.5 Error category objects [syserr.errcat.objects]
const error_category& generic_category() noexcept;
1Returns: 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.
2Remarks: 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;
3Returns: 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.
4Remarks: 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 unspeci-
fied. [ 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 ]
19.5.2 Class error_code [syserr.errcode]
19.5.2.1 Class error_code overview [syserr.errcode.overview]
1The 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 ]
§ 19.5.2.1 475
c
ISO/IEC N????
namespace std {
class error_code {
public:
// 19.5.2.2 constructors:
error_code() noexcept;
error_code(int val, const error_category& cat) noexcept;
template <class ErrorCodeEnum>
error_code(ErrorCodeEnum e) noexcept;
// 19.5.2.3 modifiers:
void assign(int val, const error_category& cat) noexcept;
template <class ErrorCodeEnum>
error_code& operator=(ErrorCodeEnum e) noexcept;
void clear() noexcept;
// 19.5.2.4 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
};
// 19.5.2.5 non-member functions:
error_code make_error_code(errc e) noexcept;
bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
template <class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
}// namespace std
19.5.2.2 Class error_code constructors [syserr.errcode.constructors]
error_code() noexcept;
1Effects: Constructs an object of type error_code.
2Postconditions: val_ == 0 and cat_ == &system_category().
error_code(int val, const error_category& cat) noexcept;
3Effects: Constructs an object of type error_code.
4Postconditions: val_ == val and cat_ == &cat.
template <class ErrorCodeEnum>
error_code(ErrorCodeEnum e) noexcept;
5Effects: Constructs an object of type error_code.
6Postconditions: *this == make_error_code(e).
7Remarks: This constructor shall not participate in overload resolution unless
is_error_code_enum<ErrorCodeEnum>::value is true.
§ 19.5.2.2 476
c
ISO/IEC N????
19.5.2.3 Class error_code modifiers [syserr.errcode.modifiers]
void assign(int val, const error_category& cat) noexcept;
1Postconditions: val_ == val and cat_ == &cat.
template <class ErrorCodeEnum>
error_code& operator=(ErrorCodeEnum e) noexcept;
2Postconditions: *this == make_error_code(e).
3Returns: *this.
4Remarks: This operator shall not participate in overload resolution unless
is_error_code_enum<ErrorCodeEnum>::value is true.
void clear() noexcept;
5Postconditions: value() == 0 and category() == system_category().
19.5.2.4 Class error_code observers [syserr.errcode.observers]
int value() const noexcept;
1Returns: val_.
const error_category& category() const noexcept;
2Returns: *cat_.
error_condition default_error_condition() const noexcept;
3Returns: category().default_error_condition(value()).
string message() const;
4Returns: category().message(value()).
explicit operator bool() const noexcept;
5Returns: value() != 0.
19.5.2.5 Class error_code non-member functions [syserr.errcode.nonmembers]
error_code make_error_code(errc e) noexcept;
1Returns: error_code(static_cast<int>(e), generic_category()).
bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
2Returns: lhs.category() < rhs.category() || lhs.category() == rhs.category() && lhs.value()
< rhs.value().
template <class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
3Effects: os << ec.category().name() << ’:’ << ec.value().
§ 19.5.2.5 477
c
ISO/IEC N????
19.5.3 Class error_condition [syserr.errcondition]
19.5.3.1 Class error_condition overview [syserr.errcondition.overview]
1The class error_condition describes an object used to hold values identifying error conditions. [ Note:
error_condition values are portable abstractions, while error_code values (19.5.2) are implementation
specific. — end note ]
namespace std {
class error_condition {
public:
// 19.5.3.2 constructors:
error_condition() noexcept;
error_condition(int val, const error_category& cat) noexcept;
template <class ErrorConditionEnum>
error_condition(ErrorConditionEnum e) noexcept;
// 19.5.3.3 modifiers:
void assign(int val, const error_category& cat) noexcept;
template<class ErrorConditionEnum>
error_condition& operator=(ErrorConditionEnum e) noexcept;
void clear() noexcept;
// 19.5.3.4 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
};
// 19.5.3.5 non-member functions:
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
}// namespace std
19.5.3.2 Class error_condition constructors [syserr.errcondition.constructors]
error_condition() noexcept;
1Effects: Constructs an object of type error_condition.
2Postconditions: val_ == 0 and cat_ == &generic_category().
error_condition(int val, const error_category& cat) noexcept;
3Effects: Constructs an object of type error_condition.
4Postconditions: val_ == val and cat_ == &cat.
template <class ErrorConditionEnum>
error_condition(ErrorConditionEnum e) noexcept;
5Effects: Constructs an object of type error_condition.
6Postcondition: *this == make_error_condition(e).
§ 19.5.3.2 478
c
ISO/IEC N????
7Remarks: This constructor shall not participate in overload resolution unless
is_error_condition_enum<ErrorConditionEnum>::value is true.
19.5.3.3 Class error_condition modifiers [syserr.errcondition.modifiers]
void assign(int val, const error_category& cat) noexcept;
1Postconditions: val_ == val and cat_ == &cat.
template <class ErrorConditionEnum>
error_condition& operator=(ErrorConditionEnum e) noexcept;
2Postcondition: *this == make_error_condition(e).
3Returns: *this.
4Remarks: This operator shall not participate in overload resolution unless
is_error_condition_enum<ErrorConditionEnum>::value is true.
void clear() noexcept;
Postconditions: value() == 0 and category() == generic_category().
19.5.3.4 Class error_condition observers [syserr.errcondition.observers]
int value() const noexcept;
1Returns: val_.
const error_category& category() const noexcept;
2Returns: *cat_.
string message() const;
3Returns: category().message(value()).
explicit operator bool() const noexcept;
4Returns: value() != 0.
19.5.3.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()).
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
1Returns: lhs.category() < rhs.category() || lhs.category() == rhs.category() &&
lhs.value() < rhs.value().
§ 19.5.3.5 479
c
ISO/IEC N????
19.5.4 Comparison operators [syserr.compare]
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
1Returns: lhs.category() == rhs.category() && lhs.value() == rhs.value().
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
2Returns: lhs.category().equivalent(lhs.value(), rhs) || rhs.category().equivalent(lhs,
rhs.value()).
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
3Returns: rhs.category().equivalent(rhs.value(), lhs) || lhs.category().equivalent(rhs,
lhs.value()).
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
4Returns: 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;
5Returns: !(lhs == rhs).
19.5.5 System error hash support [syserr.hash]
template <> struct hash<error_code>;
1The template specialization shall meet the requirements of class template hash (20.10.12).
19.5.6 Class system_error [syserr.syserr]
19.5.6.1 Class system_error overview [syserr.syserr.overview]
1The 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.
2[Note: If an error represents an out-of-memory condition, implementations are encouraged to throw an
exception object of type bad_alloc 18.6.2.1 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;
§ 19.5.6.1 480
c
ISO/IEC N????
const char* what() const noexcept;
};
}// namespace std
19.5.6.2 Class system_error members [syserr.syserr.members]
system_error(error_code ec, const string& what_arg);
1Effects: Constructs an object of class system_error.
2Postconditions: code() == ec.
string(what()).find(what_arg) != string::npos.
system_error(error_code ec, const char* what_arg);
3Effects: Constructs an object of class system_error.
4Postconditions: code() == ec.
string(what()).find(what_arg) != string::npos.
system_error(error_code ec);
5Effects: Constructs an object of class system_error.
6Postconditions: code() == ec.
system_error(int ev, const error_category& ecat,
const string& what_arg);
7Effects: Constructs an object of class system_error.
8Postconditions: code() == error_code(ev, ecat).
string(what()).find(what_arg) != string::npos.
system_error(int ev, const error_category& ecat,
const char* what_arg);
9Effects: Constructs an object of class system_error.
10 Postconditions: code() == error_code(ev, ecat).
string(what()).find(what_arg) != string::npos.
system_error(int ev, const error_category& ecat);
11 Effects: Constructs an object of class system_error.
12 Postconditions: code() == error_code(ev, ecat).
const error_code& code() const noexcept;
13 Returns: ec or error_code(ev, ecat), from the constructor, as appropriate.
const char* what() const noexcept;
14 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 ]
§ 19.5.6.2 481
c
ISO/IEC N????
20 General utilities library [utilities]
20.1 General [utilities.general]
1This 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 44.
Table 44 — General utilities library summary
Subclause Header(s)
20.2 Utility components <utility>
20.3 Pairs <utility>
20.4 Tuples <tuple>
20.5 Compile-time integer sequences <utility>
20.6 Optional objects <optional>
20.7 Fixed-size sequences of bits <bitset>
<memory>
20.8 Memory <cstdlib>
<cstring>
20.9 Smart pointers <memory>
20.10 Function objects <functional>
20.11 Type traits <type_traits>
20.12 Compile-time rational arithmetic <ratio>
20.13 Time utilities <chrono>
<ctime>
20.14 Scoped allocators <scoped_allocator>
20.15 Type indexes <typeindex>
20.2 Utility components [utility]
1This subclause contains some basic function and class templates that are used throughout the rest of the
library.
Header <utility> synopsis
2The 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.
#include <initializer_list>
namespace std {
// 20.2.1, 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&);
}
// 20.2.2, swap:
§ 20.2 482
c
ISO/IEC N????
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(noexcept(swap(*a, *b)));
// 20.2.3, exchange:
template <class T, class U=T> T exchange(T& obj, U&& new_val);
// 20.2.4, 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<T>::value && is_copy_constructible<T>::value,
const T&, T&&> move_if_noexcept(T& x) noexcept;
// 20.2.5, declval:
template <class T>
add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand
// 20.3, pairs:
template <class T1, class T2> struct pair;
// 20.3.3, 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&&);
// 20.3.4, 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<std::pair<T1, T2> >;
template <class T1, class T2> struct tuple_element<0, std::pair<T1, T2> >;
template <class T1, class T2> struct tuple_element<1, std::pair<T1, T2> >;
template<size_t I, class T1, class T2>
constexpr typename tuple_element<I, std::pair<T1, T2> >::type&
get(std::pair<T1, T2>&) noexcept;
template<size_t I, class T1, class T2>
§ 20.2 483
c
ISO/IEC N????
constexpr typename tuple_element<I, std::pair<T1, T2> >::type&&
get(std::pair<T1, T2>&&) noexcept;
template<size_t I, class T1, class T2>
constexpr const typename tuple_element<I, std::pair<T1, T2> >::type&
get(const std::pair<T1, T2>&) noexcept;
template <class T, class U>
constexpr T& get(pair<T, U>& p) noexcept;
template <class T, class U>
constexpr const T& get(const pair<T, U>& p) noexcept;
template <class T, class U>
constexpr T&& get(pair<T, U>&& p) noexcept;
template <class T, class U>
constexpr T& get(pair<U, T>& p) noexcept;
template <class T, class U>
constexpr const T& get(const pair<U, T>& p) noexcept;
template <class T, class U>
constexpr T&& get(pair<U, T>&& p) noexcept;
// 20.3.5, pair piecewise construction
struct piecewise_construct_t { };
constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
template <class... Types> class tuple; // defined in <tuple>
// 20.5, 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)>;
}
20.2.1 Operators [operators]
1To 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);
2Requires: Type Tis EqualityComparable (Table 17).
3Returns: !(x == y).
template <class T> bool operator>(const T& x, const T& y);
4Requires: Type Tis LessThanComparable (Table 18).
5Returns: y<x.
template <class T> bool operator<=(const T& x, const T& y);
§ 20.2.1 484
c
ISO/IEC N????
6Requires: Type Tis LessThanComparable (Table 18).
7Returns: !(y < x).
template <class T> bool operator>=(const T& x, const T& y);
8Requires: Type Tis LessThanComparable (Table 18).
9Returns: !(x < y).
10 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.
20.2.2 swap [utility.swap]
template<class T> void swap(T& a, T& b) noexcept(see below );
1Remark: The expression inside noexcept is equivalent to:
is_nothrow_move_constructible<T>::value &&
is_nothrow_move_assignable<T>::value
2Requires: Type Tshall be MoveConstructible (Table 20) and MoveAssignable (Table 22).
3Effects: Exchanges values stored in two locations.
template<class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
4Requires: a[i] shall be swappable with (17.6.3.2)b[i] for all iin the range [0,N).
5Effects: swap_ranges(a, a + N, b)
20.2.3 exchange [utility.exchange]
template <class T, class U=T> T exchange(T& obj, U&& new_val);
1Effects: Equivalent to:
T old_val = std::move(obj);
obj = std::forward<U>(new_val);
return old_val;
20.2.4 forward/move helpers [forward]
1The library provides templated helper functions to simplify applying move semantics to an lvalue and to
simplify the implementation of forwarding functions.
template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
2Returns: static_cast<T&&>(t).
3Remark: If the second form is instantiated with an lvalue reference type, the program is ill-formed.
4[Example:
§ 20.2.4 485
c
ISO/IEC N????
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
}
5In 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 iis 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;
6Returns: static_cast<remove_reference_t<T>&&>(t).
7[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&&)
}
8In the first call to factory,A1 is deduced as A&, so ais 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 ais 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<T>::value && is_copy_constructible<T>::value,
const T&, T&&> move_if_noexcept(T& x) noexcept;
9Returns: std::move(x)
§ 20.2.4 486
c
ISO/IEC N????
20.2.5 Function template declval [declval]
1The library provides the function template declval to simplify the definition of expressions which occur as
unevaluated operands (Clause 5).
template <class T>
add_rvalue_reference_t<T> declval() noexcept; // as unevaluated operand
2Remarks: If this function is odr-used (3.2), the program is ill-formed.
3Remarks: The template parameter Tof 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 (20.11.7.6).
— end example ]
20.3 Pairs [pairs]
20.3.1 In general [pairs.general]
1The 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 20.4.2.5 and 20.4.2.6).
20.3.2 Class template pair [pairs.pair]
// defined in header <utility>
namespace std {
template <class T1, class T2>
struct pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(const pair&) = default;
pair(pair&&) = default;
constexpr pair();
constexpr pair(const T1& x, const T2& y);
template<class U, class V> constexpr pair(U&& x, V&& y);
template<class U, class V> constexpr pair(const pair<U, V>& p);
template<class U, class V> constexpr pair(pair<U, V>&& 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 U, class V> pair& operator=(const pair<U, V>& p);
pair& operator=(pair&& p) noexcept(see below );
template<class U, class V> pair& operator=(pair<U, V>&& p);
void swap(pair& p) noexcept(see below );
};
}
§ 20.3.2 487
c
ISO/IEC N????
1Constructors 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.
2The 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
aconstexpr function.
constexpr pair();
3Requires: is_default_constructible<first_type>::value is true and is_default_construct-
ible<second_type>::value is true.
4Effects: Value-initializes first and second.
constexpr pair(const T1& x, const T2& y);
5Requires: is_copy_constructible<first_type>::value is true and is_copy_constructible<sec-
ond_type>::value is true.
6Effects: The constructor initializes first with xand second with y.
template<class U, class V> constexpr pair(U&& x, V&& y);
7Requires: is_constructible<first_type, U&&>::value is true and is_constructible<second_-
type, V&&>::value is true.
8Effects: The constructor initializes first with std::forward<U>(x) and second with std::forward<
V>(y).
9Remarks: If Uis not implicitly convertible to first_type or Vis not implicitly convertible to second_-
type this constructor shall not participate in overload resolution.
template<class U, class V> constexpr pair(const pair<U, V>& p);
10 Requires: is_constructible<first_type, const U&>::value is true and is_constructible<sec-
ond_type, const V&>::value is true.
11 Effects: Initializes members from the corresponding members of the argument.
12 Remark: This constructor shall not participate in overload resolution unless const U& is implicitly
convertible to first_type and const V& is implicitly convertible to second_type.
template<class U, class V> constexpr pair(pair<U, V>&& p);
13 Requires: is_constructible<first_type, U&&>::value is true and is_constructible<second_-
type, V&&>::value is true.
14 Effects: The constructor initializes first with std::forward<U>(p.first) and second with std::
forward<V>(p.second).
15 Remark: This constructor shall not participate in overload resolution unless Uis implicitly convertible
to first_type and Vis implicitly convertible to second_type.
template<class... Args1, class... Args2>
pair(piecewise_construct_t,
tuple<Args1...> first_args, tuple<Args2...> second_args);
§ 20.3.2 488
c
ISO/IEC N????
16 Requires: is_constructible<first_type, Args1&&...>::value is true and is_constructible<second_-
type, Args2&&...>::value is true.
17 Effects: The constructor 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 xof type Uwithin 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);
18 Requires: is_copy_assignable<first_type>::value is true and is_copy_assignable<second_-
type>::value is true.
19 Effects: Assigns p.first to first and p.second to second.
20 Returns: *this.
template<class U, class V> pair& operator=(const pair<U, V>& p);
21 Requires: is_assignable<first_type&, const U&>::value is true and is_assignable<second_-
type&, const V&>::value is true.
22 Effects: Assigns p.first to first and p.second to second.
23 Returns: *this.
pair& operator=(pair&& p) noexcept(see below );
24 Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable<T1>::value &&
is_nothrow_move_assignable<T2>::value
25 Requires: is_move_assignable<first_type>::value is true and is_move_assignable<second_-
type>::value is true.
26 Effects: Assigns to first with std::forward<first_type>(p.first) and to second with
std::forward<second_type>(p.second).
27 Returns: *this.
template<class U, class V> pair& operator=(pair<U, V>&& p);
28 Requires: is_assignable<first_type&, U&&>::value is true and is_assignable<second_type&,
V&&>::value is true.
29 Effects: Assigns to first with std::forward<U>(p.first) and to second with
std::forward<V>(p.second).
30 Returns: *this.
void swap(pair& p) noexcept(see below );
31 Remarks: The expression inside noexcept is equivalent to:
§ 20.3.2 489
c
ISO/IEC N????
noexcept(swap(first, p.first)) &&
noexcept(swap(second, p.second))
32 Requires: first shall be swappable with (17.6.3.2)p.first and second shall be swappable with
p.second.
33 Effects: Swaps first with p.first and second with p.second.
20.3.3 Specialized algorithms [pairs.spec]
template <class T1, class T2>
constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
1Returns: 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);
2Returns: 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);
3Returns: !(x == y)
template <class T1, class T2>
constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
4Returns: y<x
template <class T1, class T2>
constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);
5Returns: !(x < y)
template <class T1, class T2>
constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);
6Returns: !(y < x)
template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
noexcept(noexcept(x.swap(y)));
7Effects: x.swap(y)
template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
8Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y));
where V1 and V2 are determined as follows: Let Ui be decay<Ti>::type for each Ti. Then each Vi is
X& if Ui equals reference_wrapper<X>, otherwise Vi is Ui.
9[Example: In place of:
§ 20.3.3 490
c
ISO/IEC N????
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 ]
20.3.4 Tuple-like access to pair [pair.astuple]
tuple_size<pair<T1, T2> >::value
1Returns: Integral constant expression.
2Value: 2.
tuple_element<0, pair<T1, T2> >::type
3Value: the type T1.
tuple_element<1, pair<T1, T2> >::type
4Value: the type T2.
template<size_t I, class T1, class T2>
constexpr tuple_element_t<I, std::pair<T1, T2> >&
get(pair<T1, T2>&) noexcept;
template<size_t I, class T1, class T2>
constexpr const typename tuple_element<I, std::pair<T1, T2> >::type&
get(const pair<T1, T2>&) noexcept;
5Returns: If I == 0 returns p.first; if I == 1 returns p.second; otherwise the program is ill-formed.
template<size_t I, class T1, class T2>
constexpr typename tuple_element<I, std::pair<T1, T2> >::type&&
get(std::pair<T1, T2>&&) noexcept;
6Returns: If I == 0 returns std::forward<T1&&>(p.first); if I == 1 returns std::forward<T2&&>(
p.second); otherwise the program is ill-formed.
template <class T, class U>
constexpr T& get(pair<T, U>& p) noexcept;
template <class T, class U>
constexpr const T& get(const pair<T, U>& p) noexcept;
7Requires: Tand Uare distinct types. Otherwise, the program is ill-formed.
8Returns: get<0>(p);
template <class T, class U>
constexpr T&& get(pair<T, U>&& p) noexcept;
§ 20.3.4 491
c
ISO/IEC N????
9Requires: Tand Uare distinct types. Otherwise, the program is ill-formed.
10 Returns: get<0>(std::move(p));
template <class T, class U>
constexpr T& get(pair<U, T>& p) noexcept;
template <class T, class U>
constexpr const T& get(const pair<U, T>& p) noexcept;
11 Requires: Tand Uare distinct types. Otherwise, the program is ill-formed.
12 Returns: get<1>(p);
template <class T, class U>
constexpr T&& get(pair<U, T>&& p) noexcept;
13 Requires: Tand Uare distinct types. Otherwise, the program is ill-formed.
14 Returns: get<1>(std::move(p));
20.3.5 Piecewise construction [pair.piecewise]
struct piecewise_construct_t { };
constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
1The 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 (20.4) arguments used for piecewise construction of
the elements of the pair object.
20.4 Tuples [tuple]
20.4.1 In general [tuple.general]
1This 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. See 20.3.
2Header <tuple> synopsis
namespace std {
// 20.4.2, class template tuple:
template <class... Types> class tuple;
// 20.4.2.4, tuple creation functions:
const unspecified ignore;
template <class... Types>
constexpr tuple<VTypes ...> make_tuple(Types&&...);
template <class... Types>
tuple<Types&&...> forward_as_tuple(Types&&...) noexcept;
template<class... Types>
tuple<Types&...> tie(Types&...) noexcept;
template <class... Tuples>
constexpr tuple<Ctypes ...> tuple_cat(Tuples&&...);
§ 20.4.1 492
c
ISO/IEC N????
// 20.4.2.5, tuple helper classes:
template <class T> class tuple_size; // undefined
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; // undefined
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...> >;
// 20.4.2.6, element access:
template <size_t I, class... Types>
constexpr typename tuple_element<I, tuple<Types...> >::type&
get(tuple<Types...>&) noexcept;
template <size_t I, class... Types>
constexpr typename tuple_element<I, tuple<Types...> >::type&&
get(tuple<Types...>&&) noexcept;
template <size_t I, class... Types>
constexpr typename tuple_element<I, tuple<Types...> >::type const&
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;
// 20.4.2.7, 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...>&);
// 20.4.2.8, allocator-related traits
template <class... Types, class Alloc>
struct uses_allocator<tuple<Types...>, Alloc>;
// 20.4.2.9, specialized algorithms:
template <class... Types>
void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below );
}
§ 20.4.1 493
c
ISO/IEC N????
20.4.2 Class template tuple [tuple.tuple]
namespace std {
template <class... Types>
class tuple {
public:
// 20.4.2.1,tuple construction
constexpr tuple();
explicit constexpr tuple(const Types&...);
template <class... UTypes>
explicit constexpr tuple(UTypes&&...);
tuple(const tuple&) = default;
tuple(tuple&&) = default;
template <class... UTypes>
constexpr tuple(const tuple<UTypes...>&);
template <class... UTypes>
constexpr tuple(tuple<UTypes...>&&);
template <class U1, class U2>
constexpr tuple(const pair<U1, U2>&); // only if sizeof...(Types) == 2
template <class U1, class U2>
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>
tuple(allocator_arg_t, const Alloc& a, const Types&...);
template <class Alloc, class... UTypes>
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>
tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template <class Alloc, class... UTypes>
tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
template <class Alloc, class U1, class U2>
tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template <class Alloc, class U1, class U2>
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
// 20.4.2.2,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...>&&);
§ 20.4.2 494
c
ISO/IEC N????
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
// 20.4.2.3,tuple swap
void swap(tuple&) noexcept(see below );
};
}
20.4.2.1 Construction [tuple.cnstr]
1For each tuple constructor, an exception is thrown only if the construction of one of the types in Types
throws an exception.
2The 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
aconstexpr function. The defaulted move and copy constructor of tuple<> shall be constexpr functions.
3In the constructor descriptions that follow, let ibe in the range [0,sizeof...(Types)) in order, Tibe the
ith type in Types, and Uibe the ith type in a template parameter pack named UTypes, where indexing is
zero-based.
constexpr tuple();
4Requires: is_default_constructible<Ti>::value is true for all i.
5Effects: Value initializes each element.
explicit constexpr tuple(const Types&...);
6Requires: is_copy_constructible<Ti>::value is true for all i.
7Effects: Initializes each element with the value of the corresponding parameter.
template <class... UTypes>
explicit constexpr tuple(UTypes&&... u);
8Requires: sizeof...(Types) == sizeof...(UTypes).is_constructible<Ti,Ui&&>::value is true
for all i.
9Effects: Initializes the elements in the tuple with the corresponding value in std::forward<UTypes>(u).
10 Remark: This constructor shall not participate in overload resolution unless each type in UTypes is
implicitly convertible to its corresponding type in Types.
tuple(const tuple& u) = default;
11 Requires: is_copy_constructible<Ti>::value is true for all i.
12 Effects: Initializes each element of *this with the corresponding element of u.
tuple(tuple&& u) = default;
13 Requires: is_move_constructible<Ti>::value is true for all i.
14 Effects: For all i, initializes the ith element of *this with std::forward<Ti>(get<i>(u)).
§ 20.4.2.1 495
c
ISO/IEC N????
template <class... UTypes> constexpr tuple(const tuple<UTypes...>& u);
15 Requires: sizeof...(Types) == sizeof...(UTypes).is_constructible<Ti, const Ui&>::value
is true for all i.
16 Effects: Constructs each element of *this with the corresponding element of u.
17 Remark: This constructor shall not participate in overload resolution unless const Ui&is implicitly
convertible to Tifor all i.
template <class... UTypes> constexpr tuple(tuple<UTypes...>&& u);
18 Requires: sizeof...(Types) == sizeof...(UTypes).is_constructible<Ti,Ui&&>::value is true
for all i.
19 Effects: For all i, initializes the ith element of *this with std::forward<Ui>(get<i>(u)).
20 Remark: This constructor shall not participate in overload resolution unless each type in UTypes is
implicitly convertible to its corresponding type in Types.
template <class U1, class U2> constexpr tuple(const pair<U1, U2>& u);
21 Requires: sizeof...(Types) == 2.is_constructible<T0, const U1&>::value is true for the first
type T0in Types and is_constructible<T1, const U2&>::value is true for the second type T1in
Types.
22 Effects: Constructs the first element with u.first and the second element with u.second.
23 Remark: This constructor shall not participate in overload resolution unless const U1& is implicitly
convertible to T0and const U2& is implicitly convertible to T1.
template <class U1, class U2> constexpr tuple(pair<U1, U2>&& u);
24 Requires: sizeof...(Types) == 2.is_constructible<T0, U1&&>::value is true for the first type
T0in Types and is_constructible<T1, U2&&>::value is true for the second type T1in Types.
25 Effects: Initializes the first element with std::forward<U1>(u.first) and the second element with
std::forward<U2>(u.second).
26 Remark: This constructor shall not participate in overload resolution unless U1 is implicitly convertible
to T0and U2 is implicitly convertible to T1.
template <class Alloc>
tuple(allocator_arg_t, const Alloc& a);
template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, const Types&...);
template <class Alloc, class... UTypes>
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>
tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template <class Alloc, class... UTypes>
tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
§ 20.4.2.1 496
c
ISO/IEC N????
template <class Alloc, class U1, class U2>
tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template <class Alloc, class U1, class U2>
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
27 Requires: Alloc shall meet the requirements for an Allocator (17.6.3.5).
28 Effects: Equivalent to the preceding constructors except that each element is constructed with uses-
allocator construction (20.8.7.2).
20.4.2.2 Assignment [tuple.assign]
1For 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 ibe in the range [0,sizeof...
(Types)) in order, Tibe the ith type in Types, and Uibe the ith type in a template parameter pack named
UTypes, where indexing is zero-based.
tuple& operator=(const tuple& u);
2Requires: is_copy_assignable<Ti>::value is true for all i.
3Effects: Assigns each element of uto the corresponding element of *this.
4Returns: *this
tuple& operator=(tuple&& u) noexcept(see below );
5Remark: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_move_assignable<Ti>::value
where Tiis the ith type in Types.
6Requires: is_move_assignable<Ti>::value is true for all i.
7Effects: For all i, assigns std::forward<Ti>(get<i>(u)) to get<i>(*this).
8Returns: *this.
template <class... UTypes>
tuple& operator=(const tuple<UTypes...>& u);
9Requires: sizeof...(Types) == sizeof...(UTypes) and is_assignable<Ti&, const Ui&>::value
is true for all i.
10 Effects: Assigns each element of uto the corresponding element of *this.
11 Returns: *this
template <class... UTypes>
tuple& operator=(tuple<UTypes...>&& u);
12 Requires: is_assignable<Ti&, Ui&&>::value == true for all i.sizeof...(Types) ==
sizeof...(UTypes).
13 Effects: For all i, assigns std::forward<Ui>(get<i)>(u)) to get<i>(*this).
14 Returns: *this.
template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u);
§ 20.4.2.2 497
c
ISO/IEC N????
15 Requires: sizeof...(Types) == 2.is_assignable<T0&, const U1&>::value is true for the first
type T0in Types and is_assignable<T1&, const U2&>::value is true for the second type T1in
Types.
16 Effects: Assigns u.first to the first element of *this and u.second to the second element of *this.
17 Returns: *this
template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u);
18 Requires: sizeof...(Types) == 2.is_assignable<T0&, U1&&>::value is true for the first type T0
in Types and is_assignable<T1&, U2&&>::value is true for the second type T1in Types.
19 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.
20 Returns: *this.
20.4.2.3 swap [tuple.swap]
void swap(tuple& rhs) noexcept(see below );
1Remark: The expression inside noexcept is equivalent to the logical and of the following expressions:
noexcept(swap(declval<Ti&>>(), declval<Ti&>()))
where Tiis the ith type in Types.
2Requires: Each element in *this shall be swappable with (17.6.3.2) the corresponding element in rhs.
3Effects: Calls swap for each element in *this and its corresponding element in rhs.
4Throws: Nothing unless one of the element-wise swap calls throws an exception.
20.4.2.4 Tuple creation functions [tuple.creation]
1In the function descriptions that follow, let ibe in the range [0,sizeof...(TTypes)) in order and let Ti
be the ith type in a template parameter pack named TTypes; let jbe in the range [0,sizeof...(UTypes))
in order and Ujbe the jth type in a template parameter pack named UTypes, where indexing is zero-based.
template<class... Types>
constexpr tuple<VTypes ...> make_tuple(Types&&... t);
2Let Uibe decay<Ti>::type for each Tiin Types. Then each Viin VTypes is X& if Uiequals reference_-
wrapper<X>, otherwise Viis Ui.
3Returns: tuple<VTypes...>(std::forward<Types>(t)...).
4[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... Types>
tuple<Types&&...> forward_as_tuple(Types&&... t) noexcept;
§ 20.4.2.4 498
c
ISO/IEC N????
5Effects: Constructs a tuple of references to the arguments in tsuitable 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).
6Returns: tuple<Types&&...>(std::forward<Types>(t)...)
template<class... Types>
tuple<Types&...> tie(Types&... t) noexcept;
7Returns: tuple<Types&>(t...). When an argument in tis ignore, assigning any value to the
corresponding tuple element has no effect.
8[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);
9In the following paragraphs, let Tibe the ith type in Tuples,Uibe remove_reference<Ti>::type,
and tpibe the ith parameter in the function parameter pack tpls, where all indexing is zero-based.
10 Requires: For all i,Uishall be the type cvituple<Argsi...>, where cviis the (possibly empty) ith
cv-qualifier-seq and Argsiis the parameter pack representing the element types in Ui. Let Aik be
the kith type in Argsi. For all Aik the following requirements shall be satisfied: If Tiis deduced as
an lvalue reference type, then is_constructible<Aik ,cviAik&>::value == true, otherwise is_-
constructible<Aik,cviAik&&>::value == true.
11 Remarks: The types in Ctypes shall be equal to the ordered sequence of the extended types Args0...,
Args1..., ... Argsn1..., where nis equal to sizeof...(Tuples). Let ei... be the ith ordered
sequence of tuple elements of the resulting tuple object corresponding to the type sequence Argsi.
12 Returns: Atuple object constructed by initializing the kith type element eik in ei... with
get<ki>(std::forward<Ti>(tpi)) for each valid kiand each group eiin order.
13 Note: An implementation may support additional types in the parameter pack Tuples that support
the tuple-like protocol, such as pair and array.
20.4.2.5 Tuple helper classes [tuple.helper]
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:
typedef TI type;
};
1Requires: I < sizeof...(Types). The program is ill-formed if Iis out of bounds.
2Type: TI is the type of the Ith element of Types, where indexing is zero-based.
§ 20.4.2.5 499
c
ISO/IEC N????
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>;
3Let TS denote tuple_size<T> of the cv-unqualified type T. Then each of the three templates shall
meet the UnaryTypeTrait requirements (20.11.1) with a BaseCharacteristic of
integral_constant<remove_cv<decltype(TS::value)>::type, TS::value>
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<I, T> of the cv-unqualified type T. Then each of the three templates
shall meet the TransformationTrait requirements (20.11.1) with a member typedef type that names
the following type:
for the first specialization, add_const<TE ::type>::type,
for the second specialization, add_volatile<TE ::type>::type, and
for the third specialization, add_cv<TE ::type>::type.
20.4.2.6 Element access [tuple.elem]
template <size_t I, class... Types>
constexpr typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>& t) noexcept;
1Requires: I < sizeof...(Types). The program is ill-formed if Iis out of bounds.
2Returns: A reference to the Ith element of t, where indexing is zero-based.
template <size_t I, class... Types>
constexpr typename tuple_element<I, tuple<Types...> >::type&& get(tuple<Types...>&& t) noexcept;
3Effects: Equivalent to return std::forward<typename tuple_element<I, tuple<Types...> >
::type&&>(get<I>(t));
4Note: if a Tin 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&&.
template <size_t I, class... Types>
constexpr typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>& t) noexcept;
5Requires: I < sizeof...(Types). The program is ill-formed if Iis out of bounds.
6Returns: A const reference to the Ith element of t, where indexing is zero-based.
7[Note: Constness is shallow. If a Tin Types is some reference type X&, the return type is X&, not
const X&. However, if the element type is 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;
§ 20.4.2.6 500
c
ISO/IEC N????
8Requires: The type Toccurs exactly once in Types.... Otherwise, the program is ill-formed.
9Returns: A reference to the element of tcorresponding to the type Tin Types....
10 [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 ]
11 [Note: The reason get is a nonmember 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 ]
20.4.2.7 Relational operators [tuple.rel]
template<class... TTypes, class... UTypes>
constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
1Requires: 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).
2Returns: true if get<i>(t) == get<i>(u) for all i, otherwise false. For any two zero-length tuples
eand f,e == f returns true.
3Effects: 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);
4Requires: For all i, where 0 <= i and i < sizeof...(TTypes),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).
5Returns: The result of a lexicographical comparison between tand u. The result is defined as:
(bool)(get<0>(t) < get<0>(u)) || (!(bool)(get<0>(u) < get<0>(t)) && ttail < utail), where
rtail for some tuple ris a tuple containing all but the first element of r. For any two zero-length tuples
eand f,e<freturns false.
template<class... TTypes, class... UTypes>
constexpr bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
6Returns: !(t == u).
template<class... TTypes, class... UTypes>
constexpr bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
7Returns: u<t.
template<class... TTypes, class... UTypes>
constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
§ 20.4.2.7 501
c
ISO/IEC N????
8Returns: !(u < t)
template<class... TTypes, class... UTypes>
constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
9Returns: !(t < u)
10 [Note: The above definitions for comparison operators do not require ttail (or utail) to be constructed. It may
not even be possible, as tand uare not required to be copy constructible. Also, all comparison operators
are short circuited; they do not perform element accesses beyond what is required to determine the result
of the comparison. — end note ]
20.4.2.8 Tuple traits [tuple.traits]
template <class... Types, class Alloc>
struct uses_allocator<tuple<Types...>, Alloc> : true_type { };
Requires: Alloc shall be an Allocator (17.6.3.5).
1[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 ]
20.4.2.9 Tuple specialized algorithms [tuple.special]
template <class... Types>
void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below );
1Remark: The expression inside noexcept is equivalent to:
noexcept(x.swap(y))
2Effects: x.swap(y)
20.5 Compile-time integer sequences [intseq]
20.5.1 In general [intseq.general]
1The 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.
2[Example:
template<class F, class Tuple, std::size_t... I>
auto apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {
return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
}
template<class F, class Tuple>
auto apply(F&& f, Tuple&& t) {
using Indices = make_index_sequence<std::tuple_size<Tuple>::value>;
return apply_impl(std::forward<F>(f), std::forward<Tuple>(t), Indices());
}
— end example ] [ Note: The index_sequence alias template is provided for the common case of an
integer sequence of type size_t.— end note ]
20.5.2 Class template integer_sequence [intseq.intseq]
§ 20.5.2 502
c
ISO/IEC N????
namespace std {
template<class T, T... I>
struct integer_sequence {
typedef T value_type;
static constexpr size_t size() noexcept { return sizeof...(I); }
};
}
1Tshall be an integer type.
20.5.3 Alias template make_integer_sequence [intseq.make]
template<class T, T N>
using make_integer_sequence = integer_sequence<T, see below >;
1If Nis negative the program is ill-formed. The alias template make_integer_sequence denotes a
specialization of integer_sequence with Ntemplate 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 ]
20.6 Optional objects [optional]
20.6.1 In general [optional.general]
1This subclause describes class template optional that represents optional objects. An optional object for
object types 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.
20.6.2 Header <optional> synopsis [optional.syn]
#include <initializer_list>
namespace std {
// 20.6.4, optional for object types
template <class T> class optional;
// 20.6.5, In-place construction
struct in_place_t{};
constexpr in_place_t in_place{};
// 20.6.6, Disengaged state indicator
struct nullopt_t{see below };
constexpr nullopt_t nullopt(unspecified );
// 20.6.7, class bad_optional_access
class bad_optional_access;
// 20.6.8, Relational operators
template <class T> constexpr bool operator==(const optional<T>&, const optional<T>&);
template <class T> constexpr bool operator<(const optional<T>&, const optional<T>&);
// 20.6.9, 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;
§ 20.6.2 503
c
ISO/IEC N????
// 20.6.10, Comparison with T
template <class T> constexpr bool operator==(const optional<T>&, const T&);
template <class T> constexpr bool operator==(const T&, const optional<T>&);
template <class T> constexpr bool operator<(const optional<T>&, const T&);
template <class T> constexpr bool operator<(const T&, const optional<T>&);
// 20.6.11, Specialized algorithms
template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
template <class T> constexpr optional<see below > make_optional(T&&);
// 20.6.12, hash support
template <class T> struct hash;
template <class T> struct hash<optional<T>>;
}// namespace std
1A 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.
20.6.3 Definitions [optional.defs]
1An instance of optional<T> is said to be disengaged if
it is default-initialized; or
it is initialized with a value of type nullopt_t or with a disengaged optional object of type optional<T>;
or
a value of type nullopt_t or a disengaged optional object of type optional<T> is assigned to it.
2An instance of optional<T> is said to be engaged if it is not disengaged.
20.6.4 optional for object types [optional.object]
namespace std {
template <class T>
class optional
{
public:
typedef T value_type;
// 20.6.4.1, constructors
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
optional(const optional&);
optional(optional&&) noexcept(see below );
constexpr optional(const T&);
constexpr optional(T&&);
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&&...);
// 20.6.4.2, destructor
~optional();
// 20.6.4.3, assignment
optional& operator=(nullopt_t) noexcept;
optional& operator=(const optional&);
optional& operator=(optional&&) noexcept(see below );
§ 20.6.4 504
c
ISO/IEC N????
template <class U> optional& operator=(U&&);
template <class... Args> void emplace(Args&&...);
template <class U, class... Args> void emplace(initializer_list<U>, Args&&...);
// 20.6.4.4, swap
void swap(optional&) noexcept(see below );
// 20.6.4.5, observers
constexpr T const* operator->() const;
T* operator->();
constexpr T const& operator*() const;
T& operator*();
constexpr explicit operator bool() const noexcept;
constexpr T const& value() const;
T& value();
template <class U> constexpr T value_or(U&&) const&;
template <class U> T value_or(U&&) &&;
private:
bool init; // exposition only
T* val; // exposition only
};
}// namespace std
1An engaged instance of optional<T> where Tis of object type shall contain a value of type Twithin its own
storage. This value is referred to as the contained value 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.
2Members init and val are provided for exposition only. Implementations need not provide those members.
init indicates whether the optional object’s contained value has been initialized (and not yet destroyed);
when init is true val points to the contained value.
3Tshall be an object type and shall satisfy the requirements of Destructible (Table 24).
20.6.4.1 Constructors [optional.object.ctor]
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
1Postconditions: *this is disengaged.
2Remarks: No contained value is initialized. For every object type Tthese constructors shall be
constexpr constructors (7.1.5).
optional(const optional<T>& rhs);
3Requires: is_copy_constructible<T>::value is true.
4Effects: If rhs is engaged, initializes the contained value as if direct-non-list-initializing an object of
type Twith the expression *rhs.
5Postconditions: bool(rhs) == bool(*this).
6Throws: Any exception thrown by the selected constructor of T.
optional(optional<T>&& rhs) noexcept(see below );
§ 20.6.4.1 505
c
ISO/IEC N????
7Requires: is_move_constructible<T>::value is true.
8Effects: If rhs is engaged, initializes the contained value as if direct-non-list-initializing an object of
type Twith the expression std::move(*rhs).bool(rhs) is unchanged.
9Postconditions: bool(rhs) == bool(*this).
10 Throws: Any exception thrown by the selected constructor of T.
11 Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_constructible<T>::value
constexpr optional(const T& v);
12 Requires: is_copy_constructible<T>::value is true.
13 Effects: Initializes the contained value as if direct-non-list-initializing an object of type Twith the
expression v.
14 Postconditions: *this is engaged.
15 Throws: Any exception thrown by the selected constructor of T.
16 Remarks: If T’s selected constructor is a constexpr constructor, this constructor shall be a constexpr
constructor.
constexpr optional(T&& v);
17 Requires: is_move_constructible<T>::value is true.
18 Effects: Initializes the contained value as if direct-non-list-initializing an object of type Twith the
expression std::move(v).
19 Postconditions: *this is engaged.
20 Throws: Any exception thrown by the selected constructor of T.
21 Remarks: If T’s selected constructor is a constexpr constructor, this constructor shall be a constexpr
constructor.
template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);
22 Requires: is_constructible<T, Args&&...>::value is true.
23 Effects: Initializes the contained value as if constructing an object of type Twith the arguments
std::forward<Args>(args)....
24 Postconditions: *this is engaged.
25 Throws: Any exception thrown by the selected constructor of T.
26 Remarks: If T’s constructor selected for the initialization is a constexpr constructor, this constructor
shall be a constexpr constructor.
template <class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
§ 20.6.4.1 506
c
ISO/IEC N????
27 Requires: is_constructible<T, initializer_list<U>&, Args&&...>::value is true.
28 Effects: Initializes the contained value as if constructing an object of type Twith the arguments il,
std::forward<Args>(args)....
29 Postconditions: *this is engaged.
30 Throws: Any exception thrown by the selected constructor of T.
31 Remarks: The function shall not participate in overload resolution unless is_constructible<T,
initializer_list<U>&, Args&&...>::value is true.
32 Remarks: If T’s constructor selected for the initialization is a constexpr constructor, this constructor
shall be a constexpr constructor.
20.6.4.2 Destructor [optional.object.dtor]
~optional();
1Effects: If is_trivially_destructible<T>::value != true and *this is engaged, calls val->T::˜T().
2Remarks: If is_trivially_destructible<T>::value == true then this destructor shall be a trivial
destructor.
20.6.4.3 Assignment [optional.object.assign]
optional<T>& operator=(nullopt_t) noexcept;
1Effects: If *this is engaged calls val->T::˜T() to destroy the contained value; otherwise no effect.
2Returns: *this.
3Postconditions: *this is disengaged.
optional<T>& operator=(const optional<T>& rhs);
4Requires: is_copy_constructible<T>::value is true and is_copy_assignable<T>::value is true.
5Effects:
If *this is disengaged and rhs is disengaged, no effect, otherwise
if *this is engaged and rhs is disengaged, destroys the contained value by calling val->T::˜T(),
otherwise
— if *this is disengaged and rhs is engaged, initializes the contained value as if direct-non-list-
initializing an object of type Twith *rhs, otherwise
(if both *this and rhs are engaged) assigns *rhs to the contained value.
6Returns: *this.
7Postconditions: bool(rhs) == bool(*this).
8Exception safety: If any exception is thrown, the values of init and rhs.init remain 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 constructor.
optional<T>& operator=(optional<T>&& rhs) noexcept(see below );
9Requires: is_move_constructible<T>::value is true and is_move_assignable<T>::value is true.
10 Effects:
§ 20.6.4.3 507
c
ISO/IEC N????
If *this is disengaged and rhs is disengaged, no effect, otherwise
if *this is engaged and rhs is disengaged, destroys the contained value by calling val->T::˜T(),
otherwise
— if *this is disengaged and rhs is engaged, initializes the contained value as if direct-non-list-
initializing an object of type Twith std::move(*rhs), otherwise
(if both *this and rhs are engaged) assigns std::move(*rhs) to the contained value.
11 Returns: *this.
12 Postconditions::bool(rhs) == bool(*this).
13 Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable<T>::value && is_nothrow_move_constructible<T>::value
14 Exception safety: If any exception is thrown, the values of init and rhs.init remain 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.
template <class U> optional<T>& operator=(U&& v);
15 Requires: is_constructible<T, U>::value is true and is_assignable<U, T>::value is true.
16 Effects: If *this is engaged assigns std::forward<U>(v) to the contained value; otherwise initializes
the contained value as if direct-non-list-initializing an object of type Twith std::forward<U>(v).
17 Returns: *this.
18 Postconditions: *this is engaged.
19 Exception safety: If any exception is thrown, the value of init remains unchanged. If an exception is
thrown during the call to T’s constructor, the state of vis 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
vis determined by the exception safety guarantee of T’s assignment.
20 Remarks: This function shall not participate in overload resolution unless is_same<remove_reference
<U>::type, T>::value is true.
21 [Note: The reason for providing such generic assignment and then constraining it so that effectively T
== U is to guarantee that assignment of the form o = {} is unambiguous. — end note ]
template <class... Args> void emplace(Args&&... args);
22 Requires: is_constructible<T, Args&&...>::value is true.
23 Effects: Calls *this = nullopt. Then initializes the contained value as if constructing an object of
type Twith the arguments std::forward<Args>(args)....
24 Postconditions: *this is engaged.
25 Throws: Any exception thrown by the selected constructor of T.
26 Exception safety: If an exception is thrown during the call to T’s constructor, *this is disengaged, and
the previous *val (if any) has been destroyed.
template <class U, class... Args> void emplace(initializer_list<U> il, Args&&... args);
§ 20.6.4.3 508
c
ISO/IEC N????
27 Requires: is_constructible<T, initializer_list<U>&, Args&&...>::value is true.
28 Effects: Calls *this = nullopt. Then initializes the contained value as if constructing an object of
type Twith the arguments il, std::forward<Args>(args)....
29 Postconditions: *this is engaged.
30 Throws: Any exception thrown by the selected constructor of T.
31 Exception safety: If an exception is thrown during the call to T’s constructor, *this is disengaged, and
the previous *val (if any) has been destroyed.
32 Remarks: This function shall not participate in overload resolution unless is_constructible<T,
initializer_list<U>&, Args&&...>::value is true.
20.6.4.4 Swap [optional.object.swap]
void swap(optional<T>& rhs) noexcept(see below );
1Requires: Lvalues of type Tshall be swappable and is_move_constructible<T>::value is true.
2Effects:
If *this is disengaged and rhs is disengaged, no effect, otherwise
— if *this is engaged and rhs is disengaged, initializes the contained value of rhs by direct-
initialization with std::move(*(*this)), followed by val->T::˜T(), swap(init, rhs.init),
otherwise
— if *this is disengaged and rhs is engaged, initializes the contained value of *this by direct-
initialization with std::move(*rhs), followed by rhs.val->T::˜T(), swap(init, rhs.init),
otherwise
(if both *this and rhs are engaged) calls swap(*(*this), *rhs).
3Throws: Any exceptions that the expressions in the Effects clause throw.
4Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_constructible<T>::value && noexcept(swap(declval<T&>(), declval<T&>()))
5Exception safety: If any exception is thrown, the values of init and rhs.init 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.
20.6.4.5 Observers [optional.object.observe]
constexpr const T* operator->() const;
T* operator->();
1Requires: *this is engaged.
2Returns: val.
3Throws: Nothing.
4Remarks: Unless Tis a user-defined type with overloaded unary operator&, the first function shall be
aconstexpr function.
constexpr const T& operator*() const;
T& operator*();
§ 20.6.4.5 509
c
ISO/IEC N????
5Requires: *this is engaged.
6Returns: *val.
7Throws: Nothing.
8Remarks: The first function shall be a constexpr function.
constexpr explicit operator bool() const noexcept;
9Returns: init.
10 Remarks: This function shall be a constexpr function.
constexpr const T& value() const;
T& value();
11 Returns: *val, if bool(*this).
12 Throws: bad_optional_access if !*this.
13 Remarks: The first function shall be a constexpr function.
template <class U> constexpr T value_or(U&& v) const&;
14 Requires: is_copy_constructible<T>::value is true and is_convertible<U&&, T>::value is true.
15 Returns: bool(*this) ? **this : static_cast<T>(std::forward<U>(v)).
16 Throws: Any exception thrown by the selected constructor of T.
17 Exception safety: If init == true and an exception is thrown during the call to T’s constructor, the
value of init and vremains unchanged and the state of *val is determined by the exception safety
guarantee of the selected constructor of T. Otherwise, when an exception is thrown during the call
to T’s constructor, the value of *this remains unchanged and the state of vis determined by the
exception safety guarantee of the selected constructor of T.
18 Remarks: If both constructors of Twhich could be selected are constexpr constructors, this function
shall be a constexpr function.
template <class U> T value_or(U&& v) &&;
19 Requires: is_move_constructible<T>::value is true and is_convertible<U&&, T>::value is true.
20 Returns: bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v)).
21 Throws: Any exception thrown by the selected constructor of T.
22 Exception safety: If init == true and an exception is thrown during the call to T’s constructor,
the value of init and vremains unchanged and the state of *val is determined by the exception
safety guarantee of T’s constructor. Otherwise, when an exception is thrown during the call to T’s
constructor, the value of *this remains unchanged and the state of vis determined by the exception
safety guarantee of the selected constructor of T.
20.6.5 In-place construction [optional.inplace]
struct in_place_t{};
constexpr in_place_t in_place{};
1The struct in_place_t is an empty structure type used as a unique type to disambiguate constructor
overloading (20.6.4.1).
§ 20.6.5 510
c
ISO/IEC N????
20.6.6 Disengaged state indicator [optional.nullopt]
struct nullopt_t{see below };
constexpr nullopt_t nullopt(unspecified );
1The struct nullopt_t is an empty structure type used as a unique type to indicate a disengaged
state for optional objects. In particular, optional<T> has a constructor with nullopt_t as single
argument; this indicates that a disengaged optional object shall be constructed.
2The type nullopt_t shall not have a default constructor. It shall be a literal type. The constant
nullopt shall be initialized with an argument of literal type.
20.6.7 Class bad_optional_access [optional.bad_optional_access]
namespace std {
class bad_optional_access : public logic_error {
public:
explicit bad_optional_access(const string& what_arg);
explicit bad_optional_access(const char* what_arg);
};
}
1The 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 a disengaged optional object.
bad_optional_access(const string& what_arg);
2Effects: Constructs an object of class bad_optional_access.
3Postcondition: strcmp(what(), what_arg.c_str()) == 0.
bad_optional_access(const char* what_arg);
4Effects: Constructs an object of class bad_optional_access.
5Postcondition: strcmp(what(), what_arg) == 0.
20.6.8 Relational operators [optional.relops]
template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y);
1Requires: Tshall meet the requirements of EqualityComparable.
2Returns: If bool(x) != bool(y),false; otherwise if bool(x) == false,true; otherwise *x == *y.
3Remarks: Instantiations of this function template for which *x == *y is a core constant expression,
shall be constexpr functions.
template <class T> constexpr bool operator<(const optional<T>& x, const optional<T>& y);
4Requires: Expression less<T>{}(*x, *y) shall be well-formed.
5Returns: If (!y), false; otherwise, if (!x), true; otherwise less<T>{}(*x, *y).
6Remarks: Instantiations of this function template for which less<T>{}(*x, *y) is a core constant
expression, shall be constexpr functions.
§ 20.6.8 511
c
ISO/IEC N????
20.6.9 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;
1Returns: (!x).
template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
2Returns: false.
template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
3Returns: bool(x).
20.6.10 Comparison with T[optional.comp_with_t]
template <class T> constexpr bool operator==(const optional<T>& x, const T& v);
1Returns: bool(x) ? *x == v : false.
template <class T> constexpr bool operator==(const T& v, const optional<T>& x);
2Returns: bool(x) ? v == *x : false.
template <class T> constexpr bool operator<(const optional<T>& x, const T& v);
3Returns: bool(x) ? less<T>{}(*x, v) : true.
20.6.11 Specialized algorithms [optional.specalg]
template <class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
1Effects: calls x.swap(y).
template <class T> constexpr optional<decay_t<T>{>} make_optional(T&& v);
2Returns: optional<decay_t<T>>(std::forward<T>(v)).
20.6.12 Hash support [optional.hash]
template <class T> struct hash<optional<T>>;
1Requires: The template specialization hash<T> shall meet the requirements of class template hash
(20.10.12).
2The template specialization hash<optional<T>> shall meet the requirements of class template hash.
3For an object oof type optional<T>, if bool(o) == true,hash<optional<T>>()(o) shall evaluate
to the same value as hash<T>()(*o).
§ 20.6.12 512
c
ISO/IEC N????
20.7 Class template bitset [template.bitset]
Header <bitset> synopsis
#include <string>
#include <iosfwd> // for istream,ostream
namespace std {
template <size_t N> class bitset;
// 20.7.4 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);
}
1The header <bitset> defines a class template and several related functions for representing and manipulating
fixed-size sequences of bits.
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();
};
// 20.7.1 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,
§ 20.7 513
c
ISO/IEC N????
charT zero = charT(’0’), charT one = charT(’1’));
// 20.7.2 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;
};
// 20.7.3 hash support
template <class T> struct hash;
template <size_t N> struct hash<bitset<N> >;
}
2The class template bitset<N>describes an object that can store a sequence consisting of a fixed number of
bits, N.
3Each 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.
4The functions described in this subclause can report three kinds of errors, each associated with a distinct
exception:
an invalid-argument error is associated with exceptions of type invalid_argument (19.2.3);
an out-of-range error is associated with exceptions of type out_of_range (19.2.5);
§ 20.7 514
c
ISO/IEC N????
an overflow error is associated with exceptions of type overflow_error (19.2.8).
20.7.1 bitset constructors [bitset.cons]
constexpr bitset() noexcept;
1Effects: Constructs an object of class bitset<N>, initializing all bits to zero.
constexpr bitset(unsigned long long val) noexcept;
2Effects: Constructs an object of class bitset<N>, initializing the first Mbit positions to the correspond-
ing bit values in val.Mis the smaller of Nand the number of bits in the value representation (3.9) 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’));
3Requires: pos <= str.size().
4Throws: out_of_range if pos > str.size().
5Effects: Determines the effective length rlen of the initializing string as the smaller of nand 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 Mbit positions to
values determined from the corresponding characters in the string str.Mis the smaller of Nand rlen.
6An element of the constructed string has value zero if the corresponding character in str, beginning
at position pos, is 0 zero. Otherwise, the element has the value 1. Character position pos+M-1
corresponds to bit position zero. Subsequent decreasing character positions correspond to increasing
bit positions.
7If 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’));
8Effects: 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)
§ 20.7.1 515
c
ISO/IEC N????
20.7.2 bitset members [bitset.members]
bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
1Effects: Clears each bit in *this for which the corresponding bit in rhs is clear, and leaves all other
bits unchanged.
2Returns: *this.
bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
3Effects: Sets each bit in *this for which the corresponding bit in rhs is set, and leaves all other bits
unchanged.
4Returns: *this.
bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
5Effects: Toggles each bit in *this for which the corresponding bit in rhs is set, and leaves all other
bits unchanged.
6Returns: *this.
bitset<N>& operator<<=(size_t pos) noexcept;
7Effects: Replaces each bit at position Iin *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.
8Returns: *this.
bitset<N>& operator>>=(size_t pos) noexcept;
9Effects: Replaces each bit at position Iin *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.
10 Returns: *this.
bitset<N>& set() noexcept;
11 Effects: Sets all bits in *this.
12 Returns: *this.
bitset<N>& set(size_t pos, bool val = true);
13 Requires: pos is valid
14 Throws: out_of_range if pos does not correspond to a valid bit position.
15 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.
16 Returns: *this.
§ 20.7.2 516
c
ISO/IEC N????
bitset<N>& reset() noexcept;
17 Effects: Resets all bits in *this.
18 Returns: *this.
bitset<N>& reset(size_t pos);
19 Requires: pos is valid
20 Throws: out_of_range if pos does not correspond to a valid bit position.
21 Effects: Resets the bit at position pos in *this.
22 Returns: *this.
bitset<N> operator~() const noexcept;
23 Effects: Constructs an object xof class bitset<N> and initializes it with *this.
24 Returns: x.flip().
bitset<N>& flip() noexcept;
25 Effects: Toggles all bits in *this.
26 Returns: *this.
bitset<N>& flip(size_t pos);
27 Requires: pos is valid
28 Throws: out_of_range if pos does not correspond to a valid bit position.
29 Effects: Toggles the bit at position pos in *this.
30 Returns: *this.
unsigned long to_ulong() const;
31 Throws: overflow_error if the integral value xcorresponding to the bits in *this cannot be repre-
sented as type unsigned long.
32 Returns: x.
unsigned long long to_ullong() const;
33 Throws: overflow_error if the integral value xcorresponding to the bits in *this cannot be repre-
sented as type unsigned long long.
34 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;
§ 20.7.2 517
c
ISO/IEC N????
35 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-1corresponds 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.
36 Returns: The created object.
size_t count() const noexcept;
37 Returns: A count of the number of bits set in *this.
constexpr size_t size() const noexcept;
38 Returns: N.
bool operator==(const bitset<N>& rhs) const noexcept;
39 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;
40 Returns: true if !(*this == rhs).
bool test(size_t pos) const;
41 Requires: pos is valid
42 Throws: out_of_range if pos does not correspond to a valid bit position.
43 Returns: true if the bit at position pos in *this has the value one.
bool all() const noexcept;
44 Returns: count() == size()
bool any() const noexcept;
45 Returns: count() != 0
bool none() const noexcept;
46 Returns: count() == 0
bitset<N> operator<<(size_t pos) const noexcept;
47 Returns: bitset<N>(*this) <<= pos.
bitset<N> operator>>(size_t pos) const noexcept;
§ 20.7.2 518
c
ISO/IEC N????
48 Returns: bitset<N>(*this) >>= pos.
constexpr bool operator[](size_t pos) const;
49 Requires: pos shall be valid.
50 Returns: true if the bit at position pos in *this has the value one, otherwise false.
51 Throws: Nothing.
bitset<N>::reference operator[](size_t pos);
52 Requires: pos shall be valid.
53 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).
54 Throws: Nothing.
55 Remark: For the purpose of determining the presence of a data race (1.10), any access or update
through the resulting reference potentially accesses or modifies, respectively, the entire underlying
bitset.
20.7.3 bitset hash support [bitset.hash]
template <size_t N> struct hash<bitset<N> >;
1The template specialization shall meet the requirements of class template hash (20.10.12).
20.7.4 bitset operators [bitset.operators]
bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
1Returns: bitset<N>(lhs) &= rhs.
bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
2Returns: bitset<N>(lhs) |= rhs.
bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
3Returns: 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);
4A formatted input function (27.7.2.2).
5Effects: Extracts up to Ncharacters 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:
Ncharacters have been extracted and stored;
end-of-file occurs on the input sequence;
§ 20.7.4 519
c
ISO/IEC N????
the next input character is neither is.widen(’0’) nor is.widen(’1’) (in which case the input
character is not extracted).
6If no characters are stored in str, calls is.setstate(ios_base::failbit) (which may throw ios_-
base::failure (27.5.5.4)).
7Returns: is.
template <class charT, class traits, size_t N>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
8Returns:
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 27.7.3.6).
20.8 Memory [memory]
20.8.1 In general [memory.general]
1This subclause describes the contents of the header <memory> (20.8.2) and some of the contents of the C
headers <cstdlib> and cstring> (20.8.13).
20.8.2 Header <memory> synopsis [memory.syn]
1The 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, and construct multiple
objects in uninitialized memory buffers (20.8.320.8.12). The header also defines the templates unique_ptr,
shared_ptr,weak_ptr, and various template functions that operate on objects of these types (20.9).
namespace std {
// 20.8.3, pointer traits
template <class Ptr> struct pointer_traits;
template <class T> struct pointer_traits<T*>;
// 20.8.4, 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;
// 20.8.5, pointer alignment function
void* align(std::size_t alignment, std::size_t size,
void*& ptr, std::size_t& space);
// 20.8.6, allocator argument tag
struct allocator_arg_t { };
constexpr allocator_arg_t allocator_arg = allocator_arg_t();
// 20.8.7,uses_allocator
template <class T, class Alloc> struct uses_allocator;
§ 20.8.2 520
c
ISO/IEC N????
// 20.8.8, allocator traits
template <class Alloc> struct allocator_traits;
// 20.8.9, the default allocator:
template <class T> class allocator;
template <> class allocator<void>;
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;
// 20.8.10, raw storage iterator:
template <class OutputIterator, class T> class raw_storage_iterator;
// 20.8.11, temporary buffers:
template <class T>
pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
template <class T>
void return_temporary_buffer(T* p);
// 20.8.12, specialized algorithms:
template <class T> T* addressof(T& r) noexcept;
template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(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 ForwardIterator, class T>
void uninitialized_fill(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);
// 20.9.1 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>
§ 20.8.2 521
c
ISO/IEC N????
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);
// 20.9.2.1, class bad_weak_ptr:
class bad_weak_ptr;
// 20.9.2.2, class template shared_ptr:
template<class T> class shared_ptr;
// 20.9.2.2.6, 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);
// 20.9.2.2.7, shared_ptr comparisons:
template<class T, class U>
bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template <class T>
§ 20.8.2 522
c
ISO/IEC N????
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;
// 20.9.2.2.8, shared_ptr specialized algorithms:
template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
// 20.9.2.2.9, shared_ptr casts:
template<class T, class U>
shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
template<class T, class U>
shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
template<class T, class U>
shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
// 20.9.2.2.10, shared_ptr get_deleter:
template<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
// 20.9.2.2.11, shared_ptr I/O:
template<class E, class T, class Y>
basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
// 20.9.2.3, class template weak_ptr:
template<class T> class weak_ptr;
// 20.9.2.3.6, weak_ptr specialized algorithms:
template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
// 20.9.2.3.7, class template owner_less:
template<class T> class owner_less;
// 20.9.2.4, class template enable_shared_from_this:
template<class T> class enable_shared_from_this;
// 20.9.2.5, shared_ptr atomic access:
§ 20.8.2 523
c
ISO/IEC N????
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);
// 20.9.2.6 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> >;
// D.10, auto_ptr (deprecated)
template <class X> class auto_ptr;
}
20.8.3 Pointer traits [pointer.traits]
1The class template pointer_traits supplies a uniform interface to certain attributes of pointer-like types.
namespace std {
template <class Ptr> struct pointer_traits {
typedef Ptr pointer;
typedef see below element_type;
typedef see below difference_type;
template <class U> using rebind = see below ;
static pointer pointer_to(see below r);
};
§ 20.8.3 524
c
ISO/IEC N????
template <class T> struct pointer_traits<T*> {
typedef T* pointer;
typedef T element_type;
typedef ptrdiff_t difference_type;
template <class U> using rebind = U*;
static pointer pointer_to(see below r) noexcept;
};
}
20.8.3.1 Pointer traits member types [pointer.traits.types]
typedef see below element_type;
1Type: Ptr::element_type if such a type exists; otherwise, Tif Ptr is a class template instantia-
tion of the form SomePointer<T, Args>, where Args is zero or more type arguments; otherwise, the
specialization is ill-formed.
typedef see below difference_type;
2Type: Ptr::difference_type if such a type exists; otherwise, std::ptrdiff_t.
template <class U> using rebind = see below ;
3Alias template: Ptr::rebind<U> if such a type exists; 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.
20.8.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;
Remark: if element_type is (possibly cv-qualified) void, the type of ris unspecified; otherwise, it is
element_type&.
Returns: The first member function returns a pointer to robtained 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
std::addressof(r).
20.8.4 Pointer safety [util.dynamic.safety]
1A 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);
2Requires: pshall be a safely-derived pointer (3.7.4.3) or a null pointer value.
3Effects: If pis not null, the complete object referenced by pis subsequently declared reachable (3.7.4.3).
4Throws: May throw std::bad_alloc if the system cannot allocate additional memory that may be
required to track objects declared reachable.
§ 20.8.4 525
c
ISO/IEC N????
template <class T> T* undeclare_reachable(T* p);
5Requires: If pis not null, the complete object referenced by pshall have been previously declared
reachable, and shall be live (3.8) from the time of the call until the last undeclare_reachable(p) call
on the object.
6Returns: A safely derived copy of pwhich shall compare equal to p.
7Throws: Nothing.
8[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);
9Requires: 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 ob-
ject. 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 ]
10 Effects: The nbytes starting at pno 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 ]
11 Throws: Nothing.
12 [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);
13 Requires: The same range must previously have been passed to declare_no_pointers().
14 Effects: Unregisters a range registered with declare_no_pointers() for destruction. It must be called
before the lifetime of the object ends.
15 Throws: Nothing.
pointer_safety get_pointer_safety() noexcept;
16 Returns: pointer_safety::strict if the implementation has strict pointer safety (3.7.4.3). It is im-
plementation defined whether get_pointer_safety returns pointer_safety::relaxed or pointer_-
safety::preferred if the implementation has relaxed pointer safety.232
232) pointer_safety::preferred might be returned to indicate that a leak detector is running so that the program can avoid
spurious leak reports.
§ 20.8.4 526
c
ISO/IEC N????
20.8.5 Align [ptr.align]
void* align(std::size_t alignment, std::size_t size,
void*& ptr, std::size_t& space);
1Effects: 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 point to the first possible address of such storage
and decreases space by the number of bytes used for alignment. Otherwise, the function does nothing.
2Requires:
alignment shall be a fundamental alignment value or an extended alignment value supported by
the implementation in this context
ptr shall point to contiguous storage of at least space bytes
3Returns: A null pointer if the requested aligned buffer would not fit into the available space, otherwise
the adjusted value of ptr.
4[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 ]
20.8.6 Allocator argument tag [allocator.tag]
namespace std {
struct allocator_arg_t { };
constexpr allocator_arg_t allocator_arg = allocator_arg_t();
}
1The 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 20.4) have constructors with allocator_-
arg_t as the first argument, immediately followed by an argument of a type that satisfies the Allocator
requirements (17.6.3.5).
20.8.7 uses_allocator [allocator.uses]
20.8.7.1 uses_allocator trait [allocator.uses.trait]
template <class T, class Alloc> struct uses_allocator;
1Remark: automatically detects whether Thas a nested allocator_type that is convertible from Alloc.
Meets the BinaryTypeTrait requirements (20.11.1). The implementation shall provide a definition
that is derived from true_type if a type T::allocator_type exists and is_convertible<Alloc,
T::allocator_type>::value != 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 Tthat 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.
20.8.7.2 uses-allocator construction [allocator.uses.construction]
1Uses-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<T, Alloc>::value is false and is_constructible<T, V1, V2, ..., VN>::value
is true, then obj is initialized as obj(v1, v2, ..., vN);
§ 20.8.7.2 527
c
ISO/IEC N????
otherwise, if uses_allocator<T, Alloc>::value is true and is_constructible<T, allocator_-
arg_t, Alloc, V1, V2, ..., VN>::value is true, then obj is initialized as obj(allocator_arg,
alloc, v1, v2, ..., vN);
otherwise, if uses_allocator<T, Alloc>::value is true and is_constructible<T, V1, V2, ...,
VN, Alloc>::value 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<T, Alloc>::value 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 ]
20.8.8 Allocator traits [allocator.traits]
1The 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 {
typedef Alloc allocator_type;
typedef typename Alloc::value_type value_type;
typedef see below pointer;
typedef see below const_pointer;
typedef see below void_pointer;
typedef see below const_void_pointer;
typedef see below difference_type;
typedef see below size_type;
typedef see below propagate_on_container_copy_assignment;
typedef see below propagate_on_container_move_assignment;
typedef see below propagate_on_container_swap;
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);
};
}
20.8.8.1 Allocator traits member types [allocator.traits.types]
§ 20.8.8.1 528
c
ISO/IEC N????
typedef see below pointer;
1Type: Alloc::pointer if such a type exists; otherwise, value_type*.
typedef see below const_pointer;
2Type: Alloc::const_pointer if such a type exists; otherwise, pointer_traits<pointer>::rebind<
const value_type>.
typedef see below void_pointer;
3Type: Alloc::void_pointer if such a type exists; otherwise, pointer_traits<pointer>::rebind<
void>.
typedef see below const_void_pointer;
4Type: Alloc::const_void_pointer if such a type exists; otherwise, pointer_traits<pointer>::
rebind<const void>.
typedef see below difference_type;
5Type: Alloc::difference_type if such a type exists; otherwise, pointer_traits<pointer>::dif-
ference_type.
typedef see below size_type;
6Type: Alloc::size_type if such a type exists; otherwise, make_unsigned<difference_type>::type.
typedef see below propagate_on_container_copy_assignment;
7Type: Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise false_-
type.
typedef see below propagate_on_container_move_assignment;
8Type: Alloc::propagate_on_container_move_assignment if such a type exists, otherwise false_-
type.
typedef see below propagate_on_container_swap;
9Type: Alloc::propagate_on_container_swap if such a type exists, otherwise false_type.
template <class T> using rebind_alloc = see below ;
10 Alias template: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args> if Alloc
is a class template instantiation of the form Alloc<U, Args>, where Args is zero or more type argu-
ments; otherwise, the instantiation of rebind_alloc is ill-formed.
§ 20.8.8.1 529
c
ISO/IEC N????
20.8.8.2 Allocator traits static member functions [allocator.traits.members]
static pointer allocate(Alloc& a, size_type n);
1Returns: a.allocate(n).
static pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
2Returns: a.allocate(n, hint) if that expression is well-formed; otherwise, a.allocate(n).
static void deallocate(Alloc& a, pointer p, size_type n);
3Effects: calls a.deallocate(p, n).
4Throws: Nothing.
template <class T, class... Args>
static void construct(Alloc& a, T* p, Args&&... args);
5Effects: 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);
6Effects: calls a.destroy(p) if that call is well-formed; otherwise, invokes p->˜T().
static size_type max_size(Alloc& a) noexcept;
7Returns: a.max_size() if that expression is well-formed; otherwise, numeric_limits<size_type>::
max().
static Alloc select_on_container_copy_construction(const Alloc& rhs);
8Returns: rhs.select_on_container_copy_construction() if that expression is well-formed; other-
wise, rhs.
20.8.9 The default allocator [default.allocator]
namespace std {
template <class T> class allocator;
// specialize for void:
template <> class allocator<void> {
public:
typedef void* pointer;
typedef const void* const_pointer;
// reference-to-void members are impossible.
typedef void value_type;
template <class U> struct rebind { typedef allocator<U> other; };
};
§ 20.8.9 530
c
ISO/IEC N????
template <class T> class allocator {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U> struct rebind { typedef allocator<U> other; };
typedef true_type propagate_on_container_move_assignment;
allocator() noexcept;
allocator(const allocator&) noexcept;
template <class U> allocator(const allocator<U>&) noexcept;
~allocator();
pointer address(reference x) const noexcept;
const_pointer address(const_reference x) const noexcept;
pointer allocate(
size_type, allocator<void>::const_pointer hint = 0);
void deallocate(pointer p, size_type n);
size_type max_size() const noexcept;
template<class U, class... Args>
void construct(U* p, Args&&... args);
template <class U>
void destroy(U* p);
};
}
20.8.9.1 allocator members [allocator.members]
1Except for the destructor, member functions of the default allocator shall not introduce data races (1.10)
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.
pointer address(reference x) const noexcept;
2Returns: The actual address of the object referenced by x, even in the presence of an overloaded
operator&.
const_pointer address(const_reference x) const noexcept;
3Returns: The actual address of the object referenced by x, even in the presence of an overloaded
operator&.
pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
4[Note: In a container member function, the address of an adjacent element is often a good choice to
pass for the hint argument. — end note ]
5Returns: A pointer to the initial element of an array of storage of size n * sizeof(T), aligned appropri-
ately for objects of type T. It is implementation-defined whether over-aligned types are supported (3.11).
§ 20.8.9.1 531
c
ISO/IEC N????
6Remark: the storage is obtained by calling ::operator new(std::size_t) (18.6.1), but it is unspec-
ified when or how often this function is called. The use of hint is unspecified, but intended as an aid
to locality if an implementation so desires.
7Throws: bad_alloc if the storage cannot be obtained.
void deallocate(pointer p, size_type n);
8Requires: pshall be a pointer value obtained from allocate().nshall equal the value passed as the
first argument to the invocation of allocate which returned p.
9Effects: Deallocates the storage referenced by p.
10 Remarks: Uses ::operator delete(void*) (18.6.1), but it is unspecified when this function is called.
size_type max_size() const noexcept;
11 Returns: The largest value Nfor which the call allocate(N,0) might succeed.
template <class U, class... Args>
void construct(U* p, Args&&... args);
12 Effects: ::new((void *)p) U(std::forward<Args>(args)...)
template <class U>
void destroy(U* p);
13 Effects: p->˜U()
20.8.9.2 allocator globals [allocator.globals]
template <class T1, class T2>
bool operator==(const allocator<T1>&, const allocator<T2>&) noexcept;
1Returns: true.
template <class T1, class T2>
bool operator!=(const allocator<T1>&, const allocator<T2>&) noexcept;
2Returns: false.
20.8.10 Raw storage iterator [storage.iterator]
1raw_storage_iterator is provided to enable algorithms to store their results into uninitialized memory.
The formal 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 (24.2.4).
namespace std {
template <class OutputIterator, class T>
class raw_storage_iterator
: public iterator<output_iterator_tag,void,void,void,void> {
public:
explicit raw_storage_iterator(OutputIterator x);
§ 20.8.10 532
c
ISO/IEC N????
raw_storage_iterator& operator*();
raw_storage_iterator& operator=(const T& element);
raw_storage_iterator& operator++();
raw_storage_iterator operator++(int);
};
}
explicit raw_storage_iterator(OutputIterator x);
2Effects: Initializes the iterator to point to the same value to which xpoints.
raw_storage_iterator& operator*();
3Returns: *this
raw_storage_iterator& operator=(const T& element);
4Effects: Constructs a value from element at the location to which the iterator points.
5Returns: A reference to the iterator.
raw_storage_iterator& operator++();
6Effects: Pre-increment: advances the iterator and returns a reference to the updated iterator.
raw_storage_iterator operator++(int);
7Effects: Post-increment: advances the iterator and returns the old value of the iterator.
20.8.11 Temporary buffers [temporary.buffer]
template <class T>
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
1Effects: Obtains a pointer to storage sufficient to store up to nadjacent Tobjects. It is implementation-
defined whether over-aligned types are supported (3.11).
2Returns: Apair containing the buffer’s address and capacity (in the units of sizeof(T)), or a pair
of 0 values if no storage can be obtained or if n <= 0.
template <class T> void return_temporary_buffer(T* p);
3Effects: Deallocates the buffer to which ppoints.
4Requires: The buffer shall have been previously allocated by get_temporary_buffer.
20.8.12 Specialized algorithms [specialized.algorithms]
1All the iterators that are used as formal template parameters in the following algorithms are required to
have their operator* return an object for which operator& is defined and returns a pointer to T. In the
algorithm uninitialized_copy, the formal template parameter InputIterator is required to satisfy the
requirements of an input iterator (24.2.3). In all of the following algorithms, the formal template parameter
ForwardIterator is required to satisfy the requirements of a forward iterator (24.2.5), and is required to
have the property that no exceptions are thrown from increment, assignment, comparison, or indirection
through valid iterators. In the following algorithms, if an exception is thrown there are no effects.
20.8.12.1 addressof [specialized.addressof]
§ 20.8.12.1 533
c
ISO/IEC N????
template <class T> T* addressof(T& r) noexcept;
1Returns: The actual address of the object or function referenced by r, even in the presence of an
overloaded operator&.
20.8.12.2 uninitialized_copy [uninitialized.copy]
template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result);
1Effects:
for (; first != last; ++result, ++first)
::new (static_cast<void*>(&*result))
typename iterator_traits<ForwardIterator>::value_type(*first);
2Returns: result
template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
ForwardIterator result);
3Effects:
for ( ; n > 0; ++result, ++first, --n) {
::new (static_cast<void*>(&*result))
typename iterator_traits<ForwardIterator>::value_type(*first);
}
4Returns: result
20.8.12.3 uninitialized_fill [uninitialized.fill]
template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x);
1Effects:
for (; first != last; ++first)
::new (static_cast<void*>(&*first))
typename iterator_traits<ForwardIterator>::value_type(x);
20.8.12.4 uninitialized_fill_n [uninitialized.fill.n]
template <class ForwardIterator, class Size, class T>
ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
1Effects:
for (; n--; ++first)
::new (static_cast<void*>(&*first))
typename iterator_traits<ForwardIterator>::value_type(x);
return first;
§ 20.8.12.4 534
c
ISO/IEC N????
Table 45 — Header <cstdlib> synopsis
Type Name(s)
Functions:calloc malloc
free realloc
20.8.13 C library [c.malloc]
1Table 45 describes the header <cstdlib>.
2The contents are the same as the Standard C library header <stdlib.h>, with the following changes:
3The functions calloc(),malloc(), and realloc() do not attempt to allocate storage by calling ::operator
new() (18.6).
4The function free() does not attempt to deallocate storage by calling ::operator delete().
See also: ISO C Clause 7.11.2.
5Storage allocated directly with malloc(),calloc(), or realloc() is implicitly declared reachable (see 3.7.4.3)
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 collec-
tion 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 ]
6Table 46 describes the header <cstring>.
Table 46 — Header <cstring> synopsis
Type Name(s)
Macro:NULL
Type:size_t
Functions:memchr memcmp
memcpy memmove memset
7The contents are the same as the Standard C library header <string.h>, with the change to memchr()
specified in 21.8.
See also: ISO C Clause 7.11.2.
20.9 Smart pointers [smartptr]
20.9.1 Class template unique_ptr [unique.ptr]
1Aunique pointer is an object that owns another object and manages that other object through a pointer.
More precisely, a unique pointer is an object uthat stores a pointer to a second object pand will dispose of
pwhen uis itself destroyed (e.g., when leaving block scope (6.7)). In this context, uis said to own p.
2The mechanism by which udisposes of pis known as p’s associated deleter, a function object whose correct
invocation results in p’s appropriate disposition (typically its deletion).
3Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request,
ucan 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.
§ 20.9.1 535
c
ISO/IEC N????
4Additionally, ucan, 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 ]
5Each object of a type Uinstantiated 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 Uis MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
The template parameter Tof unique_ptr may be an incomplete type.
6[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);
§ 20.9.1 536
c
ISO/IEC N????
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);
}
20.9.1.1 Default deleters [unique.ptr.dltr]
20.9.1.1.1 In general [unique.ptr.dltr.general]
1The class template default_delete serves as the default deleter (destruction policy) for the class template
unique_ptr.
2The template parameter Tof default_delete may be an incomplete type.
20.9.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;
1Effects: Constructs a default_delete object from another default_delete<U> object.
2Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible
to T*.
void operator()(T* ptr) const;
3Effects: calls delete on ptr.
4Remarks: If Tis an incomplete type, the program is ill-formed.
20.9.1.1.3 default_delete<T[]> [unique.ptr.dltr.dflt1]
namespace std {
template <class T> struct default_delete<T[]> {
constexpr default_delete() noexcept = default;
void operator()(T*) const;
template <class U> void operator()(U*) const = delete;
};
}
§ 20.9.1.1.3 537
c
ISO/IEC N????
void operator()(T* ptr) const;
1Effects: calls delete[] on ptr.
2Remarks: If T is an incomplete type, the program is ill-formed.
20.9.1.2 unique_ptr for single objects [unique.ptr.single]
namespace std {
template <class T, class D = default_delete<T>> class unique_ptr {
public:
typedef see below pointer;
typedef T element_type;
typedef D deleter_type;
// 20.9.1.2.1, 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
: unique_ptr() { }
template <class U, class E>
unique_ptr(unique_ptr<U, E>&& u) noexcept;
template <class U>
unique_ptr(auto_ptr<U>&& u) noexcept;
// 20.9.1.2.2, destructor
~unique_ptr();
// 20.9.1.2.3, 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;
// 20.9.1.2.4, 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;
// 20.9.1.2.5 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;
};
}
1The default type for the template parameter Dis default_delete. A client-supplied template argument D
shall be a function object type (20.10), lvalue-reference to function, or lvalue-reference to function object type
§ 20.9.1.2 538
c
ISO/IEC N????
for which, given a value dof type Dand 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.
2If the deleter’s type Dis not a reference type, Dshall satisfy the requirements of Destructible (Table 24).
3If the type remove_reference<D>::type::pointer exists, then unique_ptr<T, D>::pointer shall be a
synonym for remove_reference<D>::type::pointer. Otherwise unique_ptr<T, D>::pointer shall be a
synonym for T*. The type unique_ptr<T, D>::pointer shall satisfy the requirements of NullablePointer
(17.6.3.3).
4[Example: Given an allocator type X(17.6.3.5) and letting Abe 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 ]
20.9.1.2.1 unique_ptr constructors [unique.ptr.single.ctor]
constexpr unique_ptr() noexcept;
1Requires: Dshall satisfy the requirements of DefaultConstructible (Table 19), and that construction
shall not throw an exception.
2Effects: Constructs a unique_ptr object that owns nothing, value-initializing the stored pointer and
the stored deleter.
3Postconditions: get() == nullptr.get_deleter() returns a reference to the stored deleter.
4Remarks: If this constructor is instantiated with a pointer type or reference type for the template
argument D, the program is ill-formed.
explicit unique_ptr(pointer p) noexcept;
5Requires: Dshall satisfy the requirements of DefaultConstructible (Table 19), and that construction
shall not throw an exception.
6Effects: Constructs a unique_ptr which owns p, initializing the stored pointer with pand value-
initializing the stored deleter.
7Postconditions: get() == p.get_deleter() returns a reference to the stored deleter.
8Remarks: If this constructor is instantiated with a pointer type or reference type for the template
argument D, the program is ill-formed.
unique_ptr(pointer p, see below d1) noexcept;
unique_ptr(pointer p, see below d2) noexcept;
9The signature of these constructors depends upon whether Dis a reference type. If Dis non-reference
type A, then the signatures are:
unique_ptr(pointer p, const A& d);
unique_ptr(pointer p, A&& d);
10 If Dis an lvalue-reference type A&, then the signatures are:
unique_ptr(pointer p, A& d);
unique_ptr(pointer p, A&& d);
11 If Dis an lvalue-reference type const A&, then the signatures are:
unique_ptr(pointer p, const A& d);
unique_ptr(pointer p, const A&& d);
12 Requires:
§ 20.9.1.2.1 539
c
ISO/IEC N????
If Dis not an lvalue-reference type then
If dis an lvalue or const rvalue then the first constructor of this pair will be selected. Dshall
satisfy the requirements of CopyConstructible (Table 21), and the copy constructor of D
shall not throw an exception. This unique_ptr will hold a copy of d.
Otherwise, dis a non-const rvalue and the second constructor of this pair will be selected. D
shall satisfy the requirements of MoveConstructible (Table 20), and the move constructor
of Dshall not throw an exception. This unique_ptr will hold a value move constructed from
d.
Otherwise Dis an lvalue-reference type. dshall be reference-compatible with one of the con-
structors. If dis an rvalue, it will bind to the second constructor of this pair and the program
is ill-formed. [ Note: The diagnostic could be implemented using a static_assert which as-
sures that Dis not a reference type. — end note ] Else dis an lvalue and will bind to the
first constructor of this pair. The type which Dreferences need not be CopyConstructible nor
MoveConstructible. This unique_ptr will hold a Dwhich refers to the lvalue d. [ Note: Dmay
not be an rvalue-reference type. — end note ]
13 Effects: Constructs a unique_ptr object which owns p, initializing the stored pointer with pand
initializing the deleter as described above.
14 Postconditions: get() == p.get_deleter() returns a reference to the stored deleter. If Dis a
reference type then get_deleter() returns a reference to the lvalue d.
[Example:
D d;
unique_ptr<int, D> p1(new int, D()); // Dmust be MoveConstructible
unique_ptr<int, D> p2(new int, d); // Dmust 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;
15 Requires: If Dis not a reference type, Dshall satisfy the requirements of MoveConstructible (Table 20).
Construction of the deleter from an rvalue of type Dshall not throw an exception.
16 Effects: Constructs a unique_ptr by transferring ownership from uto *this. If Dis 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 ]
17 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 Dis 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;
18 Requires: If Eis not a reference type, construction of the deleter from an rvalue of type Eshall be
well formed and shall not throw an exception. Otherwise, Eis a reference type and construction of the
deleter from an lvalue of type Eshall be well formed and shall not throw an exception.
19 Remarks: This constructor shall not participate in overload resolution unless:
unique_ptr<U, E>::pointer is implicitly convertible to pointer,
§ 20.9.1.2.1 540
c
ISO/IEC N????
Uis not an array type, and
either Dis a reference type and Eis the same type as D, or Dis not a reference type and Eis
implicitly convertible to D.
20 Effects: Constructs a unique_ptr by transferring ownership from uto *this. If Eis 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 ]
21 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().
template <class U>
unique_ptr(auto_ptr<U>&& u) noexcept;
22 Effects: Constructs a unique_ptr object, initializing the stored pointer with u.release() and value-
initializing the stored deleter.
23 Postconditions: get() yields the value u.get() yielded before the construction. u.get() == nullptr.
get_deleter() returns a reference to the stored deleter.
24 Remarks: This constructor shall not participate in overload resolution unless U* is implicitly convertible
to T* and Dis the same type as default_delete<T>.
20.9.1.2.2 unique_ptr destructor [unique.ptr.single.dtor]
~unique_ptr();
1Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behav-
ior, and shall not throw exceptions. [ Note: The use of default_delete requires Tto be a complete
type. — end note ]
2Effects: If get() == nullptr there are no effects. Otherwise get_deleter()(get()).
20.9.1.2.3 unique_ptr assignment [unique.ptr.single.asgn]
unique_ptr& operator=(unique_ptr&& u) noexcept;
1Requires: If Dis not a reference type, Dshall satisfy the requirements of MoveAssignable (Table 22)
and assignment of the deleter from an rvalue of type Dshall not throw an exception. Otherwise, D
is a reference type; remove_reference<D>::type shall satisfy the CopyAssignable requirements and
assignment of the deleter from an lvalue of type Dshall not throw an exception.
2Effects: Transfers ownership from uto *this as if by calling reset(u.release()) followed by an
assignment from std::forward<D>(u.get_deleter()).
3Returns: *this.
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
4Requires: If Eis not a reference type, assignment of the deleter from an rvalue of type Eshall be
well-formed and shall not throw an exception. Otherwise, Eis a reference type and assignment of the
deleter from an lvalue of type Eshall be well-formed and shall not throw an exception.
5Remarks: This operator shall not participate in overload resolution unless:
unique_ptr<U, E>::pointer is implicitly convertible to pointer and
Uis not an array type.
§ 20.9.1.2.3 541
c
ISO/IEC N????
6Effects: Transfers ownership from uto *this as if by calling reset(u.release()) followed by an
assignment from std::forward<E>(u.get_deleter()).
7Returns: *this.
unique_ptr& operator=(nullptr_t) noexcept;
8Effects: reset().
9Postcondition: get() == nullptr
10 Returns: *this.
20.9.1.2.4 unique_ptr observers [unique.ptr.single.observers]
add_lvalue_reference_t<T> operator*() const;
1Requires: get() != nullptr.
2Returns: *get().
pointer operator->() const noexcept;
3Requires: get() != nullptr.
4Returns: get().
5Note: use typically requires that Tbe a complete type.
pointer get() const noexcept;
6Returns: The stored pointer.
deleter_type& get_deleter() noexcept;
const deleter_type& get_deleter() const noexcept;
7Returns: A reference to the stored deleter.
explicit operator bool() const noexcept;
8Returns: get() != nullptr.
20.9.1.2.5 unique_ptr modifiers [unique.ptr.single.modifiers]
pointer release() noexcept;
1Postcondition: get() == nullptr.
2Returns: The value get() had at the start of the call to release.
void reset(pointer p = pointer()) noexcept;
§ 20.9.1.2.5 542
c
ISO/IEC N????
3Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behav-
ior, and shall not throw exceptions.
4Effects: assigns pto the stored pointer, and then 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 ]
5Postconditions: 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;
6Requires: get_deleter() shall be swappable (17.6.3.2) and shall not throw an exception under swap.
7Effects: Invokes swap on the stored pointers and on the stored deleters of *this and u.
20.9.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:
typedef see below pointer;
typedef T element_type;
typedef D deleter_type;
// 20.9.1.3.1, constructors
constexpr unique_ptr() noexcept;
explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, see below d) noexcept;
unique_ptr(pointer p, see below d) noexcept;
unique_ptr(unique_ptr&& u) noexcept;
constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
// destructor
~unique_ptr();
// assignment
unique_ptr& operator=(unique_ptr&& u) noexcept;
unique_ptr& operator=(nullptr_t) noexcept;
// 20.9.1.3.2, 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;
// 20.9.1.3.3 modifiers
pointer release() noexcept;
void reset(pointer p = pointer()) noexcept;
void reset(nullptr_t) noexcept;
template <class U> void reset(U) = delete;
void swap(unique_ptr& u) noexcept;
// disable copy from lvalue
unique_ptr(const unique_ptr&) = delete;
§ 20.9.1.3 543
c
ISO/IEC N????
unique_ptr& operator=(const unique_ptr&) = delete;
};
}
1A specialization for array types is provided with a slightly altered interface.
Conversions between different types of unique_ptr<T[], D> or to or from the non-array forms of
unique_ptr produce an ill-formed program.
Pointers to types derived from Tare 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[].
2Descriptions are provided below only for member functions that have behavior different from the primary
template.
3The template argument Tshall be a complete type.
20.9.1.3.1 unique_ptr constructors [unique.ptr.runtime.ctor]
explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, see below d) noexcept;
unique_ptr(pointer p, see below d) noexcept;
These constructors behave the same as in the primary template except that they do not accept pointer
types which are convertible to pointer. [ Note: One implementation technique is to create private
templated overloads of these members. — end note ]
20.9.1.3.2 unique_ptr observers [unique.ptr.runtime.observers]
T& operator[](size_t i) const;
1Requires: i < the number of elements in the array to which the stored pointer points.
2Returns: get()[i].
20.9.1.3.3 unique_ptr modifiers [unique.ptr.runtime.modifiers]
void reset(nullptr_t p) noexcept;
1Effects: Equivalent to reset(pointer()).
20.9.1.4 unique_ptr creation [unique.ptr.create]
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
1Remarks: This function shall not participate in overload resolution unless Tis not an array.
2Returns: unique_ptr<T>(new T(std::forward<Args>(args)...)).
template <class T> unique_ptr<T> make_unique(size_t n);
3Remarks: This function shall not participate in overload resolution unless Tis an array of unknown
bound.
4Returns: unique_ptr<T>(new remove_extent_t<T>[n]()).
template <class T, class... Args> unspecified make_unique(Args&&...) = delete;
5Remarks: This function shall not participate in overload resolution unless Tis an array of known
bound.
§ 20.9.1.4 544
c
ISO/IEC N????
20.9.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;
1Effects: 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);
2Returns: 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);
3Returns: 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);
4Requires: Let CT be common_type<unique_ptr<T1, D1>::pointer, unique_ptr<T2, D2>::poin-
ter>::type. Then the specialization less<CT> shall be a function object type (20.10) that induces a
strict weak ordering (25.4) on the pointer values.
5Returns: less<CT>()(x.get(), y.get()).
6Remarks: 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);
7Returns: !(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);
8Returns: 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);
9Returns: !(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;
10 Returns: !x.
§ 20.9.1.5 545
c
ISO/IEC N????
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;
11 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);
12 Requires: The specialization less<unique_ptr<T, D>::pointer> shall be a function object type (20.10)
that induces a strict weak ordering (25.4) on the pointer values.
13 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);
14 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);
15 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);
16 Returns: The first function template returns !(x < nullptr). The second function template returns
!(nullptr < x).
20.9.2 Shared-ownership pointers [util.smartptr]
20.9.2.1 Class bad_weak_ptr [util.smartptr.weakptr]
namespace std {
class bad_weak_ptr: public std::exception {
public:
bad_weak_ptr() noexcept;
};
}// namespace std
§ 20.9.2.1 546
c
ISO/IEC N????
1An exception of type bad_weak_ptr is thrown by the shared_ptr constructor taking a weak_ptr.
bad_weak_ptr() noexcept;
2Postconditions: what() returns "bad_weak_ptr".
20.9.2.2 Class template shared_ptr [util.smartptr.shared]
1The 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 object is empty if it does
not own a pointer.
namespace std {
template<class T> class shared_ptr {
public:
typedef T element_type;
// 20.9.2.2.1, 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, T* 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> shared_ptr(auto_ptr<Y>&& r);
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
constexpr shared_ptr(nullptr_t) : shared_ptr() { }
// 20.9.2.2.2, destructor:
~shared_ptr();
// 20.9.2.2.3, 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> shared_ptr& operator=(auto_ptr<Y>&& r);
template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
// 20.9.2.2.4, 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);
// 20.9.2.2.5, observers:
T* get() const noexcept;
T& operator*() const noexcept;
T* operator->() const noexcept;
§ 20.9.2.2 547
c
ISO/IEC N????
long use_count() const noexcept;
bool unique() const noexcept;
explicit operator bool() const noexcept;
template<class U> bool owner_before(shared_ptr<U> const& b) const;
template<class U> bool owner_before(weak_ptr<U> const& b) const;
};
// 20.9.2.2.6, 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);
// 20.9.2.2.7, 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;
// 20.9.2.2.8, shared_ptr specialized algorithms:
template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
// 20.9.2.2.9, shared_ptr casts:
§ 20.9.2.2 548
c
ISO/IEC N????
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;
// 20.9.2.2.10, shared_ptr get_deleter:
template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
// 20.9.2.2.11, 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);
}// namespace std
2Specializations of shared_ptr shall be CopyConstructible,CopyAssignable, and LessThanComparable,
allowing their use in standard containers. Specializations of shared_ptr shall be convertible to bool,
allowing their use in boolean expressions and declarations in conditions. The template parameter Tof
shared_ptr may be an incomplete type.
3[Example:
if(shared_ptr<X> px = dynamic_pointer_cast<X>(py)) {
// do something with px
}
— end example ]
4For 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.
20.9.2.2.1 shared_ptr constructors [util.smartptr.shared.const]
constexpr shared_ptr() noexcept;
1Effects: Constructs an empty shared_ptr object.
2Postconditions: use_count() == 0 && get() == 0.
template<class Y> explicit shared_ptr(Y* p);
3Requires: pshall be convertible to T*.Yshall be a complete type. The expression delete p shall be
well formed, shall have well defined behavior, and shall not throw exceptions.
4Effects: Constructs a shared_ptr object that owns the pointer p.
5Postconditions: use_count() == 1 && get() == p.
6Throws: bad_alloc, or an implementation-defined exception when a resource other than memory
could not be obtained.
7Exception safety: If an exception is thrown, delete p is called.
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);
§ 20.9.2.2.1 549
c
ISO/IEC N????
8Requires: pshall be convertible to T*.Dshall be CopyConstructible. The copy constructor and
destructor of Dshall not throw exceptions. The expression d(p) shall be well formed, shall have
well defined behavior, and shall not throw exceptions. Ashall be an allocator (17.6.3.5). The copy
constructor and destructor of Ashall not throw exceptions.
9Effects: Constructs a shared_ptr object that owns the object pand the deleter d. The second and
fourth constructors shall use a copy of ato allocate memory for internal use.
10 Postconditions: use_count() == 1 && get() == p.
11 Throws: bad_alloc, or an implementation-defined exception when a resource other than memory
could not be obtained.
12 Exception safety: If an exception is thrown, d(p) is called.
template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
13 Effects: Constructs a shared_ptr instance that stores pand shares ownership with r.
14 Postconditions: get() == p && use_count() == r.use_count()
15 [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 ris destroyed. — end note ]
16 [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;
17 Requires: The second constructor shall not participate in the overload resolution unless Y* is implicitly
convertible to T*.
18 Effects: If ris empty, constructs an empty shared_ptr object; otherwise, constructs a shared_ptr
object that shares ownership with r.
19 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;
20 Remark: The second constructor shall not participate in overload resolution unless Y* is convertible
to T*.
21 Effects: Move-constructs a shared_ptr instance from r.
22 Postconditions: *this shall contain the old value of r.rshall be empty.r.get() == 0.
template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
23 Requires: Y* shall be convertible to T*.
24 Effects: Constructs a shared_ptr object that shares ownership with rand stores a copy of the pointer
stored in r.
25 Postconditions: use_count() == r.use_count().
26 Throws: bad_weak_ptr when r.expired().
27 Exception safety: If an exception is thrown, the constructor has no effect.
§ 20.9.2.2.1 550
c
ISO/IEC N????
template<class Y> shared_ptr(auto_ptr<Y>&& r);
28 Requires: r.release() shall be convertible to T*.Yshall be a complete type. The expression delete
r.release() shall be well formed, shall have well defined behavior, and shall not throw exceptions.
29 Effects: Constructs a shared_ptr object that stores and owns r.release().
30 Postconditions: use_count() == 1 && r.get() == 0.
31 Throws: bad_alloc, or an implementation-defined exception when a resource other than memory
could not be obtained.
32 Exception safety: If an exception is thrown, the constructor has no effect.
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&&r);
33 Effects: Equivalent to shared_ptr(r.release(), r.get_deleter()) when Dis not a reference type,
otherwise shared_ptr(r.release(), ref(r.get_deleter())).
34 Exception safety: If an exception is thrown, the constructor has no effect.
20.9.2.2.2 shared_ptr destructor [util.smartptr.shared.dest]
~shared_ptr();
1Effects:
— 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 pand a deleter d,d(p) is called.
Otherwise, *this owns a pointer p, and delete p is called.
2[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 ]
20.9.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;
template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
1Effects: Equivalent to shared_ptr(r).swap(*this).
2Returns: *this.
3[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;
§ 20.9.2.2.3 551
c
ISO/IEC N????
4Effects: Equivalent to shared_ptr(std::move(r)).swap(*this).
5Returns: *this.
template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
6Effects: Equivalent to shared_ptr(std::move(r)).swap(*this).
7Returns: *this
20.9.2.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
void swap(shared_ptr& r) noexcept;
1Effects: Exchanges the contents of *this and r.
void reset() noexcept;
2Effects: Equivalent to shared_ptr().swap(*this).
template<class Y> void reset(Y* p);
3Effects: Equivalent to shared_ptr(p).swap(*this).
template<class Y, class D> void reset(Y* p, D d);
4Effects: Equivalent to shared_ptr(p, d).swap(*this).
template<class Y, class D, class A> void reset(Y* p, D d, A a);
5Effects: Equivalent to shared_ptr(p, d, a).swap(*this).
20.9.2.2.5 shared_ptr observers [util.smartptr.shared.obs]
T* get() const noexcept;
1Returns: the stored pointer.
T& operator*() const noexcept;
2Requires: get() != 0.
3Returns: *get().
4Remarks: When Tis 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;
5Requires: get() != 0.
6Returns: get().
§ 20.9.2.2.5 552
c
ISO/IEC N????
long use_count() const noexcept;
7Returns: the number of shared_ptr objects, *this included, that share ownership with *this, or 0
when *this is empty.
8[Note: use_count() is not necessarily efficient. — end note ]
bool unique() const noexcept;
9Returns: use_count() == 1.
10 [Note: unique() may be faster than use_count(). If you are using unique() to implement copy on
write, do not rely on a specific value when get() == 0.— end note ]
explicit operator bool() const noexcept;
11 Returns: get() != 0.
template<class U> bool owner_before(shared_ptr<U> const& b) const;
template<class U> bool owner_before(weak_ptr<U> const& b) const;
12 Returns: An unspecified value such that
x.owner_before(y) defines a strict weak ordering as defined in 25.4;
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 own-
ership or are both empty.
20.9.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);
1Requires: 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. Ashall be an alloca-
tor (17.6.3.5). The copy constructor and destructor of Ashall not throw exceptions.
2Effects: Allocates memory suitable for an object of type Tand 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 ato allocate memory. If an exception is thrown, the functions have
no effect.
3Returns: Ashared_ptr instance that stores and owns the address of the newly constructed object of
type T.
4Postconditions: get() != 0 && use_count() == 1
5Throws: bad_alloc, or an exception thrown from A::allocate or from the constructor of T.
6Remarks: Implementations should perform no more than one memory allocation. [ Note: This provides
efficiency equivalent to an intrusive smart pointer. — end note ]
7[Note: These functions will typically allocate more memory than sizeof(T) to allow for internal
bookkeeping structures such as the reference counts. — end note ]
§ 20.9.2.2.6 553
c
ISO/IEC N????
20.9.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;
1Returns: a.get() == b.get().
template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
2Returns: less<V>()(a.get(), b.get()), where Vis the composite pointer type (Clause 5) of T* and
U*.
3[Note: Defining a comparison operator 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;
4Returns: !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;
5Returns: (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;
6Returns: The first function template returns less<T*>()(a.get(), nullptr). The second function
template returns less<T*>()(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;
7Returns: 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;
8Returns: The first function template returns !(nullptr < a). The second function template returns
!(a < nullptr).
§ 20.9.2.2.7 554
c
ISO/IEC N????
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;
9Returns: The first function template returns !(a < nullptr). The second function template returns
!(nullptr < a).
20.9.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;
1Effects: Equivalent to a.swap(b).
20.9.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;
1Requires: The expression static_cast<T*>(r.get()) shall be well formed.
2Returns: If ris empty, an empty shared_ptr<T>; otherwise, a shared_ptr<T> object that stores
static_cast<T*>(r.get()) and shares ownership with r.
3Postconditions: w.get() == static_cast<T*>(r.get()) and w.use_count() == r.use_count(),
where wis the return value.
4[Note: The seemingly equivalent expression shared_ptr<T>(static_cast<T*>(r.get())) will even-
tually 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;
5Requires: The expression dynamic_cast<T*>(r.get()) shall be well formed and shall have well defined
behavior.
6Returns:
When dynamic_cast<T*>(r.get()) returns a nonzero value, a shared_ptr<T> object that stores
a copy of it and shares ownership with r;
Otherwise, an empty shared_ptr<T> object.
7Postcondition: w.get() == dynamic_cast<T*>(r.get()), where wis the return value.
8[Note: The seemingly equivalent expression shared_ptr<T>(dynamic_cast<T*>(r.get())) will even-
tually 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;
9Requires: The expression const_cast<T*>(r.get()) shall be well formed.
10 Returns: If ris empty, an empty shared_ptr<T>; otherwise, a shared_ptr<T> object that stores
const_cast<T*>(r.get()) and shares ownership with r.
11 Postconditions: w.get() == const_cast<T*>(r.get()) and w.use_count() == r.use_count(), where
wis the return value.
12 [Note: The seemingly equivalent expression shared_ptr<T>(const_cast<T*>(r.get())) will even-
tually result in undefined behavior, attempting to delete the same object twice. — end note ]
§ 20.9.2.2.9 555
c
ISO/IEC N????
20.9.2.2.10 get_deleter [util.smartptr.getdeleter]
template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
1Returns: If powns a deleter dof type cv-unqualified D, returns &d; otherwise returns 0. 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 phave been destroyed.
— end note ]
20.9.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, shared_ptr<Y> const& p);
1Effects: os << p.get();.
2Returns: os.
20.9.2.3 Class template weak_ptr [util.smartptr.weak]
1The 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:
typedef T element_type;
// 20.9.2.3.1, constructors
constexpr weak_ptr() noexcept;
template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
weak_ptr(weak_ptr const& r) noexcept;
template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
// 20.9.2.3.2, destructor
~weak_ptr();
// 20.9.2.3.3, assignment
weak_ptr& operator=(weak_ptr const& r) noexcept;
template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
// 20.9.2.3.4, modifiers
void swap(weak_ptr& r) noexcept;
void reset() noexcept;
// 20.9.2.3.5, observers
long use_count() const noexcept;
bool expired() const noexcept;
shared_ptr<T> lock() const noexcept;
template<class U> bool owner_before(shared_ptr<U> const& b) const;
template<class U> bool owner_before(weak_ptr<U> const& b) const;
};
// 20.9.2.3.6, specialized algorithms
template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
}// namespace std
§ 20.9.2.3 556
c
ISO/IEC N????
2Specializations of weak_ptr shall be CopyConstructible and CopyAssignable, allowing their use in stan-
dard containers. The template parameter Tof weak_ptr may be an incomplete type.
20.9.2.3.1 weak_ptr constructors [util.smartptr.weak.const]
constexpr weak_ptr() noexcept;
1Effects: Constructs an empty weak_ptr object.
2Postconditions: 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;
3Requires: The second and third constructors shall not participate in the overload resolution unless Y*
is implicitly convertible to T*.
4Effects: If ris empty, constructs an empty weak_ptr object; otherwise, constructs a weak_ptr object
that shares ownership with rand stores a copy of the pointer stored in r.
5Postconditions: use_count() == r.use_count().
20.9.2.3.2 weak_ptr destructor [util.smartptr.weak.dest]
~weak_ptr();
1Effects: Destroys this weak_ptr object but has no effect on the object its stored pointer points to.
20.9.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;
1Effects: Equivalent to weak_ptr(r).swap(*this).
2Remarks: The implementation may meet the effects (and the implied guarantees) via different means,
without creating a temporary.
20.9.2.3.4 weak_ptr modifiers [util.smartptr.weak.mod]
void swap(weak_ptr& r) noexcept;
1Effects: Exchanges the contents of *this and r.
void reset() noexcept;
2Effects: Equivalent to weak_ptr().swap(*this).
20.9.2.3.5 weak_ptr observers [util.smartptr.weak.obs]
long use_count() const noexcept;
1Returns: 0if *this is empty; otherwise, the number of shared_ptr instances that share ownership
with *this.
2[Note: use_count() is not necessarily efficient. — end note ]
bool expired() const noexcept;
§ 20.9.2.3.5 557
c
ISO/IEC N????
3Returns: use_count() == 0.
4[Note: expired() may be faster than use_count().— end note ]
shared_ptr<T> lock() const noexcept;
5Returns: expired() ? shared_ptr<T>() : shared_ptr<T>(*this).
template<class U> bool owner_before(shared_ptr<U> const& b) const;
template<class U> bool owner_before(weak_ptr<U> const& b) const;
6Returns: An unspecified value such that
x.owner_before(y) defines a strict weak ordering as defined in 25.4;
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 own-
ership or are both empty.
20.9.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;
1Effects: Equivalent to a.swap(b).
20.9.2.3.7 Class template owner_less [util.smartptr.ownerless]
1The class template owner_less allows ownership-based mixed comparisons of shared and weak pointers.
namespace std {
template<class T> struct owner_less;
template<class T> struct owner_less<shared_ptr<T> > {
typedef bool result_type;
typedef shared_ptr<T> first_argument_type;
typedef shared_ptr<T> second_argument_type;
bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const;
bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;
bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;
};
template<class T> struct owner_less<weak_ptr<T> > {
typedef bool result_type;
typedef weak_ptr<T> first_argument_type;
typedef weak_ptr<T> second_argument_type;
bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const;
bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;
bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;
};
}
2operator()(x,y) shall return x.owner_before(y). [ Note: Note that
operator() defines a strict weak ordering as defined in 25.4;
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 ]
§ 20.9.2.3.7 558
c
ISO/IEC N????
20.9.2.4 Class template enable_shared_from_this [util.smartptr.enab]
1A class Tcan inherit from enable_shared_from_this<T> to inherit the shared_from_this member func-
tions that obtain a shared_ptr instance pointing to *this.
2[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 < q ) && !(q < 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(enable_shared_from_this const&) noexcept;
enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
~enable_shared_from_this();
public:
shared_ptr<T> shared_from_this();
shared_ptr<T const> shared_from_this() const;
};
}// namespace std
3The template parameter Tof 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;
4Effects: Constructs an enable_shared_from_this<T> object.
enable_shared_from_this<T>& operator=(const enable_shared_from_this<T>&) noexcept;
5Returns: *this.
~enable_shared_from_this();
6Effects: Destroys *this.
shared_ptr<T> shared_from_this();
shared_ptr<T const> shared_from_this() const;
7Requires: enable_shared_from_this<T> shall be an accessible base class of T.*this shall be a
subobject of an object tof type T. There shall be at least one shared_ptr instance pthat owns &t.
8Returns: Ashared_ptr<T> object rthat shares ownership with p.
9Postconditions: r.get() == this.
10 [Note: A possible implementation is shown below:
§ 20.9.2.4 559
c
ISO/IEC N????
template<class T> class enable_shared_from_this {
private:
weak_ptr<T> __weak_this;
protected:
constexpr enable_shared_from_this() : __weak_this() { }
enable_shared_from_this(enable_shared_from_this const &) { }
enable_shared_from_this& operator=(enable_shared_from_this const &) { return *this; }
~enable_shared_from_this() { }
public:
shared_ptr<T> shared_from_this() { return shared_ptr<T>(__weak_this); }
shared_ptr<T const> shared_from_this() const { return shared_ptr<T const>(__weak_this); }
};
11 The shared_ptr constructors that create unique pointers can detect the presence of an enable_shared_-
from_this base and assign the newly created shared_ptr to its __weak_this member. — end note ]
20.9.2.5 shared_ptr atomic access [util.smartptr.shared.atomic]
1Concurrent 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.
2The meaning of the arguments of type memory_order is explained in 29.3.
template<class T>
bool atomic_is_lock_free(const shared_ptr<T>* p);
3Requires: pshall not be null.
4Returns: true if atomic access to *p is lock-free, false otherwise.
5Throws: Nothing.
template<class T>
shared_ptr<T> atomic_load(const shared_ptr<T>* p);
6Requires: pshall not be null.
7Returns: atomic_load_explicit(p, memory_order_seq_cst).
8Throws: Nothing.
template<class T>
shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
9Requires: pshall not be null.
10 Requires: mo shall not be memory_order_release or memory_order_acq_rel.
11 Returns: *p.
12 Throws: Nothing.
template<class T>
void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
13 Requires: pshall not be null.
14 Effects: atomic_store_explicit(p, r, memory_order_seq_cst).
15 Throws: Nothing.
§ 20.9.2.5 560
c
ISO/IEC N????
template<class T>
void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
16 Requires: pshall not be null.
17 Requires: mo shall not be memory_order_acquire or memory_order_acq_rel.
18 Effects: p->swap(r).
19 Throws: Nothing.
template<class T>
shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
20 Requires: pshall not be null.
21 Returns: atomic_exchange_explicit(p, r, memory_order_seq_cst).
22 Throws: Nothing.
template<class T>
shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r,
memory_order mo);
23 Requires: pshall not be null.
24 Effects: p->swap(r).
25 Returns: The previous value of *p.
26 Throws: Nothing.
template<class T>
bool atomic_compare_exchange_weak(
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
27 Requires: pshall not be null and vshall not be null.
28 Returns: atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_-
order_seq_cst).
29 Throws: Nothing.
template<class T>
bool atomic_compare_exchange_strong(
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
30 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);
§ 20.9.2.5 561
c
ISO/IEC N????
31 Requires: pshall not be null and vshall not be null.
32 Requires: failure shall not be memory_order_release,memory_order_acq_rel, or stronger than
success.
33 Effects: If *p is equivalent to *v, assigns wto *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.
34 Returns: true if *p was equivalent to *v,false otherwise.
35 Throws: Nothing.
36 Remarks: two shared_ptr objects are equivalent if they store the same pointer value and share
ownership.
37 Remarks: the weak forms may fail spuriously. See 29.6.
20.9.2.6 Smart pointer hash support [util.smartptr.hash]
template <class T, class D> struct hash<unique_ptr<T, D> >;
1The template specialization shall meet the requirements of class template hash (20.10.12). For an
object pof type UP, where UP is unique_ptr<T, D>,hash<UP>()(p) shall evaluate to the same value
as hash<typename UP::pointer>()(p.get()).
2Requires: The specialization hash<typename UP::pointer> shall be well-formed and well-defined, and
shall meet the requirements of class template hash (20.10.12).
template <class T> struct hash<shared_ptr<T> >;
3The template specialization shall meet the requirements of class template hash (20.10.12). For an
object pof type shared_ptr<T>,hash<shared_ptr<T> >()(p) shall evaluate to the same value as
hash<T*>()(p.get()).
20.10 Function objects [function.objects]
1Afunction object type is an object type (3.9) that can be the type of the postfix-expression in a function call
(5.2.2,13.3.1.1).233 Afunction 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 25), 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.
2Header <functional> synopsis
namespace std {
// D.8.1, base (deprecated):
template <class Arg, class Result> struct unary_function;
template <class Arg1, class Arg2, class Result> struct binary_function;
// 20.10.3, 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;
233) 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.
§ 20.10 562
c
ISO/IEC N????
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;
// 20.10.4, 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>;
// 20.10.5, 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>;
// 20.10.6, 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>;
// 20.10.7, 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>;
// 20.10.8, negators:
template <class Predicate> class unary_negate;
template <class Predicate>
unary_negate<Predicate> not1(const Predicate&);
§ 20.10 563
c
ISO/IEC N????
template <class Predicate> class binary_negate;
template <class Predicate>
binary_negate<Predicate> not2(const Predicate&);
// 20.10.9, 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
extern unspecified _1;
extern unspecified _2;
.
.
.
extern unspecified _M;
}
// D.9, binders (deprecated):
template <class Fn> class binder1st;
template <class Fn, class T>
binder1st<Fn> bind1st(const Fn&, const T&);
template <class Fn> class binder2nd;
template <class Fn, class T>
binder2nd<Fn> bind2nd(const Fn&, const T&);
// D.8.2.1, adaptors (deprecated):
template <class Arg, class Result> class pointer_to_unary_function;
template <class Arg, class Result>
pointer_to_unary_function<Arg,Result> ptr_fun(Result (*)(Arg));
template <class Arg1, class Arg2, class Result>
class pointer_to_binary_function;
template <class Arg1, class Arg2, class Result>
pointer_to_binary_function<Arg1,Arg2,Result>
ptr_fun(Result (*)(Arg1,Arg2));
// D.8.2.2, adaptors (deprecated):
template<class S, class T> class mem_fun_t;
template<class S, class T, class A> class mem_fun1_t;
template<class S, class T>
mem_fun_t<S,T> mem_fun(S (T::*f)());
template<class S, class T, class A>
mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A));
template<class S, class T> class mem_fun_ref_t;
template<class S, class T, class A> class mem_fun1_ref_t;
template<class S, class T>
mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)());
template<class S, class T, class A>
mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A));
§ 20.10 564
c
ISO/IEC N????
template <class S, class T> class const_mem_fun_t;
template <class S, class T, class A> class const_mem_fun1_t;
template <class S, class T>
const_mem_fun_t<S,T> mem_fun(S (T::*f)() const);
template <class S, class T, class A>
const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const);
template <class S, class T> class const_mem_fun_ref_t;
template <class S, class T, class A> class const_mem_fun1_ref_t;
template <class S, class T>
const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const);
template <class S, class T, class A>
const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const);
// 20.10.10, member function adaptors:
template<class R, class T> unspecified mem_fn(R T::*);
// 20.10.11 polymorphic function wrappers:
class bad_function_call;
template<class> class function; // undefined
template<class R, class... ArgTypes> class function<R(ArgTypes...)>;
template<class R, class... ArgTypes>
void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
template<class R, class... ArgTypes>
bool operator==(const function<R(ArgTypes...)>&, nullptr_t);
template<class R, class... ArgTypes>
bool operator==(nullptr_t, const function<R(ArgTypes...)>&);
template<class R, class... ArgTypes>
bool operator!=(const function<R(ArgTypes...)>&, nullptr_t);
template<class R, class... ArgTypes>
bool operator!=(nullptr_t, const function<R(ArgTypes...)>&);
// 20.10.12, hash function primary template:
template <class T> struct hash;
// Hash function specializations
template <> struct hash<bool>;
template <> struct hash<char>;
template <> struct hash<signed char>;
template <> struct hash<unsigned char>;
template <> struct hash<char16_t>;
template <> struct hash<char32_t>;
template <> struct hash<wchar_t>;
template <> struct hash<short>;
template <> struct hash<unsigned short>;
template <> struct hash<int>;
template <> struct hash<unsigned int>;
template <> struct hash<long>;
template <> struct hash<long long>;
template <> struct hash<unsigned long>;
template <> struct hash<unsigned long long>;
template <> struct hash<float>;
§ 20.10 565
c
ISO/IEC N????
template <> struct hash<double>;
template <> struct hash<long double>;
template<class T> struct hash<T*>;
}
3[Example: If a C++ program wants to have a by-element addition of two vectors aand bcontaining double
and put the result into a, it can do:
transform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
— end example ]
4[Example: To negate every element of a:
transform(a.begin(), a.end(), a.begin(), negate<double>());
— end example ]
5[Note: To enable adaptors and other components to manipulate function objects that take one or two
arguments many of the function objects in this clause correspondingly provide typedefs 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. — end note ]
20.10.1 Definitions [func.def]
1The following definitions apply to this Clause:
2Acall signature is the name of a return type followed by a parenthesized comma-separated list of zero or
more argument types.
3Acallable type is a function object type (20.10) or a pointer to member.
4Acallable object is an object of a callable type.
5Acall wrapper type is a type that holds a callable object and supports a call operation that forwards to that
object.
6Acall wrapper is an object of a call wrapper type.
7Atarget object is the callable object held by a call wrapper.
20.10.2 Requirements [func.require]
1Define INVOKE (f, t1, t2, ..., tN) as follows:
(t1.*f)(t2, ..., tN) when fis a pointer to a member function of a class Tand t1 is an object of
type Tor a reference to an object of type Tor a reference to an object of a type derived from T;
((*t1).*f)(t2, ..., tN) when fis a pointer to a member function of a class Tand t1 is not one of
the types described in the previous item;
t1.*f when N == 1 and fis a pointer to member data of a class Tand t1 is an object of type Tor a
reference to an object of type Tor a reference to an object of a type derived from T;
(*t1).*f when N == 1 and fis a pointer to member data of a class Tand t1 is not one of the types
described in the previous item;
f(t1, t2, ..., tN) in all other cases.
2Define INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) implicitly converted to R.
3If a call wrapper (20.10.1) has a weak result type the type of its member type result_type is based on the
type Tof the wrapper’s target object (20.10.1):
if Tis a pointer to function type, result_type shall be a synonym for the return type of T;
if Tis a pointer to member function, result_type shall be a synonym for the return type of T;
§ 20.10.2 566
c
ISO/IEC N????
— if Tis a class type with a member type result_type, then result_type shall be a synonym for
T::result_type;
otherwise result_type shall not be defined.
4Every call wrapper (20.10.1) shall be MoveConstructible. A simple call wrapper is a call wrapper that is
CopyConstructible and CopyAssignable and whose copy constructor, move constructor, and assignment
operator do not throw exceptions. 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. [ 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 ]
20.10.3 Class template reference_wrapper [refwrap]
namespace std {
template <class T> class reference_wrapper {
public :
// types
typedef T type;
typedef see below result_type; // not always defined
typedef see below argument_type; // not always defined
typedef see below first_argument_type; // not always defined
typedef see below second_argument_type; // not always defined
// construct/copy/destroy
reference_wrapper(T&) noexcept;
reference_wrapper(T&&) = delete; // do not bind to temporary objects
reference_wrapper(const reference_wrapper<T>& x) noexcept;
// assignment
reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
// access
operator T& () const noexcept;
T& get() const noexcept;
// invocation
template <class... ArgTypes>
result_of_t<T&(ArgTypes&&...)>
operator() (ArgTypes&&...) const;
};
}
1reference_wrapper<T> is a CopyConstructible and CopyAssignable wrapper around a reference to an
object or function of type T.
2reference_wrapper<T> has a weak result type (20.10.2). If Tis a function type, result_type shall be a
synonym for the return type of T.
3The template instantiation reference_wrapper<T> shall define a nested type named argument_type as a
synonym for T1 only if the type Tis any of the following:
a function type or a pointer to function type taking one argument of type T1
§ 20.10.3 567
c
ISO/IEC N????
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 with a member type argument_type; the type T1 is T::argument_type.
4The 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 Tis 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 with member types first_argument_type and second_argument_type; the type T1 is
T::first_argument_type. and the type T2 is T::second_argument_type.
20.10.3.1 reference_wrapper construct/copy/destroy [refwrap.const]
reference_wrapper(T& t) noexcept;
1Effects: Constructs a reference_wrapper object that stores a reference to t.
reference_wrapper(const reference_wrapper<T>& x) noexcept;
2Effects: Constructs a reference_wrapper object that stores a reference to x.get().
20.10.3.2 reference_wrapper assignment [refwrap.assign]
reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
1Postconditions: *this stores a reference to x.get().
20.10.3.3 reference_wrapper access [refwrap.access]
operator T& () const noexcept;
1Returns: The stored reference.
T& get() const noexcept;
2Returns: The stored reference.
20.10.3.4 reference_wrapper invocation [refwrap.invoke]
template <class... ArgTypes>
result_of_t<T&(ArgTypes&&... )>
operator()(ArgTypes&&... args) const;
1Returns: INVOKE (get(), std::forward<ArgTypes>(args)...). (20.10.2)
2Remark: operator() is described for exposition only. Implementations are not required to provide an
actual reference_wrapper::operator(). Implementations are permitted to support reference_-
wrapper function invocation through multiple overloaded operators or through other means.
§ 20.10.3.4 568
c
ISO/IEC N????
20.10.3.5 reference_wrapper helper functions [refwrap.helpers]
template <class T> reference_wrapper<T> ref(T& t) noexcept;
1Returns: reference_wrapper<T>(t)
template <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;
2Returns: ref(t.get())
template <class T> reference_wrapper<const T> cref(const T& t) noexcept;
3Returns: reference_wrapper <const T>(t)
template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
4Returns: cref(t.get());
20.10.4 Arithmetic operations [arithmetic.operations]
1The library provides basic function object classes for all of the arithmetic operators in the language (5.6,
5.7).
template <class T = void> struct plus {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
2operator() returns x+y.
template <class T = void> struct minus {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
3operator() returns x-y.
template <class T = void> struct multiplies {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
4operator() returns x*y.
§ 20.10.4 569
c
ISO/IEC N????
template <class T = void> struct divides {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
5operator() returns x/y.
template <class T = void> struct modulus {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
6operator() returns x%y.
template <class T = void> struct negate {
T operator()(const T& x) const;
typedef T argument_type;
typedef T result_type;
};
7operator() returns -x.
template <> struct plus<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) + std::forward<U>(u));
typedef unspecified is_transparent;
};
8operator() returns std::forward<T>(t) + std::forward<U>(u).
template <> struct minus<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) - std::forward<U>(u));
typedef unspecified is_transparent;
};
9operator() returns std::forward<T>(t) - std::forward<U>(u).
template <> struct multiplies<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) * std::forward<U>(u));
typedef unspecified is_transparent;
};
10 operator() returns std::forward<T>(t) * std::forward<U>(u).
§ 20.10.4 570
c
ISO/IEC N????
template <> struct divides<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) / std::forward<U>(u));
typedef unspecified is_transparent;
};
11 operator() returns std::forward<T>(t) / std::forward<U>(u).
template <> struct modulus<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) % std::forward<U>(u));
typedef unspecified is_transparent;
};
12 operator() returns std::forward<T>(t) % std::forward<U>(u).
template <> struct negate<void> {
template <class T> auto operator()(T&& t) const
-> decltype(-std::forward<T>(t));
typedef unspecified is_transparent;
};
13 operator() returns -std::forward<T>(t).
20.10.5 Comparisons [comparisons]
1The library provides basic function object classes for all of the comparison operators in the language (5.9,
5.10).
template <class T = void> struct equal_to {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
2operator() returns x == y.
template <class T = void> struct not_equal_to {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
3operator() returns x != y.
template <class T = void> struct greater {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
§ 20.10.5 571
c
ISO/IEC N????
4operator() returns x>y.
template <class T = void> struct less {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
5operator() returns x<y.
template <class T = void> struct greater_equal {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
6operator() returns x >= y.
template <class T = void> struct less_equal {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
7operator() returns x <= y.
template <> struct equal_to<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) == std::forward<U>(u));
typedef unspecified is_transparent;
};
8operator() returns std::forward<T>(t) == std::forward<U>(u).
template <> struct not_equal_to<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) != std::forward<U>(u));
typedef unspecified is_transparent;
};
9operator() returns std::forward<T>(t) != std::forward<U>(u).
template <> struct greater<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) > std::forward<U>(u));
typedef unspecified is_transparent;
};
§ 20.10.5 572
c
ISO/IEC N????
10 operator() returns std::forward<T>(t) > std::forward<U>(u).
template <> struct less<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) < std::forward<U>(u));
typedef unspecified is_transparent;
};
11 operator() returns std::forward<T>(t) < std::forward<U>(u).
template <> struct greater_equal<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) >= std::forward<U>(u));
typedef unspecified is_transparent;
};
12 operator() returns std::forward<T>(t) >= std::forward<U>(u).
template <> struct less_equal<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) <= std::forward<U>(u));
typedef unspecified is_transparent;
};
13 operator() returns std::forward<T>(t) <= std::forward<U>(u).
14 For templates greater,less,greater_equal, and less_equal, the specializations for any pointer type
yield a total order, even if the built-in operators <,>,<=,>= do not.
20.10.6 Logical operations [logical.operations]
1The library provides basic function object classes for all of the logical operators in the language (5.14,5.15,
5.3.1).
template <class T = void> struct logical_and {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
2operator() returns x && y.
template <class T = void> struct logical_or {
bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
3operator() returns x || y.
§ 20.10.6 573
c
ISO/IEC N????
template <class T = void> struct logical_not {
bool operator()(const T& x) const;
typedef T argument_type;
typedef bool result_type;
};
4operator() returns !x.
template <> struct logical_and<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) && std::forward<U>(u));
typedef unspecified is_transparent;
};
5operator() returns std::forward<T>(t) && std::forward<U>(u).
template <> struct logical_or<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) || std::forward<U>(u));
typedef unspecified is_transparent;
};
6operator() returns std::forward<T>(t) || std::forward<U>(u).
template <> struct logical_not<void> {
template <class T> auto operator()(T&& t) const
-> decltype(!std::forward<T>(t));
typedef unspecified is_transparent;
};
7operator() returns !std::forward<T>(t).
20.10.7 Bitwise operations [bitwise.operations]
1The library provides basic function object classes for all of the bitwise operators in the language (5.11,5.13,
5.12,5.3.1).
template <class T = void> struct bit_and {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
2operator() returns x&y.
template <class T = void> struct bit_or {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
§ 20.10.7 574
c
ISO/IEC N????
3operator() returns x|y.
template <class T = void> struct bit_xor {
T operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef T result_type;
};
4operator() returns xˆy.
template <class T = void> struct bit_not {
T operator()(const T& x) const;
typedef T argument_type;
typedef T result_type;
};
5operator() returns ˜x.
template <> struct bit_and<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) & std::forward<U>(u));
typedef unspecified is_transparent;
};
6operator() returns std::forward<T>(t) & std::forward<U>(u).
template <> struct bit_or<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) | std::forward<U>(u));
typedef unspecified is_transparent;
};
7operator() returns std::forward<T>(t) | std::forward<U>(u).
template <> struct bit_xor<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) ^ std::forward<U>(u));
typedef unspecified is_transparent;
};
8operator() returns std::forward<T>(t) ˆ std::forward<U>(u).
template <> struct bit_not<void> {
template <class T> auto operator()(T&& t) const
-> decltype(~std::forward<T>(t));
typedef unspecified is_transparent;
};
9operator() returns ˜std::forward<T>(t).
§ 20.10.7 575
c
ISO/IEC N????
20.10.8 Negators [negators]
1Negators not1 and not2 take a unary and a binary predicate, respectively, and return their comple-
ments (5.3.1).
template <class Predicate>
class unary_negate {
public:
explicit unary_negate(const Predicate& pred);
bool operator()(const typename Predicate::argument_type& x) const;
typedef typename Predicate::argument_type argument_type;
typedef bool result_type;
};
2operator() returns !pred(x).
template <class Predicate>
unary_negate<Predicate> not1(const Predicate& pred);
3Returns: unary_negate<Predicate>(pred).
template <class Predicate>
class binary_negate {
public:
explicit binary_negate(const Predicate& pred);
bool operator()(const typename Predicate::first_argument_type& x,
const typename Predicate::second_argument_type& y) const;
typedef typename Predicate::first_argument_type first_argument_type;
typedef typename Predicate::second_argument_type second_argument_type;
typedef bool result_type;
};
4operator() returns !pred(x,y).
template <class Predicate>
binary_negate<Predicate> not2(const Predicate& pred);
5Returns: binary_negate<Predicate>(pred).
20.10.9 Function template bind [bind]
1The function template bind returns an object that binds a callable object passed as an argument to additional
arguments.
20.10.9.1 Function object binders [func.bind]
1This subclause describes a uniform mechanism for binding arguments of callable objects.
20.10.9.1.1 Class template is_bind_expression [func.bind.isbind]
namespace std {
template<class T> struct is_bind_expression; // see below
}
1is_bind_expression can be used to detect function objects generated by bind.bind uses is_bind_-
expression to detect subexpressions.
2Instantiations of the is_bind_expression template shall meet the UnaryTypeTrait requirements (20.11.1).
The implementation shall provide a definition that has a BaseCharacteristic of true_type if Tis a type
§ 20.10.9.1.1 576
c
ISO/IEC N????
returned from bind, otherwise it shall have a BaseCharacteristic of false_type. A program may specialize
this template for a user-defined type Tto have a BaseCharacteristics of true_type to indicate that Tshould
be treated as a subexpression in a bind call.
20.10.9.1.2 Class template is_placeholder [func.bind.isplace]
namespace std {
template<class T> struct is_placeholder; // see below
}
1is_placeholder can be used to detect the standard placeholders _1,_2, and so on. bind uses is_-
placeholder to detect placeholders.
2Instantiations of the is_placeholder template shall meet the UnaryTypeTrait requirements (20.11.1). The
implementation shall provide a definition that has the BaseCharacteristic of integral_constant<int, J>
if Tis the type of std::placeholders::_J, otherwise it shall have a BaseCharacteristic of integral_-
constant<int, 0>. A program may specialize this template for a user-defined type Tto have a BaseChar-
acteristic of integral_constant<int, N>with N> 0 to indicate that Tshould be treated as a placeholder
type.
20.10.9.1.3 Function template bind [func.bind.bind]
1In the text that follows, the following names have the following meanings:
FD is the type decay<F>::type,
fd is an lvalue of type FD constructed from std::forward<F>(f),
Ti is the ith type in the template parameter back BoundArgs,
TiD is the type decay<Ti>::type,
ti is the ith argument in the function parameter pack bound_args,
tid is an lvalue of type TiD constructed from std::forward<Ti>(ti),
Uj is the jth deduced type of the UnBoundArgs&&... parameter of the forwarding call wrapper, and
uj is the jth argument associated with Uj.
template<class F, class... BoundArgs>
unspecified bind(F&& f, BoundArgs&&... bound_args);
2Requires: is_constructible<FD, F>::value shall be true. For each Ti in BoundArgs,is_cons-
tructible<TiD, Ti>::value shall be true.INVOKE (fd, w1, w2, ..., wN) (20.10.2) shall be a
valid expression for some values w1, w2, ..., wN, where N == sizeof...(bound_args).
3Returns: A forwarding call wrapper gwith a weak result type (20.10.2). The effect of g(u1, u2, ...,
uM) shall be INVOKE (fd, std::forward<V1>(v1), std::forward<V2>(v2), ..., std::forward<VN>(vN),
result_of<FD cv & (V1, V2, ..., VN)>::type), where cv represents the cv-qualifiers of gand the
values and types of the bound arguments v1, v2, ..., vN 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 TiD throws an exception.
4Throws: Nothing unless the construction of fd or of one of the values tid throws an exception.
5Remarks: The return type shall satisfy the requirements of MoveConstructible. If all of FD and TiD
satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements
of CopyConstructible. [ Note: This implies that all of FD and TiD are MoveConstructible.— end
note ]
§ 20.10.9.1.3 577
c
ISO/IEC N????
template<class R, class F, class... BoundArgs>
unspecified bind(F&& f, BoundArgs&&... bound_args);
6Requires: is_constructible<FD, F>::value shall be true. For each Ti in BoundArgs,is_con-
structible<TiD, Ti>::value shall be true.INVOKE (fd, w1, w2, ..., wN) shall be a valid ex-
pression for some values w1, w2, ..., wN, where N == sizeof...(bound_args).
7Returns: A forwarding call wrapper gwith a nested type result_type defined as a synonym for R. The
effect of g(u1, u2, ..., uM) shall be INVOKE (fd, std::forward<V1>(v1), std::forward<V2>(v2),
..., std::forward<VN>(vN), R), where the values and types of the bound arguments v1, v2, ...,
vN 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 TiD throws an exception.
8Throws: Nothing unless the construction of fd or of one of the values tid throws an exception.
9Remarks: The return type shall satisfy the requirements of MoveConstructible. If all of FD and TiD
satisfy the requirements of CopyConstructible, then the return type shall satisfy the requirements
of CopyConstructible. [ Note: This implies that all of FD and TiD are MoveConstructible.— end
note ]
10 The values of the bound arguments v1, v2, ..., vN and their corresponding types V1, V2, ..., VN
depend on the types TiD derived from the call to bind and the cv-qualifiers cv of the call wrapper gas
follows:
if TiD is reference_wrapper<T>, the argument is tid.get() and its type Vi is T&;
if the value of is_bind_expression<TiD>::value is true, the argument is tid(std::forward<Uj>(
uj)...) and its type Vi is result_of<TiD cv & (Uj&&...)>::type&&;
if the value jof is_placeholder<TiD>::value is not zero, the argument is std::forward<Uj>(uj)
and its type Vi is Uj&&;
otherwise, the value is tid and its type Vi is TiD cv &.
20.10.9.1.4 Placeholders [func.bind.place]
namespace std {
namespace placeholders {
// M is the implementation-defined number of placeholders
extern unspecified _1;
extern unspecified _2;
.
.
.
extern unspecified _M;
}
}
1All placeholder types shall be DefaultConstructible and CopyConstructible, and their default con-
structors 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.
20.10.10 Function template mem_fn [func.memfn]
template<class R, class T> unspecified mem_fn(R T::* pm);
§ 20.10.10 578
c
ISO/IEC N????
1Returns: A simple call wrapper (20.10.1)fn such that the expression fn(t, a2, ..., aN) is equiv-
alent to INVOKE (pm, t, a2, ..., aN) (20.10.2). fn 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.
2The simple call wrapper 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.
3The simple call wrapper 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.
4Throws: Nothing.
20.10.11 Polymorphic function wrappers [func.wrap]
1This subclause describes a polymorphic wrapper class that encapsulates arbitrary callable objects.
20.10.11.1 Class bad_function_call [func.wrap.badcall]
1An exception of type bad_function_call is thrown by function::operator() (20.10.11.2.4) when the
function wrapper object has no target.
namespace std {
class bad_function_call : public std::exception {
public:
// 20.10.11.1.1, constructor:
bad_function_call() noexcept;
};
}// namespace std
20.10.11.1.1 bad_function_call constructor [func.wrap.badcall.const]
bad_function_call() noexcept;
1Effects: constructs a bad_function_call object.
20.10.11.2 Class template function [func.wrap.func]
namespace std {
template<class> class function; // undefined
template<class R, class... ArgTypes>
class function<R(ArgTypes...)> {
public:
typedef R result_type;
typedef T1 argument_type; // only if sizeof...(ArgTypes) == 1 and
// the type in ArgTypes is T1
typedef T1 first_argument_type; // only if sizeof...(ArgTypes) == 2 and
// ArgTypes contains T1 and T2
typedef T2 second_argument_type; // only if sizeof...(ArgTypes) == 2 and
// ArgTypes contains T1 and T2
// 20.10.11.2.1, construct/copy/destroy:
function() noexcept;
function(nullptr_t) noexcept;
function(const function&);
function(function&&);
§ 20.10.11.2 579
c
ISO/IEC N????
template<class F> function(F);
template<class A> function(allocator_arg_t, const A&) noexcept;
template<class A> function(allocator_arg_t, const A&,
nullptr_t) noexcept;
template<class A> function(allocator_arg_t, const A&,
const function&);
template<class A> function(allocator_arg_t, const A&,
function&&);
template<class F, class A> function(allocator_arg_t, const A&, F);
function& operator=(const function&);
function& operator=(function&&);
function& operator=(nullptr_t);
template<class F> function& operator=(F&&);
template<class F> function& operator=(reference_wrapper<F>) noexcept;
~function();
// 20.10.11.2.2, function modifiers:
void swap(function&) noexcept;
template<class F, class A> void assign(F&&, const A&);
// 20.10.11.2.3, function capacity:
explicit operator bool() const noexcept;
// 20.10.11.2.4, function invocation:
R operator()(ArgTypes...) const;
// 20.10.11.2.5, function target access:
const std::type_info& target_type() const noexcept;
template<class T> T* target() noexcept;
template<class T> const T* target() const noexcept;
};
// 20.10.11.2.6, 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;
// 20.10.11.2.7, specialized algorithms:
template <class R, class... ArgTypes>
void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
template<class R, class... ArgTypes, class Alloc>
struct uses_allocator<function<R(ArgTypes...)>, Alloc>
: true_type { };
§ 20.10.11.2 580
c
ISO/IEC N????
}
1The function class template provides polymorphic wrappers that generalize the notion of a function pointer.
Wrappers can store, copy, and call arbitrary callable objects (20.10.1), given a call signature (20.10.1),
allowing functions to be first-class objects.
2A callable object fof type Fis Callable for argument types ArgTypes and return type Rif the expres-
sion INVOKE (f, declval<ArgTypes>()..., R), considered as an unevaluated operand (Clause 5), is well
formed (20.10.2).
3The function class template is a call wrapper (20.10.1) whose call signature (20.10.1) is R(ArgTypes...).
20.10.11.2.1 function construct/copy/destroy [func.wrap.func.con]
1When any function constructor that takes a first argument of type allocator_arg_t is invoked, the second
argument shall have a type that conforms to the requirements for Allocator (Table 17.6.3.5). A copy of the
allocator argument is used to allocate memory, if necessary, for the internal data structures of the constructed
function object.
function() noexcept;
template <class A> function(allocator_arg_t, const A& a) noexcept;
2Postconditions: !*this.
function(nullptr_t) noexcept;
template <class A> function(allocator_arg_t, const A& a, nullptr_t) noexcept;
3Postconditions: !*this.
function(const function& f);
template <class A> function(allocator_arg_t, const A& a, const function& f);
4Postconditions: !*this if !f; otherwise, *this targets a copy of f.target().
5Throws: shall not throw exceptions if f’s target is a callable object passed via 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);
template <class A> function(allocator_arg_t, const A& a, function&& f);
6Effects: If !f,*this has no target; otherwise, move-constructs the target of finto the target of *this,
leaving fin a valid state with an unspecified value.
template<class F> function(F f);
template <class F, class A> function(allocator_arg_t, const A& a, F f);
7Requires: Fshall be CopyConstructible.fshall be Callable (20.10.11.2) for argument types ArgTypes
and return type R. The copy constructor and destructor of Ashall not throw exceptions.
8Postconditions: !*this if any of the following hold:
fis a null function pointer value.
fis a null member pointer value.
Fis an instance of the function class template, and !f
§ 20.10.11.2.1 581
c
ISO/IEC N????
9Otherwise, *this targets a copy of finitialized with std::move(f). [ 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 ]
10 Throws: shall not throw exceptions when fis 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.
function& operator=(const function& f);
11 Effects: function(f).swap(*this);
12 Returns: *this
function& operator=(function&& f);
13 Effects: Replaces the target of *this with the target of f.
14 Returns: *this
function& operator=(nullptr_t);
15 Effects: If *this != nullptr, destroys the target of this.
16 Postconditions: !(*this).
17 Returns: *this
template<class F> function& operator=(F&& f);
18 Effects: function(std::forward<F>(f)).swap(*this);
19 Returns: *this
template<class F> function& operator=(reference_wrapper<F> f) noexcept;
20 Effects: function(f).swap(*this);
21 Returns: *this
~function();
22 Effects: If *this != nullptr, destroys the target of this.
20.10.11.2.2 function modifiers [func.wrap.func.mod]
void swap(function& other) noexcept;
1Effects: interchanges the targets of *this and other.
template<class F, class A>
void assign(F&& f, const A& a);
2Effects: function(allocator_arg, a, std::forward<F>(f)).swap(*this)
§ 20.10.11.2.2 582
c
ISO/IEC N????
20.10.11.2.3 function capacity [func.wrap.func.cap]
explicit operator bool() const noexcept;
1Returns: true if *this has a target, otherwise false.
20.10.11.2.4 function invocation [func.wrap.func.inv]
R operator()(ArgTypes... args) const
1Effects: INVOKE (f, std::forward<ArgTypes>(args)..., R) (20.10.2), where fis the target ob-
ject (20.10.1) of *this.
2Returns: Nothing if Ris void, otherwise the return value of INVOKE (f, std::forward<ArgTypes>(
args)..., R).
3Throws: bad_function_call if !*this; otherwise, any exception thrown by the wrapped callable
object.
20.10.11.2.5 function target access [func.wrap.func.targ]
const std::type_info& target_type() const noexcept;
1Returns: 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;
2Requires: Tshall be a type that is Callable (20.10.11.2) for parameter types ArgTypes and return type
R.
3Returns: If target_type() == typeid(T) a pointer to the stored function target; otherwise a null
pointer.
20.10.11.2.6 null pointer comparison operators [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;
1Returns: !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;
2Returns: (bool) f.
20.10.11.2.7 specialized algorithms [func.wrap.func.alg]
template<class R, class... ArgTypes>
void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2);
1Effects: f1.swap(f2);
§ 20.10.11.2.7 583
c
ISO/IEC N????
20.10.12 Class template hash [unord.hash]
1The unordered associative containers defined in 23.5 use specializations of the class template hash as the
default hash function. For all object types Key for which there exists a specialization hash<Key>, and for all
enumeration types (7.2)Key, the instantiation hash<Key> shall:
satisfy the Hash requirements (17.6.3.4), with Key as the function call argument type, the Default-
Constructible requirements (Table 19), the CopyAssignable requirements (Table 23),
be swappable (17.6.3.2) for lvalues,
provide two nested types result_type and argument_type which shall be synonyms for size_t and
Key, respectively,
satisfy the requirement that if k1 == k2 is true, h(k1) == h(k2) is also true, where his an object of
type hash<Key> and k1 and k2 are objects of type Key;
satisfy the requirement that the expression h(k), where his an object of type hash<Key> and kis 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.
template <> struct hash<bool>;
template <> struct hash<char>;
template <> struct hash<signed char>;
template <> struct hash<unsigned char>;
template <> struct hash<char16_t>;
template <> struct hash<char32_t>;
template <> struct hash<wchar_t>;
template <> struct hash<short>;
template <> struct hash<unsigned short>;
template <> struct hash<int>;
template <> struct hash<unsigned int>;
template <> struct hash<long>;
template <> struct hash<unsigned long>;
template <> struct hash<long long>;
template <> struct hash<unsigned long long>;
template <> struct hash<float>;
template <> struct hash<double>;
template <> struct hash<long double>;
template <class T> struct hash<T*>;
2The template specializations shall meet the requirements of class template hash (20.10.12).
20.11 Metaprogramming and type traits [meta]
1This 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.
20.11.1 Requirements [meta.rqmts]
1AUnaryTypeTrait 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
§ 20.11.1 584
c
ISO/IEC N????
DefaultConstructible,CopyConstructible, and publicly and unambiguously derived, directly or indi-
rectly, from its BaseCharacteristic, which is a specialization of the template integral_constant (20.11.3),
with the arguments to the template integral_constant determined by the requirements for the particular
property being described. The member names of the BaseCharacteristic shall not be hidden and shall be
unambiguously available in the UnaryTypeTrait.
2ABinaryTypeTrait 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 de-
scribed. It shall be DefaultConstructible,CopyConstructible, and publicly and unambiguously derived,
directly or indirectly, from its BaseCharacteristic, which is a specialization of the template integral_-
constant (20.11.3), with the arguments to the template integral_constant determined by the require-
ments for the particular relationship being described. The member names of the BaseCharacteristic shall
not be hidden and shall be unambiguously available in the BinaryTypeTrait.
3ATransformationTrait 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.
20.11.2 Header <type_traits> synopsis [meta.type.synop]
namespace std {
// 20.11.3, helper class:
template <class T, T v> struct integral_constant;
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
// 20.11.4.1, primary type categories:
template <class T> struct is_void;
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;
// 20.11.4.2, 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;
// 20.11.4.3, 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;
§ 20.11.2 585
c
ISO/IEC N????
template <class T> struct is_literal_type;
template <class T> struct is_empty;
template <class T> struct is_polymorphic;
template <class T> struct is_abstract;
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> 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> struct is_nothrow_destructible;
template <class T> struct has_virtual_destructor;
// 20.11.5, type property queries:
template <class T> struct alignment_of;
template <class T> struct rank;
template <class T, unsigned I = 0> struct extent;
// 20.11.6, 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;
// 20.11.7.1, const-volatile modifications:
template <class T> struct remove_const;
template <class T> struct remove_volatile;
template <class T> struct remove_cv;
§ 20.11.2 586
c
ISO/IEC N????
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;
// 20.11.7.2, 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;
// 20.11.7.3, 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;
// 20.11.7.4, 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;
// 20.11.7.5, 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;
§ 20.11.2 587
c
ISO/IEC N????
// 20.11.7.6, other transformations:
template <std::size_t Len,
std::size_t Align = default-alignment> // see 20.11.7.6
struct aligned_storage;
template <std::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> class result_of; // not defined
template <class F, class... ArgTypes> class result_of<F(ArgTypes...)>;
template <std::size_t Len,
std::size_t Align = default-alignment > // see 20.11.7.6
using aligned_storage_t = typename aligned_storage<Len,Align>::type;
template <std::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 T>
using result_of_t = typename result_of<T>::type;
}// namespace std
1The behavior of a program that adds specializations for any of the class templates defined in this subclause
is undefined unless otherwise specified.
20.11.3 Helper classes [meta.help]
namespace std {
template <class T, T v>
struct integral_constant {
static constexpr T value = v;
typedef T value_type;
typedef integral_constant<T,v> type;
constexpr operator value_type() const { return value; }
constexpr value_type operator()() const { return value; }
};
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
}
1The class template integral_constant and its associated typedefs true_type and false_type are used as
base classes to define the interface for various type traits.
20.11.4 Unary type traits [meta.unary]
1This sub-clause contains templates that may be used to query the properties of a type at compile time.
§ 20.11.4 588
c
ISO/IEC N????
2Each of these templates shall be a UnaryTypeTrait (20.11.1) with a BaseCharacteristic of true_type if the
corresponding condition is true, otherwise false_type.
20.11.4.1 Primary type categories [meta.unary.cat]
1The primary type categories correspond to the descriptions given in section 3.9 of the C++ standard.
2For any given type T, the result of applying one of these templates to Tand to cv-qualified Tshall yield the
same result.
3[Note: For any given type T, exactly one of the primary type categories has a value member that evaluates
to true.— end note ]
Table 47 — Primary type category predicates
Template Condition Comments
template <class T>
struct is_void;
Tis void
template <class T>
struct is_integral;
Tis an integral type (3.9.1)
template <class T>
struct is_floating_point;
Tis a floating point
type (3.9.1)
template <class T>
struct is_array;
Tis an array type (3.9.2) of
known or unknown extent
Class template
array (23.3.2) is not an
array type.
template <class T>
struct is_pointer;
Tis a pointer type (3.9.2) Includes pointers to
functions but not pointers
to non-static members.
template <class T>
struct is_lvalue_reference;
Tis an lvalue reference
type (8.3.2)
template <class T>
struct is_rvalue_reference;
Tis an rvalue reference
type (8.3.2)
template <class T>
struct is_member_object_pointer;
Tis a pointer to non-static
data member
template <class T>
struct
is_member_function_pointer;
Tis a pointer to non-static
member function
template <class T>
struct is_enum;
Tis an enumeration
type (3.9.2)
template <class T>
struct is_union;
Tis a union type (3.9.2)
template <class T>
struct is_class;
Tis a class type but not a
union type (3.9.2)
template <class T>
struct is_function;
Tis a function type (3.9.2)
20.11.4.2 Composite type traits [meta.unary.comp]
1These templates provide convenient compositions of the primary type categories, corresponding to the de-
scriptions given in section 3.9.
2For any given type T, the result of applying one of these templates to T, and to cv-qualified Tshall yield the
same result.
§ 20.11.4.2 589
c
ISO/IEC N????
Table 48 — Composite type category predicates
Template Condition Comments
template <class T>
struct is_reference;
Tis an lvalue reference or
an rvalue reference
template <class T>
struct is_arithmetic;
Tis an arithmetic
type (3.9.1)
template <class T>
struct is_fundamental;
Tis a fundamental
type (3.9.1)
template <class T>
struct is_object;
Tis an object type (3.9)
template <class T>
struct is_scalar;
Tis a scalar type (3.9)
template <class T>
struct is_compound;
Tis a compound
type (3.9.2)
template <class T>
struct is_member_pointer;
Tis a pointer to non-static
data member or non-static
member function
20.11.4.3 Type properties [meta.unary.prop]
1These templates provide access to some of the more important properties of types.
2It is unspecified whether the library defines any full or partial specializations of any of these templates.
3For all of the class templates Xdeclared in this Clause, 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 Xrequire that the argument must be a complete type.
Table 49 — Type property predicates
Template Condition Preconditions
template <class T>
struct is_const;
Tis const-qualified (3.9.3)
template <class T>
struct is_volatile;
Tis
volatile-qualified (3.9.3)
template <class T>
struct is_trivial;
Tis a trivial type (3.9)remove_all_-
extents<T>::type shall
be a complete type or
(possibly cv-qualified)
void.
template <class T>
struct is_trivially_copyable;
Tis a trivially copyable
type (3.9)
remove_all_-
extents<T>::type shall
be a complete type or
(possibly cv-qualified)
void.
template <class T>
struct is_standard_layout;
Tis a standard-layout
type (3.9)
remove_all_-
extents<T>::type shall
be a complete type or
(possibly cv-qualified)
void.
§ 20.11.4.3 590
c
ISO/IEC N????
Table 49 — Type property predicates (continued)
Template Condition Preconditions
template <class T>
struct is_pod;
Tis a POD type (3.9)remove_all_-
extents<T>::type shall
be a complete type or
(possibly cv-qualified)
void.
template <class T>
struct is_literal_type;
Tis a literal type (3.9)remove_all_-
extents<T>::type shall
be a complete type or
(possibly cv-qualified)
void.
template <class T>
struct is_empty;
Tis 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 Bfor which
is_empty<B>::value is
false.
If Tis a non-union class
type, Tshall be a complete
type.
template <class T>
struct is_polymorphic;
Tis a polymorphic
class (10.3)
If Tis a non-union class
type, Tshall be a complete
type.
template <class T>
struct is_abstract;
Tis an abstract
class (10.4)
If Tis a non-union class
type, Tshall be a complete
type.
template <class T>
struct is_signed;
If is_-
arithmetic<T>::value is
true, the same result as
integral_-
constant<bool, T(-1) <
T(0)>::value; otherwise,
false
template <class T>
struct is_unsigned;
If is_-
arithmetic<T>::value is
true, the same result as
integral_-
constant<bool, T(0) <
T(-1)>::value;
otherwise, false
template <class T, class... Args>
struct is_constructible;
see below Tand all types in the
parameter pack Args shall
be complete types,
(possibly cv-qualified)
void, or arrays of
unknown bound.
§ 20.11.4.3 591
c
ISO/IEC N????
Table 49 — Type property predicates (continued)
Template Condition Preconditions
template <class T>
struct is_default_constructible;
is_-
constructible<T>::value
is true.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
template <class T>
struct is_copy_constructible;
For a referenceable type T,
the same result as
is_constructible<T,
const T&>::value,
otherwise false.
Tshall be a complete type,
(possibly cv-qualified)
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<T,
T&&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
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 5). 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 ]
Tand Ushall be complete
types, (possibly
cv-qualified) void, or
arrays of unknown bound.
template <class T>
struct is_copy_assignable;
For a referenceable type T,
the same result as
is_assignable<T&,
const T&>::value,
otherwise false.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
§ 20.11.4.3 592
c
ISO/IEC N????
Table 49 — Type property predicates (continued)
Template Condition Preconditions
template <class T>
struct is_move_assignable;
For a referenceable type T,
the same result as
is_assignable<T&,
T&&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
template <class T>
struct is_destructible;
For reference types, is_-
destructible<T>::value
is true.
For incomplete types and
function types, is_-
destructible<T>::value
is false.
For object types and given
Uequal to remove_all_-
extents<T>::type, if the
expression
std::declval<U&>().˜U()
is well-formed when
treated as an unevaluated
operand (Clause 5),
then is_-
destructible<T>::value
is true, otherwise it is
false.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
template <class T, class... Args>
struct
is_trivially_constructible;
is_constructible<T,
Args...>::value is true
and the variable definition
for is_constructible, as
defined below, is known to
call no operation that is
not trivial ( 3.9,12).
Tand all types in the
parameter pack Args shall
be complete types,
(possibly cv-qualified)
void, or arrays of
unknown bound.
template <class T>
struct
is_trivially_default_constructible;
is_trivially_-
constructible<T>::value
is true.
Tshall be a complete type,
(possibly cv-qualified)
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<T, const
T&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
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<T,
T&&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
§ 20.11.4.3 593
c
ISO/IEC N????
Table 49 — Type property predicates (continued)
Template Condition Preconditions
template <class T, class U>
struct is_trivially_assignable;
is_assignable<T,
U>::value is true and the
assignment, as defined by
is_assignable, is known
to call no operation that is
not trivial (3.9,12).
Tand Ushall be complete
types, (possibly
cv-qualified) 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<T&, const
T&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
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<T&,
T&&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
template <class T>
struct is_trivially_destructible;
is_-
destructible<T>::value
is true and the indicated
destructor is known to be
trivial.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
template <class T, class... Args>
struct is_nothrow_constructible;
is_constructible<T,
Args...>::value is true
and the variable definition
for is_constructible, as
defined below, is known
not to throw any
exceptions (5.3.7).
Tand all types in the
parameter pack Args shall
be complete types,
(possibly cv-qualified)
void, or arrays of
unknown bound.
template <class T>
struct
is_nothrow_default_constructible;
is_nothrow_-
constructible<T>::value
is true.
Tshall be a complete type,
(possibly cv-qualified)
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<T, const
T&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
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<T,
T&&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
§ 20.11.4.3 594
c
ISO/IEC N????
Table 49 — Type property predicates (continued)
Template Condition Preconditions
template <class T, class U>
struct is_nothrow_assignable;
is_assignable<T,
U>::value is true and
the assignment is known
not to throw any
exceptions (5.3.7).
Tand Ushall be complete
types, (possibly
cv-qualified) 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<T&,
const T&>::value,
otherwise false.
Tshall be a complete type,
(possibly cv-qualified)
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<T&,
T&&>::value, otherwise
false.
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
template <class T>
struct is_nothrow_destructible;
is_-
destructible<T>::value
is true and the indicated
destructor is known not to
throw any
exceptions (5.3.7).
Tshall be a complete type,
(possibly cv-qualified)
void, or an array of
unknown bound.
template <class T>
struct has_virtual_destructor;
Thas a virtual
destructor (12.4)
If Tis a non-union class
type, Tshall be a complete
type.
4[Example:
is_const<const volatile int>::value // true
is_const<const int*>::value // false
is_const<const int&>::value // false
is_const<int[3]>::value // false
is_const<const int[3]>::value // true
— end example ]
5[Example:
remove_const<const volatile int>::type // volatile int
remove_const<const int* const>::type // const int*
remove_const<const int&>::type // const int&
remove_const<const int[3]>::type // int[3]
— end example ]
6Given the following function prototype:
template <class T>
add_rvalue_reference_t<T> create();
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(create<Args>()...);
§ 20.11.4.3 595
c
ISO/IEC N????
[Note: These tokens are never interpreted as a function declaration. — end note ] Access checking is
performed as if in a context unrelated to Tand 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 ]
20.11.5 Type property queries [meta.unary.prop.query]
1This sub-clause contains templates that may be used to query properties of types at compile time.
Table 50 — Type property queries
Template Value
template <class T>
struct alignment_of;
alignof(T).
Requires:alignof(T) shall be a valid expression (5.3.6)
template <class T>
struct rank;
If Tnames an array type, an integer value representing the number of
dimensions of T; otherwise, 0.
template <class T,
unsigned I = 0>
struct extent;
If Tis not an array type, or if it has rank less than or equal to I, or if I
is 0 and Thas type “array of unknown bound of U”, then 0; otherwise,
the bound (8.3.4) of the I’th dimension of T, where indexing of Iis
zero-based
2[Example:
// the following assertions hold:
assert(rank<int>::value == 0);
assert(rank<int[2]>::value == 1);
assert(rank<int[][4]>::value == 2);
— end example ]
3[Example:
// the following assertions hold:
assert(extent<int>::value == 0);
assert(extent<int[2]>::value == 2);
assert(extent<int[2][4]>::value == 2);
assert(extent<int[][4]>::value == 0);
assert((extent<int, 1>::value) == 0);
assert((extent<int[2], 1>::value) == 0);
assert((extent<int[2][4], 1>::value) == 4);
assert((extent<int[][4], 1>::value) == 4);
— end example ]
20.11.6 Relationships between types [meta.rel]
1This sub-clause contains templates that may be used to query relationships between types at compile time.
2Each of these templates shall be a BinaryTypeTrait (20.11.1) with a BaseCharacteristic of true_type if the
corresponding condition is true, otherwise false_type.
Table 51 — Type relationship predicates
Template Condition Comments
template <class T, class U>
struct is_same;
Tand Uname the same
type with the same
cv-qualifications
§ 20.11.6 596
c
ISO/IEC N????
Table 51 — Type relationship predicates (continued)
Template Condition Comments
template <class Base, class
Derived>
struct is_base_of;
Base is a base class of
Derived (Clause 10)
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
different types (ignoring possible
cv-qualifiers) then 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 (possibly cv-qualified) void
types.
3[Example:
struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : private B1, private B2 {};
is_base_of<B, D>::value // true
is_base_of<const B, D>::value // true
is_base_of<B, const D>::value // true
is_base_of<B, const B>::value // true
is_base_of<D, B>::value // false
is_base_of<B&, D&>::value // false
is_base_of<B[3], D[3]>::value // false
is_base_of<int, int>::value // false
— end example ]
4Given the following function prototype:
template <class T>
add_rvalue_reference_t<T> create();
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 create<From>();
}
[Note: This requirement gives well defined results for reference types, void types, array types, and
function types. — end note ] Access checking is performed as if in a context unrelated to To and From. Only
the validity of the immediate context of the expression of the return-statement (including conversions to
the return type) is considered. [ Note: The evaluation of the conversion can result in side effects such as
the instantiation of class template specializations and function template specializations, the generation of
§ 20.11.6 597
c
ISO/IEC N????
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 ]
20.11.7 Transformations between types [meta.trans]
1This sub-clause contains templates that may be used to transform one type to another following some
predefined rule.
2Each of the templates in this subclause shall be a TransformationTrait (20.11.1).
20.11.7.1 Const-volatile modifications [meta.trans.cv]
Table 52 — Const-volatile modifications
Template Comments
template <class T>
struct remove_const;
The member typedef type shall name the same type as Texcept that
any top-level const-qualifier has been removed.
[Example:remove_const<const volatile int>::type evaluates to
volatile int, whereas remove_const<const int*>::type evaluates
to const int*.— end example ]
template <class T>
struct remove_volatile;
The member typedef type shall name the same type as Texcept that
any top-level volatile-qualifier has been removed.
[Example:remove_volatile<const volatile int>::type evaluates to
const int, whereas remove_volatile<volatile int*>::type
evaluates to volatile int*.— end example ]
template <class T>
struct remove_cv;
The member typedef type shall be the same as Texcept that any
top-level cv-qualifier has been removed. [ Example:remove_cv<const
volatile int>::type evaluates to int, whereas remove_cv<const
volatile int*>::type evaluates to const volatile int*.— end
example ]
template <class T>
struct add_const;
If Tis a reference, function, or top-level const-qualified type, then type
shall name the same type as T, otherwise T const.
template <class T>
struct add_volatile;
If Tis a reference, function, or top-level volatile-qualified type, then
type shall name the same type as T, otherwise T volatile.
template <class T>
struct add_cv;
The member typedef type shall name the same type as
add_const_t<add_volatile_t<T>>.
20.11.7.2 Reference modifications [meta.trans.ref]
Table 53 — Reference modifications
Template Comments
template <class T>
struct remove_reference;
If Thas type “reference to T1” then the member typedef type shall
name T1; otherwise, type shall name T.
template <class T>
struct
add_lvalue_reference;
If Tnames an object or function type then the member typedef type
shall name T&; otherwise, if Tnames a type “rvalue reference to T1” then
the member typedef type shall name T1&; otherwise, type shall name T.
template <class T>
struct
add_rvalue_reference;
If Tnames an object or function type then the member typedef type
shall name T&&; otherwise, type shall name T. [ Note: This rule reflects
the semantics of reference collapsing (8.3.2). For example, when a type T
names a type T1&, the type add_rvalue_reference<T>::type is not an
rvalue reference. — end note ]
20.11.7.3 Sign modifications [meta.trans.sign]
§ 20.11.7.3 598
c
ISO/IEC N????
Table 54 — Sign modifications
Template Comments
template <class T>
struct make_signed;
If Tnames a (possibly cv-qualified) signed integer type (3.9.1) then the
member typedef type shall name the type T; otherwise, if Tnames a
(possibly cv-qualified) unsigned integer type then type shall name the
corresponding signed integer type, with the same cv-qualifiers as T;
otherwise, type shall name the signed integer type with smallest
rank (4.13) for which sizeof(T) == sizeof(type), with the same
cv-qualifiers as T.
Requires:Tshall be a (possibly cv-qualified) integral type or enumeration
but not a bool type.
template <class T>
struct make_unsigned;
If Tnames a (possibly cv-qualified) unsigned integer type (3.9.1) then
the member typedef type shall name the type T; otherwise, if Tnames a
(possibly cv-qualified) signed integer type then type shall name the
corresponding unsigned integer type, with the same cv-qualifiers as T;
otherwise, type shall name the unsigned integer type with smallest
rank (4.13) for which sizeof(T) == sizeof(type), with the same
cv-qualifiers as T.
Requires:Tshall be a (possibly cv-qualified) integral type or enumeration
but not a bool type.
§ 20.11.7.3 599
c
ISO/IEC N????
20.11.7.4 Array modifications [meta.trans.arr]
Table 55 — Array modifications
Template Comments
template <class T>
struct remove_extent;
If Tnames 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 Tis “multi-dimensional array of U”, the resulting member typedef
type is U, otherwise T.
1[Example
// the following assertions hold:
assert((is_same<remove_extent<int>::type, int>::value));
assert((is_same<remove_extent<int[2]>::type, int>::value));
assert((is_same<remove_extent<int[2][3]>::type, int[3]>::value));
assert((is_same<remove_extent<int[][3]>::type, int[3]>::value));
— end example ]
2[Example
// the following assertions hold:
assert((is_same<remove_all_extents<int>::type, int>::value));
assert((is_same<remove_all_extents<int[2]>::type, int>::value));
assert((is_same<remove_all_extents<int[2][3]>::type, int>::value));
assert((is_same<remove_all_extents<int[][3]>::type, int>::value));
— end example ]
20.11.7.5 Pointer modifications [meta.trans.ptr]
Table 56 — Pointer modifications
Template Comments
template <class T>
struct remove_pointer;
If Thas type “(possibly cv-qualified) pointer to T1” then the member
typedef type shall name T1; otherwise, it shall name T.
template <class T>
struct add_pointer;
The member typedef type shall name the same type as
remove_reference<T>::type*.
§ 20.11.7.5 600
c
ISO/IEC N????
20.11.7.6 Other transformations [meta.trans.other]
Table 57 — Other transformations
Template Condition Comments
template <std::size_t Len,
std::size_t Align
=default-alignment >
struct aligned_storage;
Len shall not be zero. Align
shall be equal to
alignof(T) for some type T
or to default-alignment.
The value of default-alignment shall
be the most stringent alignment
requirement for any C++ object type
whose size is no greater than
Len (3.9). 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.
template <std::size_t Len,
class... Types>
struct aligned_union;
At least one type is
provided.
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 std::size_t
whose value is the strictest alignment
of all types listed in Types.
template <class T> struct
decay;
Let Ube
remove_reference<T>::type. If
is_array<U>::value is true, the
member typedef type shall equal
remove_extent<U>::type*. If
is_function<U>::value is true, the
member typedef type shall equal
add_pointer<U>::type. Otherwise
the member typedef type equals
remove_cv<U>::type. [ Note: This
behavior is similar to the
lvalue-to-rvalue (4.1),
array-to-pointer (4.2), and
function-to-pointer (4.3) 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 Bis 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 Bis true, the member typedef type
shall equal T. If Bis false, the
member typedef type shall equal F.
§ 20.11.7.6 601
c
ISO/IEC N????
Table 57 — Other transformations (continued)
Template Condition Comments
template <class... T>
struct common_type;
The member typedef type shall be
defined as set out below. All types in
the parameter pack Tshall be
complete or (possibly cv)void. A
program may specialize this trait if at
least one template parameter in the
specialization is a user-defined type.
[Note: Such specializations are needed
when only explicit conversions are
desired among the template
arguments. — end note ]
template <class T>
struct underlying_type;
Tshall be an enumeration
type (7.2)
The member typedef type shall name
the underlying type of T.
template <class Fn,
class... ArgTypes> struct
result_of<Fn(ArgTypes...)>;
Fn and all types in the
parameter pack ArgTypes
shall be complete types,
(possibly cv-qualified) void,
or arrays of unknown bound.
If the expression
INVOKE(declval<Fn>(),
declval<ArgTypes>()...) is well
formed when treated as an
unevaluated operand (Clause 5), the
member typedef type shall name 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 ]
1[Note: A typical implementation would define aligned_storage as:
template <std::size_t Len, std::size_t Alignment>
struct aligned_storage {
typedef struct {
alignas(Alignment) unsigned char __data[Len];
} type;
};
— end note ]
2It is implementation-defined whether any extended alignment is supported (3.11).
3The nested typedef common_type::type shall be defined as follows:
§ 20.11.7.6 602
c
ISO/IEC N????
template <class ...T> struct common_type;
template <class T>
struct common_type<T> {
typedef T type;
};
template <class T, class U>
struct common_type<T, U> {
typedef decltype(true ? declval<T>() : declval<U>()) type;
};
template <class T, class U, class... V>
struct common_type<T, U, V...> {
typedef common_type_t<common_type_t<T, U>, V...> type;
};
4[Example: Given these definitions:
typedef bool (&PF1)();
typedef short (*PF2)(long);
struct S {
operator PF2() const;
double operator()(char, int&);
void fn(long) const;
char data;
};
typedef void (S::*PMF)(long) const;
typedef char S::*PMD;
the following assertions will hold:
static_assert(is_same<result_of<S(int)>::type, short>::value, "Error!");
static_assert(is_same<result_of<S&(unsigned char, int&)>::type, double>::value, "Error!");
static_assert(is_same<result_of<PF1()>::type, bool>::value, "Error!");
static_assert(is_same<result_of<PMF(unique_ptr<S>, int)>::type, void>::value, "Error!");
static_assert(is_same<result_of<PMD(S)>::type, char&&>::value, "Error!");
static_assert(is_same<result_of<PMD(const S*)>::type, const char&>::value, "Error!");
— end example ]
20.12 Compile-time rational arithmetic [ratio]
20.12.1 In general [ratio.general]
1This 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.
2Throughout this subclause, if the template argument types R1 and R2 are not specializations of the ratio
template, the program is ill-formed.
20.12.2 Header <ratio> synopsis [ratio.syn]
namespace std {
// 20.12.3, class template ratio
template <intmax_t N, intmax_t D = 1> class ratio;
// 20.12.4, ratio arithmetic
§ 20.12.2 603
c
ISO/IEC N????
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 ;
// 20.12.5, 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;
// 20.12.6, convenience SI typedefs
typedef ratio<1, 1000000000000000000000000> yocto; // see below
typedef ratio<1, 1000000000000000000000> zepto; // see below
typedef ratio<1, 1000000000000000000> atto;
typedef ratio<1, 1000000000000000> femto;
typedef ratio<1, 1000000000000> pico;
typedef ratio<1, 1000000000> nano;
typedef ratio<1, 1000000> micro;
typedef ratio<1, 1000> milli;
typedef ratio<1, 100> centi;
typedef ratio<1, 10> deci;
typedef ratio< 10, 1> deca;
typedef ratio< 100, 1> hecto;
typedef ratio< 1000, 1> kilo;
typedef ratio< 1000000, 1> mega;
typedef ratio< 1000000000, 1> giga;
typedef ratio< 1000000000000, 1> tera;
typedef ratio< 1000000000000000, 1> peta;
typedef ratio< 1000000000000000000, 1> exa;
typedef ratio< 1000000000000000000000, 1> zetta; // see below
typedef ratio<1000000000000000000000000, 1> yotta; // see below
}
20.12.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;
typedef ratio<num, den> type;
};
}
1If the template argument Dis zero or the absolute values of either of the template arguments Nand Dis 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 ]
2The static data members num and den shall have the following values, where gcd represents the greatest
common divisor of the absolute values of Nand D:
num shall have the value sign(N) * sign(D) * abs(N) / gcd.
§ 20.12.3 604
c
ISO/IEC N????
den shall have the value abs(D) / gcd.
20.12.4 Arithmetic on ratios [ratio.arithmetic]
1Each of the alias templates ratio_add,ratio_subtract,ratio_multiply, and ratio_divide denotes the
result of an arithmetic computation on two ratiosR1 and R2. With Xand Ycomputed (in the absence of
arithmetic overflow) as specified by Table 58, each alias denotes a ratio<U, V> such that Uis the same as
ratio<X, Y>::num and Vis the same as ratio<X, Y>::den.
2If it is not possible to represent Uor Vwith intmax_t, the program is ill-formed. Otherwise, an implemen-
tation should yield correct values of Uand V. If it is not possible to represent Xor Ywith intmax_t, the
program is ill-formed unless the implementation yields correct values of Uand V.
Table 58 — Expressions used to perform ratio arithmetic
Type Value of XValue 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
3[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 ]
20.12.5 Comparison of ratios [ratio.comparison]
template <class R1, class R2> struct ratio_equal
: integral_constant<bool, see below > { };
1If R1::num == R2::num and R1::den == R2::den,ratio_equal<R1, R2> shall be derived from
integral_constant<bool, true>; otherwise it shall be derived from integral_constant<bool,
false>.
template <class R1, class R2> struct ratio_not_equal
: integral_constant<bool, !ratio_equal<R1, R2>::value> { };
template <class R1, class R2> struct ratio_less
: integral_constant<bool, see below > { };
§ 20.12.5 605
c
ISO/IEC N????
2If R1::num * R2::den < R2::num * R1::den,ratio_less<R1, R2> shall be derived from integral_-
constant<bool, true>; otherwise it shall be derived from integral_constant<bool, false>. Im-
plementations 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
: integral_constant<bool, !ratio_less<R2, R1>::value> { };
template <class R1, class R2> struct ratio_greater
: integral_constant<bool, ratio_less<R2, R1>::value> { };
template <class R1, class R2> struct ratio_greater_equal
: integral_constant<bool, !ratio_less<R1, R2>::value> { };
20.12.6 SI types for ratio [ratio.si]
1For each of the typedefs 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.
20.13 Time utilities [time]
20.13.1 In general [time.general]
1This subclause describes the chrono library (20.13.2) and various C functions (20.13.8) that provide generally
useful time utilities.
20.13.2 Header <chrono> synopsis [time.syn]
namespace std {
namespace chrono {
// 20.13.5, class template duration
template <class Rep, class Period = ratio<1> > class duration;
// 20.13.6, class template time_point
template <class Clock, class Duration = typename Clock::duration> class time_point;
}// namespace chrono
// 20.13.4.3 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 {
// 20.13.4, customization traits
template <class Rep> struct treat_as_floating_point;
template <class Rep> struct duration_values;
// 20.13.5.5, 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>
§ 20.13.2 606
c
ISO/IEC N????
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);
// 20.13.5.6, 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);
// 20.13.5.7, duration_cast
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
// convenience typedefs
typedef duration<signed integer type of at least 64 bits, nano> nanoseconds;
typedef duration<signed integer type of at least 55 bits, micro> microseconds;
typedef duration<signed integer type of at least 45 bits, milli> milliseconds;
typedef duration<signed integer type of at least 35 bits > seconds;
typedef duration<signed integer type of at least 29 bits, ratio< 60>> minutes;
typedef duration<signed integer type of at least 23 bits, ratio<3600>> hours;
// 20.13.6.5, time_point arithmetic
template <class Clock, class Duration1, class Rep2, class Period2>
§ 20.13.2 607
c
ISO/IEC N????
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);
// 20.13.6.6 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);
// 20.13.6.7, time_point_cast
template <class ToDuration, class Clock, class Duration>
constexpr time_point<Clock, ToDuration>
time_point_cast(const time_point<Clock, Duration>& t);
// 20.13.7, clocks
class system_clock;
class steady_clock;
class high_resolution_clock;
}// namespace chrono
inline namespace literals {
inline namespace chrono_literals {
// 20.13.5.8, 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);
§ 20.13.2 608
c
ISO/IEC N????
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_literals
}// namespace literals
}// namespace std
20.13.3 Clock requirements [time.clock.req]
1A 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 59.
2In Table 59 C1 and C2 denote clock types. t1 and t2 are values returned by C1::now() where the call
returning t1 happens before (1.10) 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 59 — 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.
3[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 ]
4A type TC meets the TrivialClock requirements if:
TC satisfies the Clock requirements (20.13.3),
the types TC::rep,TC::duration, and TC::time_point satisfy the requirements of EqualityCom-
parable (Table 17), LessThanComparable (Table 18), DefaultConstructible (Table 19), CopyCon-
structible (Table 21), CopyAssignable (Table 23), Destructible (Table 24), and the requirements
of numeric types (26.2). [ 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 (17.6.3.2),
the function TC::now() does not throw exceptions, and
the type TC::time_point::clock meets the TrivialClock requirements, recursively.
§ 20.13.3 609
c
ISO/IEC N????
20.13.4 Time-related traits [time.traits]
20.13.4.1 treat_as_floating_point [time.traits.is_fp]
template <class Rep> struct treat_as_floating_point
: is_floating_point<Rep> { };
1The 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<Rep>::value
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<Rep>::value is false,Rep will be treated as if it behaved
like an integral type for the purpose of these conversions. — end note ]
20.13.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();
};
1The duration template uses the duration_values trait to construct special values of the durations repre-
sentation (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();
2Returns: Rep(0). [ Note: Rep(0) is specified instead of Rep() because Rep() may have some other
meaning, such as an uninitialized value. — end note ]
3Remark: The value returned shall be the additive identity.
static constexpr Rep min();
4Returns: numeric_limits<Rep>::lowest().
5Remark: The value returned shall compare less than or equal to zero().
static constexpr Rep max();
6Returns: numeric_limits<Rep>::max().
7Remark: The value returned shall compare greater than zero().
20.13.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>> {
typedef chrono::duration<common_type_t<Rep1, Rep2>, see below > type;
};
1The period of the duration indicated by this specialization of common_type shall be the greatest com-
mon 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 ]
§ 20.13.4.3 610
c
ISO/IEC N????
2[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>> {
typedef chrono::time_point<Clock, common_type_t<Duration1, Duration2>> type;
};
3The 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.
20.13.5 Class template duration [time.duration]
1Aduration 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:
typedef Rep rep;
typedef Period period;
private:
rep rep_; // exposition only
public:
// 20.13.5.1, 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;
// 20.13.5.2, observer:
constexpr rep count() const;
// 20.13.5.3, arithmetic:
constexpr duration operator+() const;
constexpr duration operator-() const;
duration& operator++();
duration operator++(int);
duration& operator--();
duration operator--(int);
duration& operator+=(const duration& d);
duration& operator-=(const duration& d);
duration& operator*=(const rep& rhs);
duration& operator/=(const rep& rhs);
duration& operator%=(const rep& rhs);
duration& operator%=(const duration& rhs);
// 20.13.5.4, special values:
static constexpr duration zero();
§ 20.13.5 611
c
ISO/IEC N????
static constexpr duration min();
static constexpr duration max();
};
2Requires: Rep shall be an arithmetic type or a class emulating an arithmetic type.
3Remarks: If duration is instantiated with a duration type for the template argument Rep, the
program is ill-formed.
4Remarks: If Period is not a specialization of ratio, the program is ill-formed.
5Remarks: If Period::num is not positive, the program is ill-formed.
6Requires: Members of duration shall not throw exceptions other than those thrown by the indicated
operations on their representations.
7Remarks: 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 1
30 of a second
// (30 Hz) using a double
— end example ]
20.13.5.1 duration constructors [time.duration.cons]
template <class Rep2>
constexpr explicit duration(const Rep2& r);
1Remarks: This constructor shall not participate in overload resolution unless Rep2 is implicitly con-
vertible to rep and
treat_as_floating_point<rep>::value is true or
treat_as_floating_point<Rep2>::value is false.
[Example:
duration<int, milli> d(3); // OK
duration<int, milli> d(3.5); // error
— end example ]
2Effects: Constructs an object of type duration.
3Postcondition: count() == static_cast<rep>(r).
template <class Rep2, class Period2>
constexpr duration(const duration<Rep2, Period2>& d);
4Remarks: This constructor shall not participate in overload resolution unless no overflow is induced in
the conversion and treat_as_floating_point<rep>::value is true or both ratio_divide<Period2,
period>::den is 1and treat_as_floating_point<Rep2>::value is false. [ Note: This requirement
prevents implicit truncation error when converting between integral-based duration types. Such a con-
struction could easily lead to confusion about the value of the duration.— end note ] [ Example:
§ 20.13.5.1 612
c
ISO/IEC N????
duration<int, milli> ms(3);
duration<int, micro> us = ms; // OK
duration<int, milli> ms2 = us; // error
— end example ]
5Effects: Constructs an object of type duration, constructing rep_ from
duration_cast<duration>(d).count().
20.13.5.2 duration observer [time.duration.observer]
constexpr rep count() const;
1Returns: rep_.
20.13.5.3 duration arithmetic [time.duration.arithmetic]
constexpr duration operator+() const;
1Returns: *this.
constexpr duration operator-() const;
2Returns: duration(-rep_);.
duration& operator++();
3Effects: ++rep_.
4Returns: *this.
duration operator++(int);
5Returns: duration(rep_++);.
duration& operator--();
6Effects: --rep_.
7Returns: *this.
duration operator--(int);
8Returns: duration(rep_--);.
duration& operator+=(const duration& d);
9Effects: rep_ += d.count().
10 Returns: *this.
duration& operator-=(const duration& d);
§ 20.13.5.3 613
c
ISO/IEC N????
11 Effects: rep_ -= d.count().
12 Returns: *this.
duration& operator*=(const rep& rhs);
13 Effects: rep_ *= rhs.
14 Returns: *this.
duration& operator/=(const rep& rhs);
15 Effects: rep_ /= rhs.
16 Returns: *this.
duration& operator%=(const rep& rhs);
17 Effects: rep_ %= rhs.
18 Returns: *this.
duration& operator%=(const duration& rhs);
19 Effects: rep_ %= rhs.count().
20 Returns: *this.
20.13.5.4 duration special values [time.duration.special]
static constexpr duration zero();
1Returns: duration(duration_values<rep>::zero()).
static constexpr duration min();
2Returns: duration(duration_values<rep>::min()).
static constexpr duration max();
3Returns: duration(duration_values<rep>::max()).
20.13.5.5 duration non-member arithmetic [time.duration.nonmember]
1In the function descriptions that follow, CD represents the return type of the function. CR(A,B) represents
common_type<A, B>::type.
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);
2Returns: 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);
§ 20.13.5.5 614
c
ISO/IEC N????
3Returns: 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);
4Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible
to CR(Rep1, Rep2).
5Returns: 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);
6Remarks: This operator shall not participate in overload resolution unless Rep1 is implicitly convertible
to CR(Rep1, Rep2).
7Returns: 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);
8Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible
to CR(Rep1, Rep2) and Rep2 is not an instantiation of duration.
9Returns: 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);
10 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);
11 Remarks: This operator shall not participate in overload resolution unless Rep2 is implicitly convertible
to CR(Rep1, Rep2) and Rep2 is not an instantiation of duration.
12 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);
13 Returns: CD(CD(lhs).count() % CD(rhs).count()).
§ 20.13.5.5 615
c
ISO/IEC N????
20.13.5.6 duration comparisons [time.duration.comparisons]
1In the function descriptions that follow, CT represents common_type<A, B>::type, where Aand Bare 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);
2Returns: 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);
3Returns: !(lhs == rhs).
template <class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator<(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
4Returns: 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);
5Returns: !(rhs < lhs).
template <class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
6Returns: rhs < lhs.
template <class Rep1, class Period1, class Rep2, class Period2>
constexpr bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
7Returns: !(lhs < rhs).
20.13.5.7 duration_cast [time.duration.cast]
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
1Remarks: This function shall not participate in overload resolution unless ToDuration is an instanti-
ation of duration.
2Returns: 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)))
§ 20.13.5.7 616
c
ISO/IEC N????
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)))
Notes: 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.
20.13.5.8 Suffixes for duration literals [time.duration.literals]
1This 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.
2If any of these suffixes are applied to a floating point literal the result is a chrono::duration literal with
an unspecified floating point representation.
3If 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.
4[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);
5Returns: Aduration 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);
6Returns: Aduration literal representing minutes minutes.
constexpr chrono::seconds operator "" s(unsigned long long sec);
constexpr chrono::duration<unspecified > operator "" s(long double sec);
7Returns: Aduration literal representing sec seconds.
8[Note: The same suffix sis 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);
9Returns: Aduration literal representing msec milliseconds.
§ 20.13.5.8 617
c
ISO/IEC N????
constexpr chrono::microseconds operator "" us(unsigned long long usec);
constexpr chrono::duration<unspecified , micro> operator "" us(long double usec);
10 Returns: Aduration literal representing usec microseconds.
constexpr chrono::nanoseconds operator "" ns(unsigned long long nsec);
constexpr chrono::duration<unspecified , nano> operator "" ns(long double nsec);
11 Returns: Aduration literal representing nsec nanoseconds.
20.13.6 Class template time_point [time.point]
template <class Clock, class Duration = typename Clock::duration>
class time_point {
public:
typedef Clock clock;
typedef Duration duration;
typedef typename duration::rep rep;
typedef typename duration::period period;
private:
duration d_; // exposition only
public:
// 20.13.6.1, 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);
// 20.13.6.2, observer:
constexpr duration time_since_epoch() const;
// 20.13.6.3, arithmetic:
time_point& operator+=(const duration& d);
time_point& operator-=(const duration& d);
// 20.13.6.4, special values:
static constexpr time_point min();
static constexpr time_point max();
};
1Clock shall meet the Clock requirements (20.13.7).
2If Duration is not an instance of duration, the program is ill-formed.
20.13.6.1 time_point constructors [time.point.cons]
constexpr time_point();
1Effects: 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);
2Effects: Constructs an object of type time_point, initializing d_ with d. Such a time_point object
represents the epoch + d.
§ 20.13.6.1 618
c
ISO/IEC N????
template <class Duration2>
constexpr time_point(const time_point<clock, Duration2>& t);
3Remarks: This constructor shall not participate in overload resolution unless Duration2 is implicitly
convertible to duration.
4Effects: Constructs an object of type time_point, initializing d_ with t.time_since_epoch().
20.13.6.2 time_point observer [time.point.observer]
constexpr duration time_since_epoch() const;
1Returns: d_.
20.13.6.3 time_point arithmetic [time.point.arithmetic]
time_point& operator+=(const duration& d);
1Effects: d_ += d.
2Returns: *this.
time_point& operator-=(const duration& d);
3Effects: d_ -= d.
4Returns: *this.
20.13.6.4 time_point special values [time.point.special]
static constexpr time_point min();
1Returns: time_point(duration::min()).
static constexpr time_point max();
2Returns: time_point(duration::max()).
20.13.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);
1Returns: 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);
2Returns: 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);
3Returns: lhs + (-rhs).
§ 20.13.6.5 619
c
ISO/IEC N????
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);
4Returns: lhs.time_since_epoch() - rhs.time_since_epoch().
20.13.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);
1Returns: 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);
2Returns: !(lhs == rhs).
template <class Clock, class Duration1, class Duration2>
constexpr bool operator<(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
3Returns: 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);
4Returns: !(rhs < lhs).
template <class Clock, class Duration1, class Duration2>
constexpr bool operator>(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
5Returns: rhs < lhs.
template <class Clock, class Duration1, class Duration2>
constexpr bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
6Returns: !(lhs < rhs).
20.13.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);
1Remarks: This function shall not participate in overload resolution unless ToDuration is an instanti-
ation of duration.
2Returns: time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch())).
§ 20.13.6.7 620
c
ISO/IEC N????
20.13.7 Clocks [time.clock]
1The types defined in this subclause shall satisfy the TrivialClock requirements (20.13.3).
20.13.7.1 Class system_clock [time.clock.system]
1Objects of class system_clock represent wall clock time from the system-wide realtime clock.
class system_clock {
public:
typedef see below rep;
typedef ratio<unspecified ,unspecified > period;
typedef chrono::duration<rep, period> duration;
typedef chrono::time_point<system_clock> time_point;
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;
};
typedef unspecified system_clock::rep;
2Requires: 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;
3Returns: Atime_t object that represents the same point in time as twhen 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;
4Returns: Atime_point object that represents the same point in time as twhen 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.
20.13.7.2 Class steady_clock [time.clock.steady]
1Objects 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:
typedef unspecified rep;
typedef ratio<unspecified ,unspecified > period;
typedef chrono::duration<rep, period> duration;
typedef chrono::time_point<unspecified , duration> time_point;
static constexpr bool is_steady = true;
static time_point now() noexcept;
};
§ 20.13.7.2 621
c
ISO/IEC N????
20.13.7.3 Class high_resolution_clock [time.clock.hires]
1Objects 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:
typedef unspecified rep;
typedef ratio<unspecified ,unspecified > period;
typedef chrono::duration<rep, period> duration;
typedef chrono::time_point<unspecified , duration> time_point;
static constexpr bool is_steady = unspecified ;
static time_point now() noexcept;
};
20.13.8 Date and time functions [date.time]
1Table 60 describes the header <ctime>.
Table 60 — Header <ctime> synopsis
Type Name(s)
Macros:NULL CLOCKS_PER_SEC
Types:size_t clock_t time_t
Struct:tm
Functions:
asctime clock difftime localtime strftime
ctime gmtime mktime time
2The contents are the same as the Standard C library header <time.h>.234 The functions asctime,ctime,
gmtime, and localtime are not required to avoid data races (17.6.5.9).
See also: ISO C Clause 7.12, Amendment 1 Clause 4.6.4.
20.14 Class template scoped_allocator_adaptor [allocator.adaptor]
20.14.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;
1The 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 alloca-
tor type, the inner allocator becomes the scoped_allocator_adaptor itself, thus using the same allocator
234) strftime supports the C conversion specifiers C,D,e,F,g,G,h,r,R,t,T,u,V, and z, and the modifiers Eand O.
§ 20.14.1 622
c
ISO/IEC N????
resource for the container and every element within the container and, if the elements themselves are con-
tainers, 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:
typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only
public:
typedef OuterAlloc outer_allocator_type;
typedef see below inner_allocator_type;
typedef typename OuterTraits::value_type value_type;
typedef typename OuterTraits::size_type size_type;
typedef typename OuterTraits::difference_type difference_type;
typedef typename OuterTraits::pointer pointer;
typedef typename OuterTraits::const_pointer const_pointer;
typedef typename OuterTraits::void_pointer void_pointer;
typedef typename OuterTraits::const_void_pointer const_void_pointer;
typedef see below propagate_on_container_copy_assignment;
typedef see below propagate_on_container_move_assignment;
typedef see below propagate_on_container_swap;
template <class Tp>
struct rebind {
typedef scoped_allocator_adaptor<
OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
};
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();
inner_allocator_type& inner_allocator() noexcept;
§ 20.14.1 623
c
ISO/IEC N????
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 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;
}
20.14.2 Scoped allocator adaptor member types [allocator.adaptor.types]
typedef see below inner_allocator_type;
1Type: scoped_allocator_adaptor<OuterAlloc> if sizeof...(InnerAllocs) is zero; otherwise,
scoped_allocator_adaptor<InnerAllocs...>.
typedef see below propagate_on_container_copy_assignment;
2Type: true_type if allocator_traits<A>::propagate_on_container_copy_assignment::value is
true for any Ain the set of OuterAlloc and InnerAllocs...; otherwise, false_type.
typedef see below propagate_on_container_move_assignment;
3Type: true_type if allocator_traits<A>::propagate_on_container_move_assignment::value is
true for any Ain the set of OuterAlloc and InnerAllocs...; otherwise, false_type.
§ 20.14.2 624
c
ISO/IEC N????
typedef see below propagate_on_container_swap;
4Type: true_type if allocator_traits<A>::propagate_on_container_swap::value is true for any
Ain the set of OuterAlloc and InnerAllocs...; otherwise, false_type.
20.14.3 Scoped allocator adaptor constructors [allocator.adaptor.cnstr]
scoped_allocator_adaptor();
1Effects: value-initializes the OuterAlloc base class and the inner allocator object.
template <class OuterA2>
scoped_allocator_adaptor(OuterA2&& outerAlloc,
const InnerAllocs&... innerAllocs) noexcept;
2Requires: OuterAlloc shall be constructible from OuterA2.
3Effects: initializes the OuterAlloc base class with std::forward<OuterA2>(outerAlloc) and inner
with innerAllocs... (hence recursively initializing each allocator within the adaptor with the corre-
sponding allocator from the argument list).
scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
4Effects: initializes each allocator within the adaptor with the corresponding allocator from other.
scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
5Effects: 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;
6Requires: OuterAlloc shall be constructible from OuterA2.
7Effects: initializes each allocator within the adaptor with the corresponding allocator from other.
template <class OuterA2>
scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2,
InnerAllocs...>&& other) noexcept;
8Requires: OuterAlloc shall be constructible from OuterA2.
9Effects: initializes each allocator within the adaptor with the corresponding allocator rvalue from
other.
§ 20.14.3 625
c
ISO/IEC N????
20.14.4 Scoped allocator adaptor members [allocator.adaptor.members]
1In the construct member functions, OUTERMOST(x) is xif xdoes not have an outer_allocator() mem-
ber 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;
2Returns: *this if sizeof...(InnerAllocs) is zero; otherwise, inner.
outer_allocator_type& outer_allocator() noexcept;
3Returns: static_cast<OuterAlloc&>(*this).
const outer_allocator_type& outer_allocator() const noexcept;
4Returns: static_cast<const OuterAlloc&>(*this).
pointer allocate(size_type n);
5Returns: allocator_traits<OuterAlloc>::allocate(outer_allocator(), n).
pointer allocate(size_type n, const_void_pointer hint);
6Returns: allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint).
void deallocate(pointer p, size_type n) noexcept;
7Effects: allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n);
size_type max_size() const;
8Returns: allocator_traits<OuterAlloc>::max_size(outer_allocator()).
template <class T, class... Args>
void construct(T* p, Args&&... args);
9Effects:
— If uses_allocator<T, inner_allocator_type>::value is false and is_constructible<T,
Args...>::value is true, calls OUTERMOST_ALLOC_TRAITS(*this)::construct(
OUTERMOST (*this), p, std::forward<Args>(args)...).
Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and is_construc-
tible<T, allocator_arg_t, inner_allocator_type, Args...>::value is true, calls OUT-
ERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p, allocator_arg,
inner_allocator(), std::forward<Args>(args)...).
§ 20.14.4 626
c
ISO/IEC N????
Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and is_construct-
ible<T, Args..., inner_allocator_type>::value 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);
10 Requires: all of the types in Args1 and Args2 shall be CopyConstructible (Table 21).
11 Effects: Constructs a tuple object xprime from xby the following rules:
If uses_allocator<T1, inner_allocator_type>::value is false and is_constructible<T1,
Args1...>::value is true, then xprime is x.
Otherwise, if uses_allocator<T1, inner_allocator_type>::value is true and is_construct-
ible<T1, allocator_arg_t, inner_allocator_type, Args1...>::value 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<T1, inner_allocator_type>::value is true and is_construct-
ible<T1, Args1..., inner_allocator_type>::value 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 yby the following rules:
If uses_allocator<T2, inner_allocator_type>::value is false and is_constructible<T2,
Args2...>::value is true, then yprime is y.
Otherwise, if uses_allocator<T2, inner_allocator_type>::value is true and is_construct-
ible<T2, allocator_arg_t, inner_allocator_type, Args2...>::value 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<T2, inner_allocator_type>::value is true and is_construct-
ible<T2, Args2..., inner_allocator_type>::value 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);
12 Effects: equivalent to this->construct(p, piecewise_construct, tuple<>(), tuple<>()).
§ 20.14.4 627
c
ISO/IEC N????
template <class T1, class T2, class U, class V>
void construct(pair<T1, T2>* p, U&& x, V&& y);
13 Effects: equivalent to this->construct(p, piecewise_construct, forward_as_tuple(std::for-
ward<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);
14 Effects: equivalent to this->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);
15 Effects: equivalent to this->construct(p, piecewise_construct, forward_as_tuple(std::for-
ward<U>(x.first)), forward_as_tuple(std::forward<V>(x.second))).
template <class T>
void destroy(T* p);
16 Effects: calls OUTERMOST_ALLOC_TRAITS (*this)::destroy(OUTERMOST (*this), p).
scoped_allocator_adaptor select_on_container_copy_construction() const;
17 Returns: A new scoped_allocator_adaptor object where each allocator Ain the adaptor is initialized
from the result of calling allocator_traits<A>::select_on_container_copy_construction() on
the corresponding allocator in *this.
20.14.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;
1Returns: a.outer_allocator() == b.outer_allocator() if sizeof...(InnerAllocs) is zero; oth-
erwise, 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;
2Returns: !(a == b).
§ 20.14.5 628
c
ISO/IEC N????
20.15 Class type_index [type.index]
20.15.1 Header <typeindex> synopsis [type.index.synopsis]
namespace std {
class type_index;
template <class T> struct hash;
template<> struct hash<type_index>;
}
20.15.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.
};
}
1The class type_index provides a simple wrapper for type_info which can be used as an index type in
associative containers (23.4) and in unordered associative containers (23.5).
20.15.3 type_index members [type.index.members]
type_index(const type_info& rhs) noexcept;
1Effects: constructs a type_index object, the equivalent of target = &rhs.
bool operator==(const type_index& rhs) const noexcept;
2Returns: *target == *rhs.target
bool operator!=(const type_index& rhs) const noexcept;
3Returns: *target != *rhs.target
bool operator<(const type_index& rhs) const noexcept;
4Returns: target->before(*rhs.target)
bool operator<=(const type_index& rhs) const noexcept;
5Returns: !rhs.target->before(*target)
§ 20.15.3 629
c
ISO/IEC N????
bool operator>(const type_index& rhs) const noexcept;
6Returns: rhs.target->before(*target)
bool operator>=(const type_index& rhs) const noexcept;
7Returns: !target->before(*rhs.target)
size_t hash_code() const noexcept;
8Returns: target->hash_code()
const char* name() const noexcept;
9Returns: target->name()
20.15.4 Hash support [type.index.hash]
template <> struct hash<type_index>;
1The template specialization shall meet the requirements of class template hash (20.10.12). For an
object index of type type_index,hash<type_index>()(index) shall evaluate to the same result as
index.hash_code().
§ 20.15.4 630
c
ISO/IEC N????
21 Strings library [strings]
21.1 General [strings.general]
1This Clause describes components for manipulating sequences of any non-array POD (3.9) type. In this
Clause such types are called char-like types , and objects of char-like types are called char-like objects or
simply characters.
2The following subclauses describe a character traits class, a string class, and null-terminated sequence
utilities, as summarized in Table 61.
Table 61 — Strings library summary
Subclause Header(s)
21.2 Character traits <string>
21.3 String classes <string>
<cctype>
<cwctype>
21.8 Null-terminated sequence utilities <cstring>
<cwchar>
<cstdlib>
<cuchar>
21.2 Character traits [char.traits]
1This 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.
2Most classes specified in Clauses 21.3 and 27 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 typedefs and
functions in the template parameter ‘traits’ used by each such template. This subclause defines the semantics
of these members.
3To 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 formal parameters charT and traits.Traits::char_type shall be the same as
CharT.
4This subclause specifies a struct 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.
21.2.1 Character traits requirements [char.traits.require]
1In Table 62,Xdenotes a Traits class defining types and functions for the character container type CharT;
cand ddenote values of type CharT;pand qdenote values of type const CharT*;sdenotes a value of
type CharT*;n,iand jdenote values of type std::size_t;eand fdenote 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 rdenotes an
lvalue of type CharT. Operations on Traits shall not throw exceptions.
§ 21.2.1 631
c
ISO/IEC N????
Table 62 — Character traits requirements
Expression Return type Assertion/note Complexity
pre-/post-condition
X::char_type charT (described in 21.2.2) compile-time
X::int_type (described in 21.2.2) compile-time
X::off_type (described in 21.2.2) compile-time
X::pos_type (described in 21.2.2) compile-time
X::state_type (described in 21.2.2) compile-time
X::eq(c,d) bool yields: whether cis to be
treated as equal to d.
constant
X::lt(c,d) bool yields: whether cis to be
treated as less than d.
constant
X::compare(p,q,n) int yields: 0if for each iin [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 iin [0,j)
X::eq(p[i],q[i]) is true; else
a positive value.
linear
X::length(p) std::size_t yields: the smallest isuch that
X::eq(p[i],charT()) is true.
linear
X::find(p,n,c) const X::char_type* yields: the smallest qin
[p,p+n) such that
X::eq(*q,c) is true, zero
otherwise.
linear
X::move(s,p,n) X::char_type* for each iin [0,n), performs
X::assign(s[i],p[i]).
Copies correctly even where the
ranges [p,p+n) and [s,s+n)
overlap. yields: s.
linear
X::copy(s,p,n) X::char_type* pre: pnot in [s,s+n). yields:
s. for each iin [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 iin [0,n), performs
X::assign(s[i],c). yields: s.
linear
X::not_eof(e) int_type yields: eif
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 yields: if for some c,
X::eq_int_type(e,X::to_-
int_type(c)) is true, c; else
some unspecified value.
constant
§ 21.2.1 632
c
ISO/IEC N????
Table 62 — Character traits requirements (continued)
Expression Return type Assertion/note Complexity
pre-/post-condition
X::to_int_type(c) X::int_type yields: some value e,
constrained by the definitions of
to_char_type and
eq_int_type.
constant
X::eq_int_type(e,f) bool yields: for all cand 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 eand f
are both copies of X::eof();
otherwise, yields false if one of
eand fis a copy of X::eof()
and the other is not; otherwise
the value is unspecified.
constant
X::eof() X::int_type yields: a value esuch that
X::eq_int_type(e,X::to_-
int_type(c)) is false for all
values c.
constant
2The struct template
template<class charT> struct char_traits;
shall be provided in the header <string> as a basis for explicit specializations.
21.2.2 traits typedefs [char.traits.typedefs]
typedef CHAR_T char_type;
1The type char_type is used to refer to the character container type in the implementation of the
library classes defined in 21.3 and Clause 27.
typedef INT_T int_type;
2Requires: 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.235
typedef implementation-defined off_type;
typedef implementation-defined pos_type;
3Requires: Requirements for off_type and pos_type are described in 27.2.2 and 27.3.
typedef STATE_T state_type;
4Requires: state_type shall meet the requirements of CopyAssignable (Table 23), CopyConstructible
(Table 21), and DefaultConstructible (Table 19) types.
235) If eof() can be held in char_type then some iostreams operations may give surprising results.
§ 21.2.2 633
c
ISO/IEC N????
21.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>;
}
1The header <string> shall define four specializations of the template struct char_traits:char_traits<
char>,char_traits<char16_t>,char_traits<char32_t>, and char_traits<wchar_t>.
2The requirements for the members of these specializations are given in Clause 21.2.1.
21.2.3.1 struct char_traits<char> [char.traits.specializations.char]
namespace std {
template<> struct char_traits<char> {
typedef char char_type;
typedef int int_type;
typedef streamoff off_type;
typedef streampos pos_type;
typedef mbstate_t state_type;
static 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 int compare(const char_type* s1, const char_type* s2, size_t n);
static size_t length(const char_type* s);
static 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;
};
}
1The defined types for int_type,pos_type,off_type, and state_type shall be int,streampos,streamoff,
and mbstate_t respectively.
2The type streampos shall be an implementation-defined type that satisfies the requirements for pos_type
in 27.2.2 and 27.3.
3The type streamoff shall be an implementation-defined type that satisfies the requirements for off_type
in 27.2.2 and 27.3.
4The 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.
5The 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.
6The member eof() shall return EOF.
21.2.3.2 struct char_traits<char16_t> [char.traits.specializations.char16_t]
§ 21.2.3.2 634
c
ISO/IEC N????
namespace std {
template<> struct char_traits<char16_t> {
typedef char16_t char_type;
typedef uint_least16_t int_type;
typedef streamoff off_type;
typedef u16streampos pos_type;
typedef mbstate_t state_type;
static 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 int compare(const char_type* s1, const char_type* s2, size_t n);
static size_t length(const char_type* s);
static 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;
};
}
1The type u16streampos shall be an implementation-defined type that satisfies the requirements for pos_type
in 27.2.2 and 27.3.
2The two-argument members assign,eq, and lt shall be defined identically to the built-in operators =,==,
and <respectively.
3The member eof() shall return an implementation-defined constant that cannot appear as a valid UTF-16
code unit.
21.2.3.3 struct char_traits<char32_t> [char.traits.specializations.char32_t]
namespace std {
template<> struct char_traits<char32_t> {
typedef char32_t char_type;
typedef uint_least32_t int_type;
typedef streamoff off_type;
typedef u32streampos pos_type;
typedef mbstate_t state_type;
static 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 int compare(const char_type* s1, const char_type* s2, size_t n);
static size_t length(const char_type* s);
static 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);
§ 21.2.3.3 635
c
ISO/IEC N????
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;
};
}
1The type u32streampos shall be an implementation-defined type that satisfies the requirements for pos_type
in 27.2.2 and 27.3.
2The two-argument members assign,eq, and lt shall be defined identically to the built-in operators =,==,
and <respectively.
3The member eof() shall return an implementation-defined constant that cannot appear as a Unicode code
point.
21.2.3.4 struct char_traits<wchar_t> [char.traits.specializations.wchar.t]
namespace std {
template<> struct char_traits<wchar_t> {
typedef wchar_t char_type;
typedef wint_t int_type;
typedef streamoff off_type;
typedef wstreampos pos_type;
typedef mbstate_t state_type;
static 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 int compare(const char_type* s1, const char_type* s2, size_t n);
static size_t length(const char_type* s);
static 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;
};
}
1The defined types for int_type,pos_type, and state_type shall be wint_t,wstreampos, and mbstate_t
respectively.
2The type wstreampos shall be an implementation-defined type that satisfies the requirements for pos_type
in 27.2.2 and 27.3.
3The 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.
4The two-argument members assign,eq, and lt shall be defined identically to the built-in operators =,==,
and <respectively.
§ 21.2.3.4 636
c
ISO/IEC N????
5The member eof() shall return WEOF.
21.3 String classes [string.classes]
1The header <string> defines the basic_string class template for manipulating varying-length sequences
of char-like objects and four typedefs, string,u16string,u32string, and wstring, that name the special-
izations basic_string<char>,basic_string<char16_t>,basic_string<char32_t>, and basic_string<
wchar_t>, respectively.
Header <string> synopsis
#include <initializer_list>
namespace std {
// 21.2, 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>;
// 21.4, 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>
§ 21.3 637
c
ISO/IEC N????
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;
§ 21.3 638
c
ISO/IEC N????
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);
// 21.4.8.8, swap:
template<class charT, class traits, class Allocator>
void swap(basic_string<charT,traits,Allocator>& lhs,
basic_string<charT,traits,Allocator>& rhs);
// 21.4.8.9, 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
typedef basic_string<char> string;
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
typedef basic_string<wchar_t> wstring;
§ 21.3 639
c
ISO/IEC N????
// 21.5, 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);
// 21.6, hash support:
template <class T> struct hash;
template <> struct hash<string>;
template <> struct hash<u16string>;
template <> struct hash<u32string>;
template <> struct hash<wstring>;
inline namespace literals {
inline namespace string_literals {
// 21.7, 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);
}
}
§ 21.3 640
c
ISO/IEC N????
}
21.4 Class template basic_string [basic.string]
1The 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.
2The 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.236
3The iterators supported by basic_string are random access iterators (24.2.7).
4In all cases, size() <= capacity().
5The functions described in this Clause can report two kinds of errors, each associated with an exception
type:
a length error is associated with exceptions of type length_error (19.2.4);
an out-of-range error is associated with exceptions of type out_of_range (19.2.5).
namespace std {
template<class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> >
class basic_string {
public:
// types:
typedef traits traits_type;
typedef typename traits::char_type value_type;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<Allocator>::difference_type difference_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef implementation-defined iterator; // See 23.2
typedef implementation-defined const_iterator; // See 23.2
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
static const size_type npos = -1;
// 21.4.2, construct/copy/destroy:
explicit basic_string(const Allocator& a = Allocator());
basic_string(const basic_string& str);
basic_string(basic_string&& str) noexcept;
basic_string(const basic_string& str, size_type pos, size_type n = npos,
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,
236) Allocator::value_type must name the same type as charT (21.4.1).
§ 21.4 641
c
ISO/IEC N????
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;
basic_string& operator=(const charT* s);
basic_string& operator=(charT c);
basic_string& operator=(initializer_list<charT>);
// 21.4.3, 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;
// 21.4.4, 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;
// 21.4.5, 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();
// 21.4.6, modifiers:
basic_string& operator+=(const basic_string& str);
basic_string& operator+=(const charT* s);
basic_string& operator+=(charT c);
§ 21.4 642
c
ISO/IEC N????
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);
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;
basic_string& assign(const basic_string& str, size_type pos,
size_type n);
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 pos1, const basic_string& str);
basic_string& insert(size_type pos1, const basic_string& str,
size_type pos2, size_type n);
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);
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, const charT* s,
§ 21.4 643
c
ISO/IEC N????
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);
// 21.4.7, string operations:
const charT* c_str() const noexcept;
const charT* data() const noexcept;
allocator_type get_allocator() 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(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(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 (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(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 (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(const basic_string& str) const noexcept;
§ 21.4 644
c
ISO/IEC N????
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) 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;
};
}
21.4.1 basic_string general requirements [string.require]
1If any operation would cause size() to exceed max_size(), that operation shall throw an exception object
of type length_error.
2If any member function or operator of basic_string throws an exception, that function or operator shall
have no other effect.
3No erase() or pop_back() member function shall throw any exceptions.
4In every specialization basic_string<charT, traits, Allocator>, the type allocator_traits<All-
ocator>::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 23.2.1.
5The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string
object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of nsuch that 0
<= n < s.size().
6References, 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.237
Calling non-const member functions, except operator[],at,front,back,begin,rbegin,end, and
rend.
21.4.2 basic_string constructors and assignment operators [string.cons]
explicit basic_string(const Allocator& a = Allocator());
1Effects: Constructs an object of class basic_string. The postconditions of this function are indicated
in Table 63.
Table 63 — basic_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
237) For example, as an argument to non-member functions swap() (21.4.8.8), operator>>() (21.4.8.9), and
getline() (21.4.8.9), or as an argument to basic_string::swap()
§ 21.4.2 645
c
ISO/IEC N????
basic_string(const basic_string& str);
basic_string(basic_string&& str) noexcept;
2Effects: Constructs an object of class basic_string as indicated in Table 64. In the second form, str
is left in a valid state with an unspecified value.
Table 64 — basic_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, size_type n = npos,
const Allocator& a = Allocator());
3Requires: pos <= str.size()
4Throws: out_of_range if pos > str.size().
5Effects: Constructs an object of class basic_string and determines the effective length rlen of the
initial string value as the smaller of nand str.size() - pos, as indicated in Table 65.
Table 65 — 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()
basic_string(const charT* s, size_type n,
const Allocator& a = Allocator());
6Requires: spoints to an array of at least nelements of charT.
7Effects: Constructs an object of class basic_string and determines its initial string value from the
array of charT of length nwhose first element is designated by s, as indicated in Table 66.
basic_string(const charT* s, const Allocator& a = Allocator());
8Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
9Effects: 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 67.
10 Remarks: Uses traits::length().
§ 21.4.2 646
c
ISO/IEC N????
Table 66 — basic_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()
Table 67 — basic_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());
11 Requires: n < npos
12 Effects: Constructs an object of class basic_string and determines its initial string value by repeating
the char-like object cfor all nelements, as indicated in Table 68.
Table 68 — basic_string(size_t, charT, const Allocator&) effects
Element Value
data() points at the first element of an allocated array of
nelements, 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());
13 Effects: If InputIterator is an integral type, equivalent to
basic_string(static_cast<size_type>(begin), static_cast<value_type>(end), a)
14 Otherwise constructs a string from the values in the range [begin,end), as indicated in the Sequence
Requirements table (see 23.2.3).
basic_string(initializer_list<charT> il, const Allocator& a = Allocator());
15 Effects: Same as basic_string(il.begin(), il.end(), a).
§ 21.4.2 647
c
ISO/IEC N????
basic_string(const basic_string& str, const Allocator& alloc);
basic_string(basic_string&& str, const Allocator& alloc);
16 Effects: Constructs an object of class basic_string as indicated in Table 69. The stored allocator is
constructed from alloc. In the second form, str is left in a valid state with an unspecified value.
Table 69 — basic_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
17 Throws: The second form throws nothing if alloc == str.get_allocator().
basic_string& operator=(const basic_string& str);
18 Effects: If *this and str are not the same object, modifies *this as shown in Table 70.
19 If *this and str are the same object, the member has no effect.
20 Returns: *this
Table 70 — operator=(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;
21 Effects: If *this and str are not the same object, modifies *this as shown in Table 71. [ Note: A
valid implementation is swap(str).— end note ]
22 If *this and str are the same object, the member has no effect.
23 Returns: *this
basic_string& operator=(const charT* s);
24 Returns: *this = basic_string(s).
25 Remarks: Uses traits::length().
§ 21.4.2 648
c
ISO/IEC N????
Table 71 — operator=(basic_string&&) effects
Element Value
data() points at the array whose first element was pointed
at by str.data()
size() previous value of str.size()
capacity() a value at least as large as size()
basic_string& operator=(charT c);
26 Returns: *this = basic_string(1,c).
basic_string& operator=(initializer_list<charT> il);
27 Effects: *this = basic_string(il).
28 Returns: *this.
21.4.3 basic_string iterator support [string.iterators]
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
1Returns: An iterator referring to the first character in the string.
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
2Returns: 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;
3Returns: 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;
4Returns: An iterator which is semantically equivalent to reverse_iterator(begin()).
21.4.4 basic_string capacity [string.capacity]
size_type size() const noexcept;
1Returns: A count of the number of char-like objects currently in the string.
2Complexity: constant time.
§ 21.4.4 649
c
ISO/IEC N????
size_type length() const noexcept;
3Returns: size().
size_type max_size() const noexcept;
4Returns: The size of the largest possible string.
5Complexity: constant time.
void resize(size_type n, charT c);
6Requires: n <= max_size()
7Throws: length_error if n > max_size().
8Effects: 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);
9Effects: resize(n,charT()).
size_type capacity() const noexcept;
10 Returns: The size of the allocated storage in the string.
void reserve(size_type res_arg=0);
11 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.
12 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 ]
13 Throws: length_error if res_arg > max_size().238
void shrink_to_fit();
14 Remarks: 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 ]
void clear() noexcept;
238) reserve() uses allocator_traits<Allocator>::allocate() which may throw an appropriate exception.
§ 21.4.4 650
c
ISO/IEC N????
15 Effects: Behaves as if the function calls:
erase(begin(), end());
bool empty() const noexcept;
16 Returns: size() == 0.
21.4.5 basic_string element access [string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1Requires: pos <= size().
2Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type
charT with value charT(), where modifying the object leads to undefined behavior.
3Throws: Nothing.
4Complexity: constant time.
const_reference at(size_type pos) const;
reference at(size_type pos);
5Throws: out_of_range if pos >= size().
6Returns: operator[](pos).
const charT& front() const;
charT& front();
7Requires: !empty()
8Effects: Equivalent to operator[](0).
const charT& back() const;
charT& back();
9Requires: !empty()
10 Effects: Equivalent to operator[](size() - 1).
21.4.6 basic_string modifiers [string.modifiers]
21.4.6.1 basic_string::operator+= [string::op+=]
basic_string&
operator+=(const basic_string& str);
1Effects: Calls append(str).
2Returns: *this.
basic_string& operator+=(const charT* s);
3Effects: Calls append(s).
4Returns: *this.
§ 21.4.6.1 651
c
ISO/IEC N????
basic_string& operator+=(charT c);
5Effects: Calls push_back(c);
6Returns: *this.
basic_string& operator+=(initializer_list<charT> il);
7Effects: Calls append(il).
8Returns: *this.
21.4.6.2 basic_string::append [string::append]
basic_string&
append(const basic_string& str);
1Effects: Calls append(str.data(), str.size()).
2Returns: *this.
basic_string&
append(const basic_string& str, size_type pos, size_type n);
3Requires: pos <= str.size()
4Throws: out_of_range if pos > str.size().
5Effects: Determines the effective length rlen of the string to append as the smaller of nand str.size()
- pos and calls append(str.data() + pos, rlen).
6Returns: *this.
basic_string&
append(const charT* s, size_type n);
7Requires: spoints to an array of at least nelements of charT.
8Throws: length_error if size() + n > max_size().
9Effects: 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 nelements of s.
10 Returns: *this.
basic_string& append(const charT* s);
11 Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
12 Effects: Calls append(s, traits::length(s)).
13 Returns: *this.
basic_string& append(size_type n, charT c);
14 Effects: Equivalent to append(basic_string(n, c)).
15 Returns: *this.
§ 21.4.6.2 652
c
ISO/IEC N????
template<class InputIterator>
basic_string& append(InputIterator first, InputIterator last);
16 Requires: [first,last) is a valid range.
17 Effects: Equivalent to append(basic_string(first, last)).
18 Returns: *this.
basic_string& append(initializer_list<charT> il);
19 Effects: Calls append(il.begin(), il.size()).
20 Returns: *this.
void push_back(charT c)
21 Effects: Equivalent to append(static_cast<size_type>(1), c).
21.4.6.3 basic_string::assign [string::assign]
basic_string& assign(const basic_string& str);
1Effects: Equivalent to assign(str, 0, npos).
2Returns: *this.
basic_string& assign(basic_string&& str) noexcept;
3Effects: The function replaces the string controlled by *this with a string of length str.size() whose
elements are a copy of the string controlled by str. [ Note: A valid implementation is swap(str).
end note ]
4Returns: *this.
basic_string&
assign(const basic_string& str, size_type pos,
size_type n);
5Requires: pos <= str.size()
6Throws: out_of_range if pos > str.size().
7Effects: Determines the effective length rlen of the string to assign as the smaller of nand str.size()
- pos and calls assign(str.data() + pos rlen).
8Returns: *this.
basic_string& assign(const charT* s, size_type n);
9Requires: spoints to an array of at least nelements of charT.
10 Throws: length_error if n > max_size().
11 Effects: Replaces the string controlled by *this with a string of length nwhose elements are a copy
of those pointed to by s.
12 Returns: *this.
§ 21.4.6.3 653
c
ISO/IEC N????
basic_string& assign(const charT* s);
13 Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
14 Effects: Calls assign(s, traits::length(s)).
15 Returns: *this.
basic_string& assign(initializer_list<charT> il);
16 Effects: Calls assign(il.begin(), il.size()).
17 *this.
basic_string& assign(size_type n, charT c);
18 Effects: Equivalent to assign(basic_string(n, c)).
19 Returns: *this.
template<class InputIterator>
basic_string& assign(InputIterator first, InputIterator last);
20 Effects: Equivalent to assign(basic_string(first, last)).
21 Returns: *this.
21.4.6.4 basic_string::insert [string::insert]
basic_string&
insert(size_type pos1,
const basic_string& str);
1Requires: pos <= size().
2Throws: out_of_range if pos > size().
3Effects: Calls insert(pos, str.data(), str.size()).
4Returns: *this.
basic_string&
insert(size_type pos1,
const basic_string& str,
size_type pos2, size_type n);
5Requires: pos1 <= size() and pos2 <= str.size()
6Throws: out_of_range if pos1 > size() or pos2 > str.size().
7Effects: Determines the effective length rlen of the string to insert as the smaller of nand str.size()
- pos2 and calls insert(pos1, str.data() + pos2, rlen).
8Returns: *this.
basic_string&
insert(size_type pos, const charT* s, size_type n);
§ 21.4.6.4 654
c
ISO/IEC N????
9Requires: spoints to an array of at least nelements of charT and pos <= size().
10 Throws: out_of_range if pos > size() or length_error if size() + n > max_size().
11 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
nelements are a copy of the elements in sand whose remaining elements are a copy of the remaining
elements of the original string controlled by *this.
12 Returns: *this.
basic_string&
insert(size_type pos, const charT* s);
13 Requires: pos <= size() and spoints to an array of at least traits::length(s) + 1 elements of
charT.
14 Effects: Equivalent to insert(pos, s, traits::length(s)).
15 Returns: *this.
basic_string&
insert(size_type pos, size_type n, charT c);
16 Effects: Equivalent to insert(pos, basic_string(n, c)).
17 Returns: *this.
iterator insert(const_iterator p, charT c);
18 Requires: pis a valid iterator on *this.
19 Effects: inserts a copy of cbefore the character referred to by p.
20 Returns: An iterator which refers to the copy of the inserted character.
iterator insert(const_iterator p, size_type n, charT c);
21 Requires: pis a valid iterator on *this.
22 Effects: inserts ncopies of cbefore the character referred to by p.
23 Returns: An iterator which refers to the copy of the first inserted character, or pif n == 0.
template<class InputIterator>
iterator insert(const_iterator p, InputIterator first, InputIterator last);
24 Requires: pis a valid iterator on *this.[first,last) is a valid range.
25 Effects: Equivalent to insert(p - begin(), basic_string(first, last)).
26 Returns: An iterator which refers to the copy of the first inserted character, or pif first == last.
iterator insert(const_iterator p, initializer_list<charT> il);
27 Effects: insert(p, il.begin(), il.end()).
28 Returns: An iterator which refers to the copy of the first inserted character, or pif i1 is empty.
§ 21.4.6.4 655
c
ISO/IEC N????
21.4.6.5 basic_string::erase [string::erase]
basic_string& erase(size_type pos = 0, size_type n = npos);
1Requires: pos <= size()
2Throws: out_of_range if pos > size().
3Effects: Determines the effective length xlen of the string to be removed as the smaller of nand
size() - pos.
4The 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.
5Returns: *this.
iterator erase(const_iterator p);
6Effects: removes the character referred to by p.
7Returns: An iterator which points to the element immediately following pprior to the element being
erased. If no such element exists, end() is returned.
iterator erase(const_iterator first, const_iterator last);
8Requires: first and last are valid iterators on *this, defining a range [first,last).
9Effects: removes the characters in the range [first,last).
10 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();
11 Requires: !empty()
12 Effects: Equivalent to erase(size() - 1, 1).
21.4.6.6 basic_string::replace [string::replace]
basic_string&
replace(size_type pos1, size_type n1,
const basic_string& str);
1Requires: pos1 <= size().
2Throws: out_of_range if pos1 > size().
3Effects: Calls replace(pos1, n1, str.data(), str.size()).
4Returns: *this.
basic_string&
replace(size_type pos1, size_type n1,
const basic_string& str,
size_type pos2, size_type n2);
§ 21.4.6.6 656
c
ISO/IEC N????
5Requires: pos1 <= size() and pos2 <= str.size().
6Throws: out_of_range if pos1 > size() or pos2 > str.size().
7Effects: 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).
8Returns: *this.
basic_string&
replace(size_type pos1, size_type n1, const charT* s, size_type n2);
9Requires: pos1 <= size() and spoints to an array of at least n2 elements of charT.
10 Throws: out_of_range if pos1 > size() or length_error if the length of the resulting string would
exceed max_size() (see below).
11 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 func-
tion 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.
12 Returns: *this.
basic_string&
replace(size_type pos, size_type n, const charT* s);
13 Requires: pos <= size() and spoints to an array of at least traits::length(s) + 1 elements of
charT.
14 Effects: Calls replace(pos, n, s, traits::length(s)).
15 Returns: *this.
basic_string&
replace(size_type pos1, size_type n1,
size_type n2, charT c);
16 Effects: Equivalent to replace(pos1, n1, basic_string(n2, c)).
17 Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
18 Requires: [begin(),i1) and [i1,i2) are valid ranges.
19 Effects: Calls replace(i1 - begin(), i2 - i1, str).
20 Returns: *this.
basic_string&
replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
§ 21.4.6.6 657
c
ISO/IEC N????
21 Requires: [begin(),i1) and [i1,i2) are valid ranges and spoints to an array of at least nelements
of charT.
22 Effects: Calls replace(i1 - begin(), i2 - i1, s, n).
23 Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
24 Requires: [begin(),i1) and [i1,i2) are valid ranges and spoints to an array of at least traits::
length(s) + 1 elements of charT.
25 Effects: Calls replace(i1 - begin(), i2 - i1, s, traits::length(s)).
26 Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, size_type n,
charT c);
27 Requires: [begin(),i1) and [i1,i2) are valid ranges.
28 Effects: Calls replace(i1 - begin(), i2 - i1, basic_string(n, c)).
29 Returns: *this.
template<class InputIterator>
basic_string& replace(const_iterator i1, const_iterator i2,
InputIterator j1, InputIterator j2);
30 Requires: [begin(),i1),[i1,i2) and [j1,j2) are valid ranges.
31 Effects: Calls replace(i1 - begin(), i2 - i1, basic_string(j1, j2)).
32 Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2,
initializer_list<charT> il);
33 Requires: [begin(),i1) and [i1,i2) are valid ranges.
34 Effects: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()).
35 *this.
21.4.6.7 basic_string::copy [string::copy]
size_type copy(charT* s, size_type n, size_type pos = 0) const;
1Requires: pos <= size()
2Throws: out_of_range if pos > size().
3Effects: Determines the effective length rlen of the string to copy as the smaller of nand size() -
pos.sshall designate an array of at least rlen elements.
The function then replaces the string designated by swith a string of length rlen whose elements are
a copy of the string controlled by *this beginning at position pos.
The function does not append a null object to the string designated by s.
4Returns: rlen.
§ 21.4.6.7 658
c
ISO/IEC N????
21.4.6.8 basic_string::swap [string::swap]
void swap(basic_string& s);
1Postcondition: *this contains the same sequence of characters that was in s,scontains the same
sequence of characters that was in *this.
2Throws: Nothing.
3Complexity: constant time.
21.4.7 basic_string string operations [string.ops]
21.4.7.1 basic_string accessors [string.accessors]
const charT* c_str() const noexcept;
const charT* data() const noexcept;
1Returns: A pointer psuch that p + i == &operator[](i) for each iin [0,size()].
2Complexity: constant time.
3Requires: The program shall not alter any of the values stored in the character array.
allocator_type get_allocator() const noexcept;
4Returns: 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.
21.4.7.2 basic_string::find [string::find]
size_type find(const basic_string& str,
size_type pos = 0) const noexcept;
1Effects: Determines the lowest position xpos, if possible, such that both of the following conditions
obtain:
pos <= xpos and xpos + str.size() <= size();
traits::eq(at(xpos+I), str.at(I)) for all elements Iof the string controlled by str.
2Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
3Remarks: Uses traits::eq().
size_type find(const charT* s, size_type pos, size_type n) const;
4Returns: find(basic_string(s,n),pos).
size_type find(const charT* s, size_type pos = 0) const;
5Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
6Returns: find(basic_string(s), pos).
size_type find(charT c, size_type pos = 0) const;
7Returns: find(basic_string(1,c), pos).
§ 21.4.7.2 659
c
ISO/IEC N????
21.4.7.3 basic_string::rfind [string::rfind]
size_type rfind(const basic_string& str,
size_type pos = npos) const noexcept;
1Effects: Determines the highest position xpos, if possible, such that both of the following conditions
obtain:
xpos <= pos and xpos + str.size() <= size();
traits::eq(at(xpos+I), str.at(I)) for all elements Iof the string controlled by str.
2Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
3Remarks: Uses traits::eq().
size_type rfind(const charT* s, size_type pos, size_type n) const;
4Returns: rfind(basic_string(s, n), pos).
size_type rfind(const charT* s, size_type pos = npos) const;
5Requires: s points to an array of at least traits::length(s) + 1 elements of charT.
6Returns: rfind(basic_string(s), pos).
size_type rfind(charT c, size_type pos = npos) const;
7Returns: rfind(basic_string(1,c),pos).
21.4.7.4 basic_string::find_first_of [string::find.first.of]
size_type
find_first_of(const basic_string& str,
size_type pos = 0) const noexcept;
1Effects: Determines the lowest position xpos, if possible, such that both of the following conditions
obtain:
pos <= xpos and xpos < size();
traits::eq(at(xpos), str.at(I)) for some element Iof the string controlled by str.
2Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
3Remarks: Uses traits::eq().
size_type
find_first_of(const charT* s, size_type pos, size_type n) const;
4Returns: find_first_of(basic_string(s, n), pos).
size_type find_first_of(const charT* s, size_type pos = 0) const;
5Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
6Returns: find_first_of(basic_string(s), pos).
size_type find_first_of(charT c, size_type pos = 0) const;
7Returns: find_first_of(basic_string(1,c), pos).
§ 21.4.7.4 660
c
ISO/IEC N????
21.4.7.5 basic_string::find_last_of [string::find.last.of]
size_type
find_last_of(const basic_string& str,
size_type pos = npos) const noexcept;
1Effects: Determines the highest position xpos, if possible, such that both of the following conditions
obtain:
xpos <= pos and xpos < size();
traits::eq(at(xpos), str.at(I)) for some element Iof the string controlled by str.
2Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
3Remarks: Uses traits::eq().
size_type find_last_of(const charT* s, size_type pos, size_type n) const;
4Returns: find_last_of(basic_string(s, n), pos).
size_type find_last_of(const charT* s, size_type pos = npos) const;
5Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
6Returns: find_last_of(basic_string(s), pos).
size_type find_last_of(charT c, size_type pos = npos) const;
7Returns: find_last_of(basic_string(1,c),pos).
21.4.7.6 basic_string::find_first_not_of [string::find.first.not.of]
size_type
find_first_not_of(const basic_string& str,
size_type pos = 0) const noexcept;
1Effects: Determines the lowest position xpos, if possible, such that both of the following conditions
obtain:
pos <= xpos and xpos < size();
traits::eq(at(xpos), str.at(I)) for no element Iof the string controlled by str.
2Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
3Remarks: Uses traits::eq().
size_type
find_first_not_of(const charT* s, size_type pos, size_type n) const;
4Returns: find_first_not_of(basic_string(s, n), pos).
size_type find_first_not_of(const charT* s, size_type pos = 0) const;
§ 21.4.7.6 661
c
ISO/IEC N????
5Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
6Returns: find_first_not_of(basic_string(s), pos).
size_type find_first_not_of(charT c, size_type pos = 0) const;
7Returns: find_first_not_of(basic_string(1, c), pos).
21.4.7.7 basic_string::find_last_not_of [string::find.last.not.of]
size_type
find_last_not_of(const basic_string& str,
size_type pos = npos) const noexcept;
1Effects: Determines the highest position xpos, if possible, such that both of the following conditions
obtain:
xpos <= pos and xpos < size();
traits::eq(at(xpos), str.at(I)) for no element Iof the string controlled by str.
2Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
3Remarks: Uses traits::eq().
size_type find_last_not_of(const charT* s, size_type pos,
size_type n) const;
4Returns: find_last_not_of(basic_string(s, n), pos).
size_type find_last_not_of(const charT* s, size_type pos = npos) const;
5Requires: spoints to an array of at least traits::length(s) + 1 elements of charT.
6Returns: find_last_not_of(basic_string(s), pos).
size_type find_last_not_of(charT c, size_type pos = npos) const;
7Returns: find_last_not_of(basic_string(1, c), pos).
21.4.7.8 basic_string::substr [string::substr]
basic_string substr(size_type pos = 0, size_type n = npos) const;
1Requires: pos <= size()
2Throws: out_of_range if pos > size().
3Effects: Determines the effective length rlen of the string to copy as the smaller of nand size() -
pos.
4Returns: basic_string(data()+pos,rlen).
§ 21.4.7.8 662
c
ISO/IEC N????
Table 72 — compare() results
Condition Return Value
size() < str.size() < 0
size() == str.size() 0
size() > str.size() > 0
21.4.7.9 basic_string::compare [string::compare]
int compare(const basic_string& str) const noexcept;
1Effects: Determines the effective length rlen of the strings to compare as the smallest of size()
and str.size(). The function then compares the two strings by calling traits::compare(data(),
str.data(), rlen).
2Returns: The nonzero result if the result of the comparison is nonzero. Otherwise, returns a value as
indicated in Table 72.
int compare(size_type pos1, size_type n1,
const basic_string& str) const;
3Returns: basic_string(*this,pos1,n1).compare(str).
int compare(size_type pos1, size_type n1,
const basic_string& str,
size_type pos2, size_type n2 ) const;
4Returns: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
int compare(const charT* s) const;
5Returns: compare(basic_string(s)).
int compare(size_type pos, size_type n1,
const charT* s) const;
6Returns: basic_string(*this, pos, n1).compare(basic_string(s)).
int compare(size_type pos, size_type n1,
const charT* s, size_type n2) const;
7Returns: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
21.4.8 basic_string non-member functions [string.nonmembers]
21.4.8.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);
§ 21.4.8.1 663
c
ISO/IEC N????
1Returns: 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);
2Returns: 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);
3Returns: 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);
4Returns: 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);
5Returns: basic_string<charT,traits,Allocator>(lhs) + rhs.
6Remarks: 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);
7Returns: std::move(rhs.insert(0, lhs)).
8Remarks: 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);
9Returns: 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);
§ 21.4.8.1 664
c
ISO/IEC N????
10 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);
11 Returns: lhs + basic_string<charT,traits,Allocator>(rhs).
12 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);
13 Returns: std::move(lhs.append(rhs)).
14 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);
15 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);
16 Returns: std::move(lhs.append(1, rhs)).
21.4.8.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;
1Returns: lhs.compare(rhs) == 0.
template<class charT, class traits, class Allocator>
bool operator==(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
2Returns: rhs == lhs.
template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
3Requires: rhs points to an array of at least traits::length(rhs) + 1 elements of charT.
4Returns: lhs.compare(rhs) == 0.
§ 21.4.8.2 665
c
ISO/IEC N????
21.4.8.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;
1Returns: !(lhs == rhs).
template<class charT, class traits, class Allocator>
bool operator!=(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
2Returns: rhs != lhs.
template<class charT, class traits, class Allocator>
bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
3Requires: rhs points to an array of at least traits::length(rhs) + 1 elements of charT.
4Returns: lhs.compare(rhs) != 0.
21.4.8.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;
1Returns: lhs.compare(rhs) < 0.
template<class charT, class traits, class Allocator>
bool operator< (const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
2Returns: rhs.compare(lhs) > 0.
template<class charT, class traits, class Allocator>
bool operator< (const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
3Returns: lhs.compare(rhs) < 0.
21.4.8.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;
1Returns: lhs.compare(rhs) > 0.
template<class charT, class traits, class Allocator>
bool operator> (const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
2Returns: rhs.compare(lhs) < 0.
§ 21.4.8.5 666
c
ISO/IEC N????
template<class charT, class traits, class Allocator>
bool operator> (const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
3Returns: lhs.compare(rhs) > 0.
21.4.8.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;
1Returns: lhs.compare(rhs) <= 0.
template<class charT, class traits, class Allocator>
bool operator<=(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
2Returns: rhs.compare(lhs) >= 0.
template<class charT, class traits, class Allocator>
bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
3Returns: lhs.compare(rhs) <= 0.
21.4.8.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;
1Returns: lhs.compare(rhs) >= 0.
template<class charT, class traits, class Allocator>
bool operator>=(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
2Returns: rhs.compare(lhs) <= 0.
template<class charT, class traits, class Allocator>
bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
3Returns: lhs.compare(rhs) >= 0.
21.4.8.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);
1Effects: Equivalent to lhs.swap(rhs);
§ 21.4.8.8 667
c
ISO/IEC N????
21.4.8.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);
1Effects: Behaves as a formatted input function (27.7.2.2.1). 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 nis str.max_size(). Characters are extracted and
appended until any of the following occurs:
ncharacters are stored;
end-of-file occurs on the input sequence;
isspace(c,is.getloc()) is true for the next available input character c.
2After the last character (if any) is extracted, is.width(0) is called and the sentry object kis de-
stroyed.
3If the function extracts no characters, it calls is.setstate(ios::failbit), which may throw ios_-
base::failure (27.5.5.4).
4Returns: 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);
5Effects: Behaves as a formatted output function (27.7.3.6.1) 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 27.7.3.6.1. Then inserts seq as if by calling os.rdbuf()->sputn(seq,
n), where nis the larger of os.width() and str.size(); then calls os.width(0).
6Returns: os
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);
7Effects: Behaves as an unformatted input function (27.7.2.3), 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)).
§ 21.4.8.9 668
c
ISO/IEC N????
traits::eq(c, delim) for the next available input character c(in which case, cis extracted but
not appended) (27.5.5.4)
str.max_size() characters are stored (in which case, the function calls is.setstate(ios_base
::failbit)) (27.5.5.4)
8The conditions are tested in the order shown. In any case, after the last character is extracted, the
sentry object kis destroyed.
9If the function extracts no characters, it calls is.setstate(ios_base::failbit) which may throw
ios_base::failure (27.5.5.4).
10 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);
11 Returns: getline(is,str,is.widen(’\n’))
21.5 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);
1Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three func-
tions 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 ar-
gument 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.
2Returns: The converted result.
3Throws: 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);
4Effects: the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold(
str.c_str(), ptr). 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.
5Returns: The converted result.
§ 21.5 669
c
ISO/IEC N????
6Throws: invalid_argument if strtod or strtold reports that no conversion could be performed.
Throws out_of_range if 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);
7Returns: 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);
8Effects: the first two functions call wcstol(str.c_str(), ptr, base), and the last three func-
tions 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 ar-
gument 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.
9Returns: The converted result.
10 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);
11 Effects: the first two functions call wcstod(str.c_str(), ptr) and the third function calls wcstold(
str.c_str(), ptr). 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.
12 Returns: The converted result.
13 Throws: invalid_argument if wcstod or wcstold reports that no conversion could be performed.
Throws out_of_range if wcstod or wcstold sets errno to ERANGE.
§ 21.5 670
c
ISO/IEC N????
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);
14 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.
21.6 Hash support [basic.string.hash]
template <> struct hash<string>;
template <> struct hash<u16string>;
template <> struct hash<u32string>;
template <> struct hash<wstring>;
1The template specializations shall meet the requirements of class template hash (20.10.12).
21.7 Suffix for basic_string literals [basic.string.literals]
string operator "" s(const char* str, size_t len);
1Returns: string{str,len}
u16string operator "" s(const char16_t* str, size_t len);
2Returns: u16string{str,len}
u32string operator "" s(const char32_t* str, size_t len);
3Returns: u32string{str,len}
wstring operator "" s(const wchar_t* str, size_t len);
4Returns: wstring{str,len}
5[Note: The same suffix sis 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 ]
21.8 Null-terminated sequence utilities [c.strings]
1Tables 74,75,76,77,78, and 79 describe headers <cctype>,<cwctype>,<cstring>,<cwchar>,<cstdlib>
(character conversions), and <cuchar>, respectively.
2The contents of these headers shall be the same as the Standard C Library headers <ctype.h>,<wctype.h>,
<string.h>,<wchar.h>, and <stdlib.h> and the C Unicode TR header <uchar.h>, respectively, with the
following modifications:
3The headers shall not define the types char16_t,char32_t, and wchar_t (2.12).
4The function signature strchr(const char*, int) shall be replaced by the two declarations:
§ 21.8 671
c
ISO/IEC N????
const char* strchr(const char* s, int c);
char* strchr( char* s, int c);
both of which shall have the same behavior as the original declaration.
5The function signature strpbrk(const char*, const char*) shall be replaced by the two declarations:
const char* strpbrk(const char* s1, const char* s2);
char* strpbrk( char* s1, const char* s2);
both of which shall have the same behavior as the original declaration.
6The function signature strrchr(const char*, int) shall be replaced by the two declarations:
const char* strrchr(const char* s, int c);
char* strrchr( char* s, int c);
both of which shall have the same behavior as the original declaration.
7The function signature strstr(const char*, const char*) shall be replaced by the two declarations:
const char* strstr(const char* s1, const char* s2);
char* strstr( char* s1, const char* s2);
both of which shall have the same behavior as the original declaration.
8The function signature memchr(const void*, int, size_t) shall be replaced by the two declarations:
const void* memchr(const void* s, int c, size_t n);
void* memchr( void* s, int c, size_t n);
both of which shall have the same behavior as the original declaration.
9The function signature wcschr(const wchar_t*, wchar_t) shall be replaced by the two declarations:
const wchar_t* wcschr(const wchar_t* s, wchar_t c);
wchar_t* wcschr( wchar_t* s, wchar_t c);
both of which shall have the same behavior as the original declaration.
10 The function signature wcspbrk(const wchar_t*, const wchar_t*) shall be replaced by the two declara-
tions:
const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2);
wchar_t* wcspbrk( wchar_t* s1, const wchar_t* s2);
both of which shall have the same behavior as the original declaration.
11 The function signature wcsrchr(const wchar_t*, wchar_t) shall be replaced by the two declarations:
const wchar_t* wcsrchr(const wchar_t* s, wchar_t c);
wchar_t* wcsrchr( wchar_t* s, wchar_t c);
both of which shall have the same behavior as the original declaration.
12 The function signature wcsstr(const wchar_t*, const wchar_t*) shall be replaced by the two declara-
tions:
const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2);
wchar_t* wcsstr( wchar_t* s1, const wchar_t* s2);
both of which shall have the same behavior as the original declaration.
13 The function signature wmemchr(const wwchar_t*, int, size_t) shall be replaced by the two declara-
tions:
const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);
wchar_t* wmemchr( wchar_t* s, wchar_t c, size_t n);
both of which shall have the same behavior as the original declaration.
14 The functions strerror and strtok are not required to avoid data races (17.6.5.9).
15 Calling the functions listed in Table 73 with an mbstate_t* argument of NULL may introduce a data
race (17.6.5.9) with other calls to these functions with an mbstate_t* argument of NULL.
See also: ISO C 7.3, 7.10.7, 7.10.8, and 7.11. Amendment 1 4.4, 4.5, and 4.6.
§ 21.8 672
c
ISO/IEC N????
Table 73 — Potential mbstate_t data races
mbrlen mbrtowc mbsrtowc mbtowc wcrtomb
wcsrtomb wctomb
Table 74 — Header <cctype> synopsis
Type Name(s)
Functions:
isalnum isblank isdigit isprint isupper
tolower isalpha isgraph ispunct isxdigit
toupper iscntrl islower isspace
Table 75 — Header <cwctype> synopsis
Type Name(s)
Macro:WEOF
Types:wctrans_t wctype_t wint_t
Functions:
iswalnum iswctype iswprint iswxdigit wctrans
iswalpha iswdigit iswpunct towctrans wctype
iswblank iswgraph iswspace towlower
iswcntrl iswlower iswupper towupper
Table 76 — Header <cstring> synopsis
Type Name(s)
Macro:NULL <cstring>
Type:size_t <cstring>
Functions:
memchr strcat strcspn strncpy strtok
memcmp strchr strerror strpbrk strxfrm
memcpy strcmp strlen strrchr
memmove strcoll strncat strspn
memset strcpy strncmp strstr
§ 21.8 673
c
ISO/IEC N????
Table 77 — Header <cwchar> synopsis
Type Name(s)
Macros:NULL WCHAR_MAX WCHAR_MIN WEOF
Types:mbstate_t wint_t size_t tm
Functions:
btowc mbsinit vwscanf wcsncpy wcstoull
fgetwc mbsrtowcs wcrtomb wcspbrk wcstoul
fgetws putwchar wcscat wcsrchr wcsxfrm
fputwc putwc wcschr wcsrtombs wctob
fputws swprintf wcscmp wcsspn wmemchr
fwide swscanf wcscoll wcsstr wmemcmp
fwprintf ungetwc wcscpy wcstod wmemcpy
fwscanf vfwprintf wcscspn wcstof wmemmove
getwchar vfwscanf wcsftime wcstok wmemset
getwc vswprintf wcslen wcstold wprintf
mbrlen vswscanf wcsncat wcstoll wscanf
mbrtowc vwprintf wcsncmp wcstol
Table 78 — Header <cstdlib> synopsis
Type Name(s)
Macros:MB_CUR_MAX
Functions:
atof mblen strtof strtoul
atoi mbtowc strtol strtoull
atol mbstowcs strtold wctomb
atoll strtod strtoll wcstombs
Table 79 — Header <cuchar> synopsis
Type Name(s)
Macros:__STDC_UTF_16__
__STDC_UTF_32__
Functions:mbrtoc16 c16rtomb
mbrtoc32 c32rtomb
§ 21.8 674
c
ISO/IEC N????
22 Localization library [localization]
22.1 General [localization.general]
1This 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.
2The following subclauses describe components for locales themselves, the standard facets, and facilities from
the ISO C library, as summarized in Table 80.
Table 80 — Localization library summary
Subclause Header(s)
22.3 Locales <locale>
22.4 Standard locale Categories
22.5 Standard code conversion facets <codecvt>
22.6 C library locales <clocale>
22.2 Header <locale> synopsis [locale.syn]
namespace std {
// 22.3.1, locale:
class locale;
template <class Facet> const Facet& use_facet(const locale&);
template <class Facet> bool has_facet(const locale&) noexcept;
// 22.3.3, 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);
template <class Codecvt, class Elem = wchar_t,
class Wide_alloc = std::allocator<Elem>,
class Byte_alloc = std::allocator<char> > class wstring_convert;
template <class Codecvt, class Elem = wchar_t,
class Tr = char_traits<Elem>> class wbuffer_convert;
// 22.4.1, ctype:
§ 22.2 675
c
ISO/IEC N????
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;
// 22.4.2, 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;
// 22.4.4, collation:
template <class charT> class collate;
template <class charT> class collate_byname;
// 22.4.5, 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;
// 22.4.6, 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;
// 22.4.7, message retrieval:
class messages_base;
template <class charT> class messages;
template <class charT> class messages_byname;
}
1The header <locale> defines classes and declares functions that encapsulate and manipulate the information
peculiar to a locale.239
22.3 Locales [locales]
22.3.1 Class locale [locale]
namespace std {
class locale {
public:
// types:
class facet;
class id;
239) In this subclause, the type name struct tm is an incomplete type that is defined in <ctime>.
§ 22.3.1 676
c
ISO/IEC N????
typedef int category;
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();
};
}
1Class 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.
2Access to the facets of a locale is via two function templates, use_facet<> and has_facet<>.
3[Example: An iostream operator<< might be implemented as:240
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
}
240) Note that in the call to put the stream is implicitly converted to an ostreambuf_iterator<charT,traits>.
§ 22.3.1 677
c
ISO/IEC N????
return s;
}
— end example ]
4In 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 (22.4.8).
5[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 collec-
tions, 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 (27.7.2.2).) — end note ]
6Once 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.
7In successive calls to a locale facet member function on a facet object installed in the same locale, the
returned result shall be identical.
8Alocale 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 "*".
9Whether 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 (17.6.5.9).
22.3.1.1 locale types [locale.types]
22.3.1.1.1 Type locale::category [locale.category]
typedef int category;
1Valid 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 Xand Yeach
represent a single category, represents the union of the two categories.
2locale 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 81.
3For any locale loc either constructed, or returned by locale::classic(), and any facet Facet shown in
Table 81,has_facet<Facet>(loc) is true. Each locale member function which takes a locale::category
argument operates on the corresponding set of facets.
4An implementation is required to provide those specializations for facet templates identified as members of
a category, and for those shown in Table 82.
5The provided implementation of members of facets num_get<charT> and num_put<charT> calls use_fac-
et <F> (l) only for facet Fof types numpunct<charT> and ctype<charT>, and for locale lthe value obtained
by calling member getloc() on the ios_base& argument to these functions.
§ 22.3.1.1.1 678
c
ISO/IEC N????
Table 81 — 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>
Table 82 — 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>
§ 22.3.1.1.1 679
c
ISO/IEC N????
6In declarations of facets, a template formal parameter with name InputIterator or OutputIterator indi-
cates the set of all possible specializations on parameters that satisfy the requirements of an Input Iterator
or an Output Iterator, respectively (24.2). A template formal parameter with name Crepresents the set of
types containing char,wchar_t, and any other implementation-defined character types that satisfy the re-
quirements for a character on which any of the iostream components can be instantiated. A template formal
parameter with name International represents the set of all possible specializations on a bool parameter.
22.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;
};
}
1Template 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.
2The refs argument to the constructor is used for lifetime management.
For refs == 0, the implementation performs delete static_cast<locale::facet*>(f) (where fis
a pointer to the facet) when the last locale object containing the facet is destroyed; for refs == 1,
the implementation never destroys the facet.
3Constructors 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.
4For 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.
22.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;
};
}
1The class locale::id provides identification of a locale facet interface, used as an index for lookup and to
encapsulate initialization.
2[Note: Because facets are used by iostreams, potentially while static constructors are running, their ini-
tialization cannot depend on programmed static initialization. One initialization strategy is for locale to
§ 22.3.1.1.3 680
c
ISO/IEC N????
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 (3.6.2). — end note ]
22.3.1.2 locale constructors and destructor [locale.cons]
locale() noexcept;
1Default constructor: a snapshot of the current global locale.
2Effects: 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;
3Effects: Constructs a locale which is a copy of other.
explicit locale(const char* std_name);
4Effects: Constructs a locale using standard C locale names, e.g., "POSIX". The resulting locale imple-
ments semantics defined to be associated with that name.
5Throws: runtime_error if the argument is not valid, or is null.
6Remarks: The set of valid string argument values is "C","", and any implementation-defined values.
explicit locale(const string& std_name);
7Effects: The same as locale(std_name.c_str()).
locale(const locale& other, const char* std_name, category);
8Effects: 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).
9Throws: runtime_error if the argument is not valid, or is null.
10 Remarks: The locale has a name if and only if other has a name.
locale(const locale& other, const string& std_name, category cat);
11 Effects: The same as locale(other, std_name.c_str(), cat).
template <class Facet> locale(const locale& other, Facet* f);
12 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 fis null, the resulting object is a copy of
other.
13 Remarks: The resulting locale has no name.
locale(const locale& other, const locale& one, category cats);
§ 22.3.1.2 681
c
ISO/IEC N????
14 Effects: Constructs a locale incorporating all facets from the first argument except those that imple-
ment cats, which are instead incorporated from the second argument.
15 Remarks: The resulting locale has a name if and only if the first two arguments have names.
const locale& operator=(const locale& other) noexcept;
16 Effects: Creates a copy of other, replacing the current value.
17 Returns: *this
~locale();
18 A non-virtual destructor that throws no exceptions.
22.3.1.3 locale members [locale.members]
template <class Facet> locale combine(const locale& other) const;
1Effects: Constructs a locale incorporating all facets from *this except for that one facet of other that
is identified by Facet.
2Returns: The newly created locale.
3Throws: runtime_error if has_facet<Facet>(other) is false.
4Remarks: The resulting locale has no name.
basic_string<char> name() const;
5Returns: The name of *this, if it has one; otherwise, the string "*". If *this has a name, then
locale(name().c_str()) is equivalent to *this. Details of the contents of the resulting string are
otherwise implementation-defined.
22.3.1.4 locale operators [locale.operators]
bool operator==(const locale& other) const;
1Returns: 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;
2Returns: The result of the expression: !(*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;
3Effects: Compares two strings according to the collate<charT> facet.
4Remarks: This member operator template (and therefore locale itself) satisfies requirements for a
comparator predicate template argument (Clause 25) applied to strings.
5Returns: The result of the following expression:
use_facet< collate<charT> >(*this).compare
(s1.data(), s1.data()+s1.size(), s2.data(), s2.data()+s2.size()) < 0;
§ 22.3.1.4 682
c
ISO/IEC N????
6[Example: A vector of strings vcan be collated according to collation rules in locale loc simply
by (25.4.1,23.3.7):
std::sort(v.begin(), v.end(), loc);
— end example ]
22.3.1.5 locale static members [locale.statics]
static locale global(const locale& loc);
1Sets the global locale to its argument.
2Effects: Causes future calls to the constructor locale() to return a copy of the argument. If the
argument has a name, does
std::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 22.6 for data race
considerations when setlocale is invoked. — end note ]
3Returns: The previous value of locale().
static const locale& classic();
4The "C" locale.
5Returns: A locale that implements the classic "C" locale semantics, equivalent to the value locale("C").
6Remarks: This locale, its facets, and their member functions, do not change with time.
22.3.2 locale globals [locale.global.templates]
template <class Facet> const Facet& use_facet(const locale& loc);
1Requires: Facet is a facet class whose definition contains the public static member id as defined
in 22.3.1.1.2.
2Returns: A reference to the corresponding facet of loc, if present.
3Throws: bad_cast if has_facet<Facet>(loc) is false.
4Remarks: 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;
5Returns: True if the facet requested is present in loc; otherwise false.
22.3.3 Convenience interfaces [locale.convenience]
22.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);
§ 22.3.3.1 683
c
ISO/IEC N????
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);
1Each of these functions isFreturns the result of the expression:
use_facet< ctype<charT> >(loc).is(ctype_base::F, c)
where Fis the ctype_base::mask value corresponding to that function (22.4.1).241
22.3.3.2 Conversions [conversions]
22.3.3.2.1 Character conversions [conversions.character]
template <class charT> charT toupper(charT c, const locale& loc);
1Returns: use_facet<ctype<charT> >(loc).toupper(c).
template <class charT> charT tolower(charT c, const locale& loc);
2Returns: use_facet<ctype<charT> >(loc).tolower(c).
22.3.3.2.2 string conversions [conversions.string]
1Class 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 ]
2Class template wstring_convert synopsis
namespace std {
template<class Codecvt, class Elem = wchar_t,
class Wide_alloc = std::allocator<Elem>,
class Byte_alloc = std::allocator<char> > class wstring_convert {
public:
typedef std::basic_string<char, char_traits<char>, Byte_alloc> byte_string;
typedef std::basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
typedef typename Codecvt::state_type state_type;
typedef typename wide_string::traits_type::int_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;
241) 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.
§ 22.3.3.2.2 684
c
ISO/IEC N????
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
};
}
3The class template describes an object that controls conversions between wide string objects of class
std::basic_string<Elem, char_traits<Elem>, Wide_alloc> and byte string objects of class std::
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 val-
ues (stored in a wide_string object) and multibyte sequences (stored in a byte_string object) is per-
formed by an object of class Codecvt, which meets the requirements of the standard code-conversion facet
std::codecvt<Elem, char, std::mbstate_t>.
4An 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
typedef std::basic_string<char, char_traits<char>, Byte_alloc> byte_string;
5The type shall be a synonym for std::basic_string<char, char_traits<char>, Byte_alloc>
size_t converted() const noexcept;
6Returns: 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);
§ 22.3.3.2.2 685
c
ISO/IEC N????
7Effects: 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.
8In 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.
9Returns: 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 std::range_error.
typedef typename wide_string::traits_type::int_type int_type;
The type shall be a synonym for wide_string::traits_type::int_type.
state_type state() const;
10 returns cvtstate.
typedef typename Codecvt::state_type state_type;
11 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);
12 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.
13 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.
14 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 std::range_error.
typedef std::basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
15 The type shall be a synonym for std::basic_string<Elem, char_traits<Elem>, Wide_alloc>.
§ 22.3.3.2.2 686
c
ISO/IEC N????
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());
16 Requires: For the first and second constructors, pcvt != nullptr.
17 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();
18 Effects: The destructor shall delete cvtptr.
22.3.3.2.3 Buffer conversions [conversions.buffer]
1Class 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.
2Class template wbuffer_convert synopsis
namespace std {
template<class Codecvt,
class Elem = wchar_t,
class Tr = std::char_traits<Elem> >
class wbuffer_convert
: public std::basic_streambuf<Elem, Tr> {
public:
typedef typename Codecvt::state_type state_type;
explicit wbuffer_convert(std::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;
std::streambuf* rdbuf() const;
std::streambuf* rdbuf(std::streambuf* bytebuf);
state_type state() const;
private:
std::streambuf* bufptr; // exposition only
Codecvt* cvtptr; // exposition only
state_type cvtstate; // exposition only
};
}
§ 22.3.3.2.3 687
c
ISO/IEC N????
3The 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 std::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 std::codecvt<Elem,
char, std::mbstate_t>.
4An 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;
5Returns: cvtstate.
std::streambuf* rdbuf() const;
6Returns: bufptr.
std::streambuf* rdbuf(std::streambuf* bytebuf);
7Effects: stores bytebuf in bufptr.
8Returns: The previous value of bufptr.
typedef typename Codecvt::state_type state_type;
9The type shall be a synonym for Codecvt::state_type.
explicit wbuffer_convert(std::streambuf* bytebuf = 0,
Codecvt* pcvt = new Codecvt, state_type state = state_type());
10 Requires: pcvt != nullptr.
11 Effects: The constructor constructs a stream buffer object, initializes bufptr to bytebuf, initializes
cvtptr to pcvt, and initializes cvtstate to state.
~wbuffer_convert();
12 Effects: The destructor shall delete cvtptr.
§ 22.3.3.2.3 688
c
ISO/IEC N????
22.4 Standard locale categories [locale.categories]
1Each 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(), respec-
tively. Each such member function takes an ios_base& argument whose members flags(),precision(),
and width(), specify the format of the corresponding datum (27.5.3). 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.
2The 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.
3Within this clause it is unspecified whether one virtual function calls another virtual function.
22.4.1 The ctype category [category.ctype]
namespace std {
class ctype_base {
public:
typedef Tmask;
// 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;
};
}
1The type mask is a bitmask type (17.5.2.1.3).
22.4.1.1 Class template ctype [locale.ctype]
namespace std {
template <class charT>
class ctype : public locale::facet, public ctype_base {
public:
typedef charT char_type;
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;
§ 22.4.1.1 689
c
ISO/IEC N????
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*, 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;
};
}
1Class ctype encapsulates the C library <cctype> features. istream members are required to use ctype<>
for character classing during input parsing.
2The specializations required in Table 81 (22.3.1.1.1), namely ctype<char> and ctype<wchar_t>, implement
character classing appropriate to the implementation’s native character set.
22.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;
1Returns: do_is(m,c) or do_is(low,high,vec)
const charT* scan_is(mask m,
const charT* low, const charT* high) const;
2Returns: do_scan_is(m,low,high)
const charT* scan_not(mask m,
const charT* low, const charT* high) const;
3Returns: do_scan_not(m,low,high)
charT toupper(charT) const;
const charT* toupper(charT* low, const charT* high) const;
§ 22.4.1.1.1 690
c
ISO/IEC N????
4Returns: do_toupper(c) or do_toupper(low,high)
charT tolower(charT c) const;
const charT* tolower(charT* low, const charT* high) const;
5Returns: 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;
6Returns: do_widen(c) or do_widen(low,high,to)
char narrow(charT c, char dfault) const;
const charT* narrow(const charT* low, const charT*, char dfault,
char* to) const;
7Returns: do_narrow(c,dfault) or do_narrow(low,high,dfault,to)
22.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;
1Effects: Classifies a character or sequence of characters. For each argument character, identifies a
value Mof type ctype_base::mask. The second form identifies a value Mof type ctype_base::mask
for each *p where (low<=p && p<high), and places it into vec[p-low].
2Returns: 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;
3Effects: Locates a character in a buffer that conforms to a classification m.
4Returns: The smallest pointer pin 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;
5Effects: Locates a character in a buffer that fails to conform to a classification m.
6Returns: 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;
7Effects: 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.
8Returns: 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.
§ 22.4.1.1.2 691
c
ISO/IEC N????
charT do_tolower(charT c) const;
const charT* do_tolower(charT* low, const charT* high) const;
9Effects: 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.
10 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;
11 Effects: Applies the simplest reasonable transformation from a char value or sequence of char values
to the corresponding charT value or values.242 The only characters for which unique transformations
are required are those in the basic source character set (2.3).
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.243
The second form transforms each character *p in the range [low,high), placing the result in dest[p-low].
12 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;
13 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 cin the basic source character set (2.3) 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].
14 Returns: The first form returns the transformed value; or dfault if no mapping is readily available.
The second form returns high.
242) The char argument of do_widen is intended to accept values derived from character literals for conversion to the locale’s
encoding.
243) In other words, the transformed character is not a member of any character classification that cis not also a member of.
§ 22.4.1.1.2 692
c
ISO/IEC N????
22.4.1.2 Class template ctype_byname [locale.ctype.byname]
namespace std {
template <class charT>
class ctype_byname : public ctype<charT> {
public:
typedef typename ctype<charT>::mask mask;
explicit ctype_byname(const char*, size_t refs = 0);
explicit ctype_byname(const string&, size_t refs = 0);
protected:
~ctype_byname();
};
}
22.4.1.3 ctype specializations [facet.ctype.special]
namespace std {
template <> class ctype<char>
: public locale::facet, public ctype_base {
public:
typedef char char_type;
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;
§ 22.4.1.3 693
c
ISO/IEC N????
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;
};
}
1A specialization ctype<char> is provided so that the member functions on type char can be implemented
inline.244 The implementation-defined value of member table_size is at least 256.
22.4.1.3.1 ctype<char> destructor [facet.ctype.char.dtor]
~ctype();
1Effects: If the constructor’s first argument was nonzero, and its second argument was true, does delete
[] table().
22.4.1.3.2 ctype<char> members [facet.ctype.char.members]
1In the following member descriptions, for unsigned char values vwhere 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);
2Requires: tbl either 0 or an array of at least table_size elements.
3Effects: 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;
4Effects: The second form, for all *p in the range [low,high), assigns into vec[p-low] the value
table()[ (unsigned char)*p].
5Returns: 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;
6Returns: The smallest pin 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;
244) 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>.
§ 22.4.1.3.2 694
c
ISO/IEC N????
7Returns: The smallest pin 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;
8Returns: do_toupper(c) or do_toupper(low,high), respectively.
char tolower(char c) const;
const char* tolower(char* low, const char* high) const;
9Returns: 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;
10 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;
11 Returns: do_narrow(c, dfault) or do_narrow(low, high, dfault, to), respectively.
const mask* table() const noexcept;
12 Returns: The first constructor argument, if it was non-zero, otherwise classic_table().
22.4.1.3.3 ctype<char> static members [facet.ctype.char.statics]
static const mask* classic_table() noexcept;
1Returns: A pointer to the initial element of an array of size table_size which represents the classifi-
cations of characters in the "C" locale.
22.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;
§ 22.4.1.3.4 695
c
ISO/IEC N????
These functions are described identically as those members of the same name in the ctype class tem-
plate (22.4.1.1.1).
22.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:
typedef internT intern_type;
typedef externT extern_type;
typedef stateT state_type;
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;
};
}
1The 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.
§ 22.4.1.4 696
c
ISO/IEC N????
2The stateT argument selects the pair of character encodings being mapped between.
3The specializations required in Table 81 (22.3.1.1.1) 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.
22.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;
1Returns: 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;
2Returns: 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;
3Returns: do_in(state, from, from_end, from_next, to, to_end, to_next)
int encoding() const noexcept;
4Returns: do_encoding()
bool always_noconv() const noexcept;
5Returns: do_always_noconv()
int length(stateT& state, const externT* from, const externT* from_end,
size_t max) const;
6Returns: do_length(state, from,from_end,max)
int max_length() const noexcept;
7Returns: do_max_length()
§ 22.4.1.4.1 697
c
ISO/IEC N????
22.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;
1Requires: (from<=from_end && to<=to_end) well-defined and true;state initialized, if at the be-
ginning of a sequence, or else equal to the result of converting the preceding characters in the sequence.
2Effects: 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).
3Acodecvt facet that is used by basic_filebuf (27.9) 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.245 [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 ]
4Remarks: 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 ]
5Returns: An enumeration value, as summarized in Table 83.
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;
245) 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.
§ 22.4.1.4.2 698
c
ISO/IEC N????
Table 83 — do_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 in-
put sequence is identical to converted sequence
6Requires: (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.
7Effects: Places characters starting at to that should be appended to terminate a sequence when the
current stateT is given by state.246 Stores no more than (to_end-to) destination elements, and
leaves the to_next pointer pointing one beyond the last element successfully stored.
8Returns: An enumeration value, as summarized in Table 84.
Table 84 — do_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;
9Returns:-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.247
bool do_always_noconv() const noexcept;
10 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;
246) Typically these will be characters to return the state to stateT()
247) 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.
§ 22.4.1.4.2 699
c
ISO/IEC N????
11 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.
12 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.
13 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;
14 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.
22.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();
};
}
22.4.2 The numeric category [category.numeric]
1The classes num_get<> and num_put<> handle numeric formatting and parsing. Virtual functions are pro-
vided for several numeric types. Implementations may (but are not required to) delegate extraction of
smaller types to extractors for larger types.248
2All specifications of member functions for num_put and num_get in the subclauses of 22.4.2 only apply to the
specializations required in Tables 81 and 82 (22.3.1.1.1), 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 (22.4), 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.
3Extractor and inserter members of the standard iostreams use num_get<> and num_put<> member functions
for formatting and parsing numeric values (27.7.2.2.1,27.7.3.6.1).
22.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:
typedef charT char_type;
typedef InputIterator iter_type;
248) Parsing "-1" correctly into, e.g., an unsigned short requires that the corresponding member get() at least extract the
sign before delegating.
§ 22.4.2.1 700
c
ISO/IEC N????
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;
};
}
§ 22.4.2.1 701
c
ISO/IEC N????
1The facet num_get is used to parse numeric values from an input sequence such as an istream.
22.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;
1Returns: do_get(in, end, str, err, val).
22.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;
1Effects: 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().
2The details of this operation occur in three stages
Stage 1: Determine a conversion specifier
§ 22.4.2.1.2 702
c
ISO/IEC N????
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
3The 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 85. The table is ordered. That is, the first line whose condition is true applies.
Table 85 — 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 86.
Table 86 — 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;
§ 22.4.2.1.2 703
c
ISO/IEC N????
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 cis 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 floating-point value, the function strtold.
The numeric value to be stored can be one of:
zero, if the conversion function fails to convert the entire field. ios_base::failbit is assigned
to err.
the most positive representable value, if the field represents a value too large positive to be
represented in val.ios_base::failbit is assigned to err.
the most negative representable value or zero for an unsigned integer type, if the field repre-
sents a value too large negative to be represented in val.ios_base::failbit is assigned to
err.
the converted value, otherwise.
The resultant numeric value is stored in val.
4Digit grouping is checked. That is, the positions of discarded separators is examined for consis-
tency with use_facet<numpunct<charT> >(loc).grouping(). If they are not consistent then ios_-
base::failbit is assigned to err.
5In 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;
6Effects: 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.
7Otherwise 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 23.2.3) 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.
§ 22.4.2.1.2 704
c
ISO/IEC N????
8The 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 ]
9Returns: in.
22.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:
typedef charT char_type;
typedef OutputIterator iter_type;
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,
§ 22.4.2.2 705
c
ISO/IEC N????
const void* v) const;
};
}
1The facet num_put is used to format numeric values to a character sequence such as an ostream.
22.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;
1Returns: do_put(out, str, fill, val).
22.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;
1Effects: Writes characters to the sequence out, formatting val as desired. In the following description,
a local variable initialized with
locale loc = str.getloc();
2The details of this operation occur in several stages:
Stage 1: Determine a printf conversion specifier spec and determining the characters that would
be printed by printf (27.9.2) 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())
§ 22.4.2.2.2 706
c
ISO/IEC N????
Stage 3: Determine where padding is required.
Stage 4: Insert the sequence into the out.
3Detailed descriptions of each stage follow.
4Returns: out.
5
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));
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 87.
Table 87 — 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 88.
Table 88 — 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 89.
The conversion specifier has the following optional additional qualifiers prepended as indicated in
Table 90.
§ 22.4.2.2.2 707
c
ISO/IEC N????
Table 89 — Length modifier
Type Length modifier
long l
long long ll
unsigned long l
unsigned long long ll
long double L
otherwise none
Table 90 — Numeric conversions
Type(s) State stdio equivalent
an integral type flags & showpos +
flags & showbase #
a floating-point type flags & showpos +
flags & 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. Other-
wise, 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 sis the conversion specifier determined above.
Stage 2: Any character cother 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 deter-
mined by the value returned by punct.do_grouping() using the method described in 22.4.3.1.2
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 padding249 is determined according to Table 91.
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;
249) The conversion specification #o generates a leading 0which is not a padding character.
§ 22.4.2.2.2 708
c
ISO/IEC N????
Table 91 — 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
6Returns: If (str.flags() & ios_base::boolalpha) == 0 returns do_put(out, str, fill,
(int)val), otherwise obtains a string sas if by
string_type s =
val ? use_facet<ctype<charT> >(loc).truename()
: use_facet<ctype<charT> >(loc).falsename();
and then inserts each character cof sinto out via *out++ = c and returns out.
22.4.3 The numeric punctuation facet [facet.numpunct]
22.4.3.1 Class template numpunct [locale.numpunct]
namespace std {
template <class charT>
class numpunct : public locale::facet {
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
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
};
}
1numpunct<> specifies numeric punctuation. The specializations required in Table 81 (22.3.1.1.1), namely
numpunct<wchar_t> and numpunct<char>, provide classic "C" numeric formats, i.e., they contain informa-
tion equivalent to that contained in the "C" locale or their wide character counterparts as if obtained by a
call to widen.
§ 22.4.3.1 709
c
ISO/IEC N????
2The 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.
22.4.3.1.1 numpunct members [facet.numpunct.members]
char_type decimal_point() const;
1Returns: do_decimal_point()
char_type thousands_sep() const;
2Returns: do_thousands_sep()
string grouping() const;
3Returns: do_grouping()
string_type truename() const;
string_type falsename() const;
4Returns: do_truename() or do_falsename(), respectively.
22.4.3.1.2 numpunct virtual functions [facet.numpunct.virtuals]
char_type do_decimal_point() const;
1Returns: A character for use as the decimal radix separator. The required specializations return ’.’
or L’.’.
char_type do_thousands_sep() const;
2Returns: A character for use as the digit group separator. The required specializations return ’,’ or
L’,’.
string do_grouping() const;
§ 22.4.3.1.2 710
c
ISO/IEC N????
3Returns: A basic_string<char> vec used as a vector of integer values, in which each element vec[i]
represents the number of digits250 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.
4The required specializations return the empty string, indicating no grouping.
string_type do_truename() const;
string_type do_falsename() const;
5Returns: A string representing the name of the boolean value true or false, respectively.
6In the base class implementation these names are "true" and "false", or L"true" and L"false".
22.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:
typedef charT char_type;
typedef basic_string<charT> string_type;
explicit numpunct_byname(const char*, size_t refs = 0);
explicit numpunct_byname(const string&, size_t refs = 0);
protected:
~numpunct_byname();
};
}
22.4.4 The collate category [category.collate]
22.4.4.1 Class template collate [locale.collate]
namespace std {
template <class charT>
class collate : public locale::facet {
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
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;
250) 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".
§ 22.4.4.1 711
c
ISO/IEC N????
virtual string_type do_transform(const charT* low, const charT* high) const;
virtual long do_hash (const charT* low, const charT* high) const;
};
}
1The 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 25) and containers operating on strings. The
specializations required in Table 81 (22.3.1.1.1), namely collate<char> and collate<wchar_t>, apply
lexicographic ordering (25.4.8).
2Each function compares a string of characters *p in the range [low,high).
22.4.4.1.1 collate members [locale.collate.members]
int compare(const charT* low1, const charT* high1,
const charT* low2, const charT* high2) const;
1Returns: do_compare(low1, high1, low2, high2)
string_type transform(const charT* low, const charT* high) const;
2Returns: do_transform(low, high)
long hash(const charT* low, const charT* high) const;
3Returns: do_hash(low, high)
22.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;
1Returns: 1if the first string is greater than the second, -1 if less, zero otherwise. The specializa-
tions required in Table 81 (22.3.1.1.1), namely collate<char> and collate<wchar_t>, implement a
lexicographical comparison (25.4.8).
string_type do_transform(const charT* low, const charT* high) const;
2Returns: Abasic_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.251
long do_hash(const charT* low, const charT* high) const;
3Returns: 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 ]
251) This function is useful when one string is being compared to many other strings.
§ 22.4.4.1.2 712
c
ISO/IEC N????
22.4.4.2 Class template collate_byname [locale.collate.byname]
namespace std {
template <class charT>
class collate_byname : public collate<charT> {
public:
typedef basic_string<charT> string_type;
explicit collate_byname(const char*, size_t refs = 0);
explicit collate_byname(const string&, size_t refs = 0);
protected:
~collate_byname();
};
}
22.4.5 The time category [category.time]
1Templates 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 22.4.5 only apply to the specializations required in Tables 81 and 82 (22.3.1.1.1). Their
members use their ios_base&,ios_base::iostate&, and fill arguments as described in (22.4), and the
ctype<> facet, to determine formatting details.
22.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:
typedef charT char_type;
typedef InputIterator iter_type;
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;
§ 22.4.5.1 713
c
ISO/IEC N????
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;
};
}
1time_get is used to parse a character sequence, extracting components of a time or date into a struct
tm record. 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.252
2If the end iterator is reached during parsing by any of the get() member functions, the member sets ios_-
base::eofbit in err.
22.4.5.1.1 time_get members [locale.time.get.members]
dateorder date_order() const;
1Returns: do_date_order()
iter_type get_time(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
2Returns: 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;
3Returns: 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;
4Returns: 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;
252) 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.
§ 22.4.5.1.1 714
c
ISO/IEC N????
5Returns: 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;
6Returns: 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;
7Requires: [fmt,fmtend) shall be a valid range.
8Effects: The function starts by evaluating err = ios_base::goodbit. It then enters a loop, reading
zero or more characters from sat 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 suntil s == end || !isspace(*s, f.getloc()) is true, and finally resumes looping.
The next character read from smatches 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.
9[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 ]
10 Returns: s
22.4.5.1.2 time_get virtual functions [locale.time.get.virtuals]
dateorder do_date_order() const;
1Returns: An enumeration value indicating the preferred order of components for those date formats
that are composed of day, month, and year.253 Returns no_order if the date format specified by ’x’
contains other variable components (e.g., Julian day, week number, week day).
253) This function is intended as a convenience only, for common formats, and may return no_order in valid locales.
§ 22.4.5.1.2 715
c
ISO/IEC N????
iter_type do_get_time(iter_type s, iter_type end, ios_base& str,
ios_base::iostate& err, tm* t) const;
2Effects: Reads characters starting at suntil 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.
3Returns: 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;
4Effects: Reads characters starting at suntil 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 92.
Table 92 — do_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"
5An implementation may also accept additional implementation-defined formats.
6Returns: 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;
7Effects: Reads characters starting at suntil 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.
8Returns: 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;
9Effects: Reads characters starting at suntil 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.
10 Returns: An iterator pointing immediately beyond the last character recognized as part of a valid year
identifier.
§ 22.4.5.1.2 716
c
ISO/IEC N????
iter_type do_get(iter_type s, iter_type end, ios_base& f,
ios_base::iostate& err, tm* t, char format, char modifier) const;
11 Requires: tshall point to an object.
12 Effects: The function starts by evaluating err = ios_base::goodbit. It then reads characters start-
ing at suntil 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 tunchanged and evaluates err |= ios_base::failbit.
When s == end evaluates to true after reading a character the function evaluates err |= ios_-
base::eofbit.
13 For complex conversion directives such as %c,%x, or %X, or directives that involve the optional modifiers
Eor 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.
14 Remark: 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.
15 Returns: An iterator pointing immediately beyond the last character recognized as possibly part of a
valid input sequence for the given format and modifier.
22.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:
typedef time_base::dateorder dateorder;
typedef InputIterator iter_type;
explicit time_get_byname(const char*, size_t refs = 0);
explicit time_get_byname(const string&, size_t refs = 0);
protected:
~time_get_byname();
};
}
22.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:
typedef charT char_type;
typedef OutputIterator iter_type;
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,
§ 22.4.5.3 717
c
ISO/IEC N????
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;
};
}
22.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;
1Effects: 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 simmediately, 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 cto 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 mod254
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).
2The second form calls do_put(s, str, fill, t, format, modifier).
3[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 ]
4Returns: An iterator pointing immediately after the last character produced.
22.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;
1Effects: Formats the contents of the parameter tinto 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()255, except that the
sequence of characters produced for those specifiers that are described as depending on the C locale
are instead implementation-defined.256
2Returns: An iterator pointing immediately after the last character produced. [ Note: The fill argu-
ment may be used in the implementation-defined formats or by derivations. A space character is a
reasonable default for this argument. — end note ]
22.4.5.4 Class template time_put_byname [locale.time.put.byname]
namespace std {
template <class charT, class OutputIterator = ostreambuf_iterator<charT> >
254) Although the C programming language defines no modifiers, most vendors do.
255) Interpretation of the modifier argument is implementation-defined, but should follow POSIX conventions.
256) Implementations are encouraged to refer to other standards such as POSIX for these definitions.
§ 22.4.5.4 718
c
ISO/IEC N????
class time_put_byname : public time_put<charT, OutputIterator>
{
public:
typedef charT char_type;
typedef OutputIterator iter_type;
explicit time_put_byname(const char*, size_t refs = 0);
explicit time_put_byname(const string&, size_t refs = 0);
protected:
~time_put_byname();
};
}
22.4.6 The monetary category [category.monetary]
1These templates handle monetary formats. A template parameter indicates whether local or international
monetary formats are to be used.
2All specifications of member functions for money_put and money_get in the subclauses of 22.4.6 only apply
to the specializations required in Tables 81 and 82 (22.3.1.1.1). Their members use their ios_base&,ios_-
base :: iostate&, and fill arguments as described in (22.4), and the moneypunct<> and ctype<> facets,
to determine formatting details.
22.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:
typedef charT char_type;
typedef InputIterator iter_type;
typedef basic_string<charT> string_type;
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;
};
}
22.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,
§ 22.4.6.1.1 719
c
ISO/IEC N????
long double& quant) const;
iter_type get(s, iter_type end, bool intl, ios_base&f,
ios_base::iostate& err, string_type& quant) const;
1Returns: do_get(s, end, intl, f, err, quant)
22.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;
1Effects: Reads characters from sto parse and construct a monetary value according to the for-
mat specified by a moneypunct<charT,Intl> facet reference mp and the character mapping spec-
ified 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 pre-
ceded by a minus sign (as produced by ct.widen(c) where cis ’-’ 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.
2Where 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.
3If 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.
4Digits 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 by257
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);
257) The semantics here are different from ct.narrow.
§ 22.4.6.1.2 720
c
ISO/IEC N????
where nis 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);
5Returns: An iterator pointing immediately beyond the last character recognized as part of a valid
monetary quantity.
22.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:
typedef charT char_type;
typedef OutputIterator iter_type;
typedef basic_string<charT> string_type;
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;
};
}
22.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;
1Returns: do_put(s, intl, f, loc, quant)
22.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;
1Effects: Writes characters to saccording 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
§ 22.4.6.2.2 721
c
ISO/IEC N????
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 subse-
quent 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).
2Remarks: 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 speci-
fied 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 ]
3Returns: An iterator pointing immediately after the last character produced.
22.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:
typedef charT char_type;
typedef basic_string<charT> string_type;
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();
§ 22.4.6.3 722
c
ISO/IEC N????
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;
};
}
1The 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 format258 In the field member of
apattern 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.
2Where 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.
3The 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 cin 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 cfor 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().
4The placement of thousands-separator characters (if any) is determined by the value returned by grouping(),
defined identically as the member numpunct<>::do_grouping().
22.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;
258) An array of char, rather than an array of part, is specified for pattern::field purely for efficiency.
§ 22.4.6.3.1 723
c
ISO/IEC N????
int frac_digits() const;
pattern pos_format() const;
pattern neg_format() const;
1Each of these functions Freturns the result of calling the corresponding virtual member function do_F().
22.4.6.3.2 moneypunct virtual functions [locale.moneypunct.virtuals]
charT do_decimal_point() const;
1Returns: The radix separator to use in case do_frac_digits() is greater than zero.259
charT do_thousands_sep() const;
2Returns: The digit group separator to use in case do_grouping() specifies a digit grouping pattern.260
string do_grouping() const;
3Returns: A pattern defined identically as, but not necessarily equal to, the result of numpunct<charT>::
do_grouping().261
string_type do_curr_symbol() const;
4Returns: A string to use as the currency identifier symbol.262
string_type do_positive_sign() const;
string_type do_negative_sign() const;
5Returns: do_positive_sign() returns the string to use to indicate a positive monetary value;263
do_negative_sign() returns the string to use to indicate a negative value.
int do_frac_digits() const;
6Returns: The number of digits after the decimal radix separator, if any.264
pattern do_pos_format() const;
pattern do_neg_format() const;
7Returns: The specializations required in Table 82 (22.3.1.1.1), 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 }.265
259) In common U.S. locales this is ’.’.
260) In common U.S. locales this is ’,’.
261) To specify grouping by 3s, the value is "\003" not "3".
262) For international specializations (second template parameter true) this is typically four characters long, usually three
letters and a space.
263) This is usually the empty string.
264) In common U.S. locales, this is 2.
265) Note that the international symbol returned by do_curr_sym() usually contains a space, itself; for example, "USD ".
§ 22.4.6.3.2 724
c
ISO/IEC N????
22.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:
typedef money_base::pattern pattern;
typedef basic_string<charT> string_type;
explicit moneypunct_byname(const char*, size_t refs = 0);
explicit moneypunct_byname(const string&, size_t refs = 0);
protected:
~moneypunct_byname();
};
}
22.4.7 The message retrieval category [category.messages]
1Class messages<charT> implements retrieval of strings from message catalogs.
22.4.7.1 Class template messages [locale.messages]
namespace std {
class messages_base {
public:
typedef unspecified signed integer type catalog;
};
template <class charT>
class messages : public locale::facet, public messages_base {
public:
typedef charT char_type;
typedef basic_string<charT> string_type;
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;
};
}
1Values of type messages_base::catalog usable as arguments to members get and close can be obtained
only by calling member open.
22.4.7.1.1 messages members [locale.messages.members]
catalog open(const basic_string<char>& name, const locale& loc) const;
1Returns: do_open(name, loc).
§ 22.4.7.1.1 725
c
ISO/IEC N????
string_type get(catalog cat, int set, int msgid,
const string_type& dfault) const;
2Returns: do_get(cat, set, msgid, dfault).
void close(catalog cat) const;
3Effects: Calls do_close(cat).
22.4.7.1.2 messages virtual functions [locale.messages.virtuals]
catalog do_open(const basic_string<char>& name,
const locale& loc) const;
1Returns: 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().
2Returns a value less than 0 if no such catalog can be opened.
3Remarks: 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;
4Requires: cat shall be a catalog obtained from open() and not yet closed.
5Returns: 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;
6Requires: cat shall be a catalog obtained from open() and not yet closed.
7Effects: Releases unspecified resources associated with cat.
8Remarks: The limit on such resources, if any, is implementation-defined.
22.4.7.2 Class template messages_byname [locale.messages.byname]
namespace std {
template <class charT>
class messages_byname : public messages<charT> {
public:
typedef messages_base::catalog catalog;
typedef basic_string<charT> string_type;
explicit messages_byname(const char*, size_t refs = 0);
explicit messages_byname(const string&, size_t refs = 0);
protected:
~messages_byname();
};
}
§ 22.4.7.2 726
c
ISO/IEC N????
22.4.8 Program-defined facets [facets.examples]
1A 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.
2[Note: The locale member function templates verify its type and storage class. — end note ]
3[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 ]
4[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 ]
5This 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.
6[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);
7This example illustrates two architectural uses of class locale.
§ 22.4.8 727
c
ISO/IEC N????
8The first is as a default argument in Date::asString(), where the default is the global (presumably user-
preferred) locale.
9The 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 ]
10 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.
11 [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;
typedef ctype<wchar_t> wctype;
§ 22.4.8 728
c
ISO/IEC N????
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;
return 0;
}
12 The new facet is used exactly like the built-in facets. — end example ]
13 [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;
typedef numpunct_byname<char> cnumpunct;
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;
return 0;
}
— end example ]
22.5 Standard code conversion facets [locale.stdcvt]
1The header <codecvt> provides code conversion facets for various character encodings.
2Header <codecvt> synopsis
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);
§ 22.5 729
c
ISO/IEC N????
~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();
};
}
3For 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 con-
version 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.
4For 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.
5For 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.
§ 22.5 730
c
ISO/IEC N????
6For 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.
22.6 C library locales [c.locales]
1Table 93 describes header <clocale>.
Table 93 — Header <clocale> synopsis
Type Name(s)
Macros:LC_ALL LC_COLLATE LC_CTYPE
LC_MONETARY LC_NUMERIC LC_TIME
NULL
Struct:lconv
Functions:localeconv setlocale
2The contents are the same as the Standard C library header <locale.h>.
3Calls to the function setlocale may introduce a data race (17.6.5.9) with other calls to setlocale or with
calls to the functions listed in Table 94.
Table 94 — 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
See also: ISO C Clause 7.4.
§ 22.6 731
c
ISO/IEC N????
23 Containers library [containers]
23.1 General [containers.general]
1This Clause describes components that C++ programs may use to organize collections of information.
2The following subclauses describe container requirements, and components for sequence containers and
associative containers, as summarized in Table 95.
Table 95 — Containers library summary
Subclause Header(s)
23.2 Requirements
23.3 Sequence containers <array>
<deque>
<dynarray>
<forward_list>
<list>
<vector>
23.4 Associative containers <map>
<set>
23.5 Unordered associative containers <unordered_map>
<unordered_set>
23.6 Container adaptors <queue>
<stack>
23.2 Container requirements [container.requirements]
23.2.1 General container requirements [container.requirements.general]
1Containers are objects that store other objects. They control allocation and deallocation of these objects
through constructors, destructors, insert and erase operations.
2All 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 ]
3For the components affected by this subclause that declare an allocator_type, objects stored in these
components shall be constructed using the allocator_traits<allocator_type>::construct function and
destroyed using the allocator_traits<allocator_type>::destroy function (20.8.8.2). 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 ]
4In Tables 96 and 97,Xdenotes a container class containing objects of type T,aand bdenote values of type
X,udenotes an identifier, rdenotes a non-const value of type X, and rv denotes a non-const rvalue of type
X.
§ 23.2.1 732
c
ISO/IEC N????
Table 96 — Container requirements
Expression Return type Operational Assertion/note Complexity
semantics pre-/post-condition
X::value_-
type
TRequires: Tis
Erasable from X
(see 23.2.1, below)
compile time
X::reference lvalue of Tcompile time
X::const_-
reference
const lvalue of
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::dif-
ference_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; post: u.empty() constant
X() post: X().empty() constant
X(a) Requires:Tis
CopyInsertable into
X(see below).
post: a == X(a).
linear
X u(a)
Xu=a;
Requires:Tis
CopyInsertable into
X(see below).
post: u == a
linear
X u(rv)
Xu=rv
post: ushall be
equal to the value
that rv had before
this construction
(Note B)
a = rv X& All existing elements
of aare either move
assigned to or
destroyed
ashall be equal to
the value that rv
had before this
assignment
linear
§ 23.2.1 733
c
ISO/IEC N????
Table 96 — Container requirements (continued)
Expression Return type Operational Assertion/note Complexity
semantics pre-/post-condition
(&a)->X() void note: the destructor
is applied to every
element of a; all the
memory 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.
distance(a.begin(),
a.end()) ==
distance(b.begin(),
b.end()) &&
equal(a.begin(),
a.end(),
b.begin())
Requires: Tis
EqualityComparable
linear
a != b convertible to
bool
Equivalent to: !(a
== b)
linear
a.swap(b) void exchanges the
contents of aand b
(Note A)
swap(a, b) void a.swap(b) (Note A)
r = a X& post: 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
Notes: the algorithm equal() is defined in Clause 25. Those entries marked “(Note A)” or “(Note B)”
have linear complexity for array and have constant complexity for all other standard containers.
5The 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.
6begin() 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();
§ 23.2.1 734
c
ISO/IEC N????
7Unless otherwise specified, all containers defined in this clause obtain memory using an allocator (see 17.6.3.5).
Copy constructors for these container types obtain an allocator by calling allocator_traits<allocator_-
type>::select_on_container_copy_construction on their first parameters. 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 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. The behavior of a call to a con-
tainer’s swap function is undefined unless the objects being swapped have allocators that compare equal or
allocator_traits<allocator_type>::propagate_on_container_swap::value is true. 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.
8The expression a.swap(b), for containers aand bof a standard container type other than array, shall ex-
change the values of aand bwithout invoking any move, copy, or swap operations on the individual container
elements. Any Compare,Pred, or Hash objects belonging to aand bshall be swappable and shall be ex-
changed by unqualified calls to non-member swap. If allocator_traits<allocator_type>::propagate_-
on_container_swap::value is true, then the allocators of aand bshall also be exchanged using an unqual-
ified call to non-member swap. Otherwise, they 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.
9If the iterator type of a container belongs to the bidirectional or random access iterator categories (24.2),
the container is called reversible and satisfies the additional requirements in Table 97.
Table 97 — 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
10 Unless otherwise specified (see 23.2.4.1,23.2.5.1,23.3.3.4, and 23.3.7.5) all container types defined in this
§ 23.2.1 735
c
ISO/IEC N????
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() or push_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 ]
11 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.
12 Table 98 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 98 unless
otherwise stated.
Table 98 — 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())
pre: <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 25.
13 All of the containers defined in this Clause and in (21.4) except array meet the additional requirements of
an allocator-aware container, as described in Table 99.
Given a container type Xhaving an allocator_type identical to Aand a value_type identical to T
and given an lvalue mof type A, a pointer pof type T*, an expression vof type (possibly const) T, and
an rvalue rv of type T, the following terms are defined. If Xis not allocator-aware, the terms below are
defined as if Awere std::allocator<T> — no allocator object needs to be created and user specializations
of std::allocator<T> are not instantiated:
Tis DefaultInsertable into Xmeans that the following expression is well-formed:
allocator_traits<A>::construct(m, p)
An element of Xis default-inserted if it is initialized by evaluation of the expression
§ 23.2.1 736
c
ISO/IEC N????
allocator_traits<A>::construct(m, p)
where pis the address of the uninitialized storage for the element allocated within X.
Tis MoveInsertable into Xmeans 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 ]
Tis CopyInsertable into Xmeans that, in addition to Tbeing 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 vis unchanged and is
equivalent to *p.
Tis EmplaceConstructible into Xfrom args , for zero or more arguments args, means that the
following expression is well-formed:
allocator_traits<A>::construct(m, p, args)
Tis Erasable from Xmeans 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. The default construct in std::allocator will call ::new((void*)p) T(args), but specialized
allocators may choose a different definition. — end note ]
14 In Table 99,Xdenotes an allocator-aware container class with a value_type of Tusing allocator of type A,
udenotes a variable, aand bdenote non-const lvalues of type X,tdenotes an lvalue or a const rvalue of
type X,rv denotes a non-const rvalue of type X, and mis a value of type A.
Table 99 — Allocator-aware container requirements
Expression Return type Assertion/note Complexity
pre-/post-condition
allocator_-
type
ARequires:allocator_-
type::value_type is the same
as X::value_type.
compile time
get_-
allocator()
Aconstant
X()
X u;
Requires: Ais
DefaultConstructible.
post: u.empty() returns true,
u.get_allocator() == A()
constant
X(m) post: u.empty() returns true, constant
X u(m); u.get_allocator() == m
X(t, m)
X u(t, m);
Requires: Tis CopyInsertable
into X.
post: u == t,
get_allocator() == m
linear
§ 23.2.1 737
c
ISO/IEC N????
Table 99 — Allocator-aware container requirements (continued)
Expression Return type Assertion/note Complexity
pre-/post-condition
X(rv)
X u(rv)
Requires: move construction of
Ashall not exit via an
exception.
post: ushall have the same
elements as rv had before this
construction; the value of
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: Tis MoveInsertable
into X.
post: ushall have the same
elements, or copies of the
elements, that rv had before
this construction,
get_allocator() == m
constant if m
== rv.get_-
allocator(),
otherwise
linear
a = t X& Requires: Tis CopyInsertable
into Xand CopyAssignable.
post: a == t
linear
a = rv X& Requires: If allocator_-
traits<allocator_type>
::propagate_on_container_-
move_assignment::value is
false,Tis MoveInsertable
into Xand MoveAssignable.
All existing elements of aare
either move assigned to or
destroyed.
post: ashall be equal to the
value that rv had before this
assignment.
linear
a.swap(b) void exchanges the contents of aand
b
constant
23.2.2 Container data races [container.requirements.dataraces]
1For purposes of avoiding data races (17.6.5.9), 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[].
2Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the con-
tained object in different elements in the same container, excepting vector<bool>, are modified concurrently.
3[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]
§ 23.2.2 738
c
ISO/IEC N????
= true.— end note ]
23.2.3 Sequence containers [sequence.reqmts]
1A 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).
2The 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.
3In Tables 100 and 101,Xdenotes a sequence container class, adenotes a value of Xcontaining elements
of type T,Adenotes X::allocator_type if it exists and std::allocator<T> if it doesn’t, iand jdenote
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>,ndenotes
a value of X::size_type,pdenotes a valid const iterator to a,qdenotes a valid dereferenceable const
iterator to a,[q1, q2) denotes a valid range of const iterators in a,tdenotes 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&&.
4The complexities of the expressions are sequence dependent.
Table 100 — Sequence container requirements (in addition to
container)
Expression Return type Assertion/note
pre-/post-condition
X(n, t)
X a(n, t)
Requires:Tshall be CopyInsertable into X.
post: distance(begin(), end()) == n
Constructs a sequence container with ncopies
of t
X(i, j)
X a(i, j)
Requires: Tshall be EmplaceConstructible
into Xfrom *i. For vector, if the iterator
does not meet the forward iterator
requirements (24.2.5), Tshall also be
MoveInsertable into X. Each iterator in the
range [i,j) shall be dereferenced exactly
once.
post: 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: Tis CopyInsertable into Xand
CopyAssignable. Assigns the range
[il.begin(),il.end()) into a. All existing
elements of aare either assigned to or
destroyed.
Returns: *this.
§ 23.2.3 739
c
ISO/IEC N????
Table 100 — Sequence container requirements (in addition to
container) (continued)
Expression Return type Assertion/note
pre-/post-condition
a.emplace(p, args); iterator Requires: Tis EmplaceConstructible into X
from args. For vector and deque, T is also
MoveInsertable into Xand MoveAssignable.
Effects: Inserts an object of type T
constructed with
std::forward<Args>(args)... before p.
a.insert(p,t) iterator Requires:Tshall be CopyInsertable into X.
For vector and deque,Tshall also be
CopyAssignable.
Effects: Inserts a copy of tbefore p.
a.insert(p,rv) iterator Requires: Tshall be MoveInsertable into X.
For vector and deque,Tshall also be
MoveAssignable.
Effects: Inserts a copy of rv before p.
a.insert(p,n,t) iterator Requires:Tshall be CopyInsertable into X
and CopyAssignable.
Inserts ncopies of tbefore p.
a.insert(p,i,j) iterator Requires:Tshall be EmplaceConstructible
into Xfrom *i. For vector, if the iterator
does not meet the forward iterator
requirements (24.2.5), Tshall also be
MoveInsertable into Xand MoveAssignable.
Each iterator in the range [i,j) shall be
dereferenced exactly once.
pre: iand jare 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,Tshall be
MoveAssignable.
Effects: Erases the element pointed to by q
a.erase(q1,q2) iterator Requires: For vector and deque,Tshall 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 aand may invalidate the
past-the-end iterator.
post: a.empty() returns true.
Complexity: Linear.
§ 23.2.3 740
c
ISO/IEC N????
Table 100 — Sequence container requirements (in addition to
container) (continued)
Expression Return type Assertion/note
pre-/post-condition
a.assign(i,j) void Requires: Tshall be EmplaceConstructible
into Xfrom *i and assignable from *i. For
vector, if the iterator does not meet the
forward iterator requirements (24.2.5), Tshall
also be MoveInsertable into X.
Each iterator in the range [i,j) shall be
dereferenced exactly once.
pre: i,jare not iterators into a.
Replaces elements in awith a copy of [i, j).
a.assign(il) void a.assign(il.begin(), il.end()).
a.assign(n,t) void Requires:Tshall be CopyInsertable into X
and CopyAssignable.
pre: tis not a reference into a.
Replaces elements in awith ncopies of t.
5iterator and const_iterator types for sequence containers shall be at least of the forward iterator category.
6The iterator returned from a.insert(p, t) points to the copy of tinserted into a.
7The iterator returned from a.insert(p, rv) points to the copy of rv inserted into a.
8The iterator returned from a.insert(p, n, t) points to the copy of the first element inserted into a, or p
if n == 0.
9The iterator returned from a.insert(p, i, j) points to the copy of the first element inserted into a, or p
if i == j.
10 The iterator returned from a.insert(p, il) points to the copy of the first element inserted into a, or pif
il is empty.
11 The iterator returned from a.emplace(p, args) points to the new element constructed from args into a.
12 The iterator returned from a.erase(q) points to the element immediately following qprior to the element
being erased. If no such element exists, a.end() is returned.
13 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.
14 For every sequence container defined in this Clause and in Clause 21:
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> // such as insert()
rt fx1(const_iterator p, InputIterator first, InputIterator last);
template <class InputIterator> // such as append(), assign()
rt fx2(InputIterator first, InputIterator last);
template <class InputIterator> // such as replace()
rt fx3(const_iterator i1, const_iterator i2, InputIterator first, InputIterator last);
§ 23.2.3 741
c
ISO/IEC N????
are called with a type InputIterator that does not qualify as an input iterator, then these functions
shall not participate in overload resolution.
15 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.
16 Table 101 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 101 — Optional sequence container operations
Expression Return type Operational semantics Container
a.front() reference; const_reference
for constant a
*a.begin() basic_-
string,
array,deque,
dynarray,
forward_-
list,list,
vector
a.back() reference; const_reference
for constant a
{ auto tmp = a.end();
--tmp;
return *tmp; }
basic_-
string,
array,deque,
dynarray,
list,vector
a.emplace_-
front(args)
void Prepends an
object of type Tconstructed with
std::forward<Args>(args)....
Requires: Tshall be
EmplaceConstructible into X
from args.
deque,
forward_-
list,
list
a.emplace_-
back(args)
void Appends an
object of type Tconstructed with
std::forward<Args>(args)....
Requires: Tshall be
EmplaceConstructible into X
from args. For vector,Tshall
also be MoveInsertable into X.
deque,list,
vector
a.push_-
front(t)
void Prepends a copy of t.
Requires: Tshall be
CopyInsertable into X.
deque,
forward_-
list,
list
a.push_-
front(rv)
void Prepends a copy of rv.
Requires: Tshall be
MoveInsertable into X.
deque,
forward_-
list,
list
a.push_-
back(t)
void Appends a copy of t.
Requires: Tshall be
CopyInsertable into X.
basic_-
string,
deque,list,
vector
§ 23.2.3 742
c
ISO/IEC N????
Table 101 — Optional sequence container operations (continued)
Expression Return type Operational semantics Container
a.push_-
back(rv)
void Appends a copy of rv.
Requires: Tshall 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,
dynarray,
vector
a.at(n) reference; const_reference
for constant a
*(a.begin() + n) basic_-
string,
array,deque,
dynarray,
vector
17 The member function at() provides bounds-checked access to container elements. at() throws out_of_-
range if n >= a.size().
23.2.4 Associative containers [associative.reqmts]
1Associative containers provide fast retrieval of data based on keys. The library provides four basic kinds of
associative containers: set,multiset,map and multimap.
2Each associative container is parameterized on Key and an ordering relation Compare that induces a strict
weak ordering (25.4) on elements of Key. In addition, map and multimap associate an arbitrary mapped type
Twith the Key. The object of type Compare is called the comparison object of a container.
3The 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.
4An 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.
5For 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>.
6iterator 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 ]
§ 23.2.4 743
c
ISO/IEC N????
7The associative containers meet all the requirements of Allocator-aware containers (23.2.1), except that
for map and multimap, the requirements placed on value_type in Table 96 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 ]
8In Table 102,Xdenotes an associative container class, adenotes a value of X,a_uniq denotes a value of Xwhen
Xsupports unique keys, a_eq denotes a value of Xwhen Xsupports multiple keys, a_tran denotes a value
of Xwhen the type X::key_compare::is_transparent exists, iand jsatisfy input iterator requirements
and refer to elements implicitly convertible to value_type,[i,j) denotes a valid range, pdenotes a valid
const iterator to a,qdenotes a valid dereferenceable const iterator to a,[q1, q2) denotes a valid range of
const iterators in a,il designates an object of type initializer_list<value_type>,tdenotes a value of
X::value_type,kdenotes a value of X::key_type and cdenotes a value of type X::key_compare;kl is a
value such that ais partitioned (25.4) with respect to c(r, kl), with rthe key value of eand ein a;ku is
a value such that ais partitioned with respect to !c(ku, r);ke is a value such that ais partitioned with
respect to c(r, ke) and !c(ke, r), with c(r, ke) implying !c(ke, r).Adenotes the storage allocator
used by X, if any, or std::allocator<X::value_type> otherwise, and mdenotes an allocator of a type
convertible to A.
Table 102 — Associative container requirements (in addition to
container)
Expression Return type Assertion/note Complexity
pre-/post-condition
X::key_type Key compile time
mapped_type
(map and
multimap
only)
Tcompile 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 defaults to less<key_type> 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(c)
X a(c);
Requires: key_compare is
CopyConstructible.
Effects: Constructs an empty
container. Uses a copy of cas
a comparison object.
constant
§ 23.2.4 744
c
ISO/IEC N????
Table 102 — Associative container requirements (in addition to
container) (continued)
Expression Return type Assertion/note Complexity
pre-/post-condition
X()
X a;
Requires: key_compare is
DefaultConstructible.
Effects: Constructs an empty
container. Uses Compare() as
a comparison object
constant
X(i,j,c)
X a(i,j,c);
Requires: key_compare is
CopyConstructible.
value_type is
EmplaceConstructible into X
from *i.
Effects: Constructs an empty
container and inserts elements
from the range [i, j) into it;
uses cas a comparison object.
Nlog Nin general (Nhas
the value distance(i, j));
linear if [i, j) is sorted
with value_comp()
X(i,j)
X a(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()).
a = il X& Requires: value_type is
CopyInsertable into Xand
CopyAssignable.
Effects: Assigns the range
[il.begin(),il.end()) into
a. All existing elements of a
are either assigned to or
destroyed.
NlogN in general (where N
has the value il.size() +
a.size()); linear if
[il.begin(),il.end()) is
sorted with value_comp().
a.key_-
comp()
X::key_-
compare
returns the comparison object
out of which awas
constructed.
constant
a.value_-
comp()
X::value_-
compare
returns an object of
value_compare constructed
out of the comparison object
constant
§ 23.2.4 745
c
ISO/IEC N????
Table 102 — Associative container requirements (in addition to
container) (continued)
Expression Return type Assertion/note Complexity
pre-/post-condition
a_uniq.
emplace(args)
pair<iterator,
bool>
Requires: value_type shall be
EmplaceConstructible into X
from args.
Effects: Inserts a value_type
object tconstructed 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 tconstructed with
std::forward<Args>(args)...
and returns the iterator
pointing to the newly inserted
element. If a range containing
elements equivalent to texists
in a_eq,tis 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
§ 23.2.4 746
c
ISO/IEC N????
Table 102 — Associative container requirements (in addition to
container) (continued)
Expression Return type Assertion/note Complexity
pre-/post-condition
a_uniq.
insert(t)
pair<iterator,
bool>
Requires: If tis a non-const
rvalue expression, value_type
shall be MoveInsertable into
X; otherwise, value_type shall
be CopyInsertable into X.
Effects: Inserts tif 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 tis a non-const
rvalue expression, value_type
shall be MoveInsertable into
X; otherwise, value_type shall
be CopyInsertable into X.
Effects: Inserts tand returns
the iterator pointing to the
newly inserted element. If a
range containing elements
equivalent to texists in a_eq,
tis inserted at the end of that
range.
logarithmic
a.insert(
p, t)
iterator Requires: If tis a non-const
rvalue expression, value_type
shall be MoveInsertable into
X; otherwise, value_type shall
be CopyInsertable into X.
Effects: Inserts tif and only if
there is no element with key
equivalent to the key of tin
containers with unique keys;
always inserts tin containers
with equivalent keys. Always
returns the iterator pointing to
the element with key
equivalent to the key of t.tis
inserted as close as possible to
the position just prior to p.
logarithmic in general, but
amortized constant if tis
inserted right before p.
§ 23.2.4 747
c
ISO/IEC N????
Table 102 — Associative container requirements (in addition to
container) (continued)
Expression Return type Assertion/note Complexity
pre-/post-condition
a.insert(
i, j)
void Requires: value_type shall be
EmplaceConstructible into X
from *i.
pre: i,jare 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.
Nlog(a.size() + N)(Nhas
the value distance(i, j)
a.insert(il) void Equivalent to
a.insert(il.begin(),
il.end()).
a.erase(k) size_type erases all elements in the
container with key equivalent
to k. returns the number of
erased elements.
log(a.size()) + a.count(k)
a.erase(q) iterator erases the element pointed to
by q. Returns an iterator
pointing to the element
immediately following qprior
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 q2.
log(a.size()) + Nwhere N
has the value distance(q1,
q2).
a.clear() void a.erase(a.begin(),a.end())
post: a.empty() returns true
linear in a.size().
a.find(k) iterator;
const_-
iterator for
constant a.
returns an iterator pointing to
an element with the key
equivalent to k, or a.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 rsuch
that !c(r, ke) && !c(ke,
r), or a_tran.end() if such
an element is not found
logarithmic
a.count(k) size_type returns the number of elements
with key equivalent to k
log(a.size()) + a.count(k)
§ 23.2.4 748
c
ISO/IEC N????
Table 102 — Associative container requirements (in addition to
container) (continued)
Expression Return type Assertion/note Complexity
pre-/post-condition
a_tran.
count(ke)
size_type returns the number of
elements with key rsuch that
!c(r, ke) && !c(ke, r)
log(a_tran.size()) +
a_tran.count(ke)
a.lower_-
bound(k)
iterator;
const_-
iterator for
constant a.
returns an iterator pointing to
the first element with key not
less than k, or a.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
a.upper_-
bound(k)
iterator;
const_-
iterator for
constant a.
returns an iterator pointing to
the first element with key
greater than k, or a.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
a.equal_-
range(k)
pair<iterator,
iterator>;
pair<const_-
iterator,
const_-
iterator> for
constant a.
equivalent to make_-
pair(a.lower_bound(k),
a.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
9The 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.
10 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 iand jsuch that distance from ito jis positive,
value_comp(*j, *i) == false
11 For associative containers with unique keys the stronger condition holds,
value_comp(*i, *j) != false.
§ 23.2.4 749
c
ISO/IEC N????
12 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.
13 The member function templates find,count,lower_bound,upper_bound, and equal_range shall not
participate in overload resolution unless the type Compare::is_transparent exists.
23.2.4.1 Exception safety guarantees [associative.reqmts.except]
1For 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).
2For 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.
3For associative containers, no swap function throws an exception unless that exception is thrown by the
swap of the container’s Compare object (if any).
23.2.5 Unordered associative containers [unord.req]
1Unordered 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.
2Unordered associative containers conform to the requirements for Containers (23.2), except that the expres-
sions a == b and a != b have different semantics than for the other container types.
3Each unordered associative container is parameterized by Key, by a function object type Hash that meets the
Hash requirements (17.6.3.4) 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 Twith the Key.
4The 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.
5Two 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 kin a container, calling hash(k) shall always return the same value.
6An 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 equiv-
alent 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.
7For unordered_set and unordered_multiset the value type is the same as the key type. For unordered_-
map and unordered_multimap it is std::pair<const Key, T>.
8For 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 ]
9The 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
§ 23.2.5 750
c
ISO/IEC N????
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.
10 The unordered associative containers meet all the requirements of Allocator-aware containers (23.2.1), except
that for unordered_map and unordered_multimap, the requirements placed on value_type in Table 96 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 ]
11 In table 103:Xis an unordered associative container class, ais an object of type X,bis a possibly const
object of type X,a_uniq is an object of type Xwhen Xsupports unique keys, a_eq is an object of type X
when Xsupports equivalent keys, iand jare input iterators that refer to value_type,[i, j) is a valid
range, pand q2 are valid const iterators to a,qand q1 are valid dereferenceable const iterators to a,[q1,
q2) is a valid range in a,il designates an object of type initializer_list<value_type>,tis a value of
type X::value_type,kis a value of type key_type,hf is a possibly const value of type hasher,eq is a
possibly const value of type key_equal,nis a value of type size_type, and zis a value of type float.
Table 103 — Unordered associative container requirements (in
addition to container)
Expression Return type Assertion/note pre-/post-condition Complexity
X::key_type Key compile time
X::mapped_type
(unordered_map and
unordered_multimap
only)
Tcompile 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
std::size_t.
compile time
X::key_equal Pred 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.
Alocal_iterator object may
be used to iterate through a
single bucket, but may not be
used to iterate across buckets.
compile time
§ 23.2.5 751
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
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.
Aconst_local_iterator
object may be used to iterate
through a single bucket, but
may not be used to iterate
across buckets.
compile time
X(n, hf, eq)
X a(n, hf, eq)
XRequires: hasher and
key_equal are
CopyConstructible.
Effects: Constructs an empty
container with at least n
buckets, using hf as the hash
function and eq as the key
equality predicate.
O(n)
X(n, hf)
X a(n, hf)
XRequires: hasher is
CopyConstructible and
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.
O(n)
X(n)
X a(n)
XRequires: 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.
O(n)
X()
X a
XRequires: 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
§ 23.2.5 752
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
X(i, j, n, hf, eq)
X a(i, j, n, hf,
eq)
XRequires: hasher and
key_equal are
CopyConstructible.
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
O(N)(Nis
distance(i,
j)), worst case
O(N2)
X(i, j, n, hf)
X a(i, j, n, hf)
XRequires: hasher is
CopyConstructible and
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
O(N)(Nis
distance(i,
j)), worst case
O(N2)
X(i, j, n)
X a(i, j, n)
XRequires: 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
O(N)(Nis
distance(i,
j)), worst case
O(N2)
§ 23.2.5 753
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
X(i, j)
X a(i, j)
XRequires: 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
O(N)(Nis
distance(i,
j)), worst case
O(N2)
X(il) X Same as X(il.begin(),
il.end()).
Same as
X(il.begin(),
il.end()).
X(b)
X a(b)
XCopy constructor. In addition
to the requirements of Table 96,
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 96, 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 Xand
CopyAssignable.
Effects: Assigns the range
[il.begin(),il.end()) into
a. All existing elements of aare
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
§ 23.2.5 754
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
a_uniq.
emplace(args)
pair<iterator, bool> Requires: value_type shall be
EmplaceConstructible into X
from args.
Effects: Inserts a value_type
object tconstructed 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
O(1), worst
case O(a_uniq.
size()).
a_eq.emplace(args) iterator Requires: value_type shall be
EmplaceConstructible into X
from args.
Effects: Inserts a value_type
object tconstructed with
std::forward<Args>(args)...
and returns the iterator
pointing to the newly inserted
element.
Average case
O(1), worst
case O(a_eq.
size()).
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
O(1), worst
case
O(a.size()).
§ 23.2.5 755
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
a_uniq.insert(t) pair<iterator,
bool>
Requires: If tis a non-const
rvalue expression, value_type
shall be MoveInsertable into
X; otherwise, value_type shall
be CopyInsertable into X.
Effects: Inserts tif 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
O(1), worst
case O(a_uniq.
size()).
a_eq.insert(t) iterator Requires: If tis 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
O(1), worst
case O(a_eq.
size()).
a.insert(q, t) iterator Requires: If tis 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 qis a hint
pointing to where the search
should start. Implementations
are permitted to ignore the
hint.
Average case
O(1), worst
case
O(a.size()).
a.insert(i, j) void Requires: value_type shall be
EmplaceConstructible into X
from *i.
Pre: iand jare not iterators in
a. Equivalent to a.insert(t)
for each element in [i,j).
Average case
O(N), where N
is distance(i,
j). Worst case
O(N
(a.size())
+ N).
§ 23.2.5 756
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
a.insert(il) void Same as
a.insert(il.begin(),
il.end()).
Same as
a.insert(
il.begin(),
il.end()).
a.erase(k) size_type Erases all elements with key
equivalent to k. Returns the
number of elements erased.
Average case
O(a.count(k)).
Worst case
O(a.size()).
a.erase(q) iterator Erases the element pointed to
by q. Return value is the
iterator immediately following q
prior to the erasure.
Average case
O(1), worst
case
O(a.size()).
a.erase(q1, q2) iterator Erases all elements in the range
[q1, q2). Return value is the
iterator immediately following
the erased elements prior to the
erasure.
Average case
linear in
distance(q1,
q2), worst case
O(a.size()).
a.clear() void Erases all elements in the
container. Post: a.empty()
returns true
Linear.
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
O(1), worst
case
O(b.size()).
b.count(k) size_type Returns the number of elements
with key equivalent to k.
Average case
O(1), worst
case
O(b.size()).
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
O(b.count(k)).
Worst case
O(b.size()).
b.bucket_count() size_type Returns the number of buckets
that bcontains.
Constant
b.max_bucket_-
count()
size_type Returns an upper bound on the
number of buckets that bmight
ever contain.
Constant
§ 23.2.5 757
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
b.bucket(k) size_type Pre: b.bucket_count() > 0.
Returns the index of the bucket
in which elements with keys
equivalent to kwould be found,
if any such element existed.
Post: the return value shall be
in the range [0,
b.bucket_count()).
Constant
b.bucket_size(n) size_type Pre: nshall be in the range [0,
b.bucket_count()). Returns
the number of elements in the
nth bucket.
O(b.bucket_-
size(n))
b.begin(n) local_iterator;
const_local_-
iterator for const
b.
Pre: nshall 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.
Pre: nshall 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
Pre: nshall 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 nth bucket.
Constant
b.cend(n) const_local_-
iterator
Pre: nshall 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 Pre: zshall be positive. May
change the container’s
maximum load factor, using z
as a hint.
Constant
§ 23.2.5 758
c
ISO/IEC N????
Table 103 — Unordered associative container requirements (in
addition to container) (continued)
Expression Return type Assertion/note pre-/post-condition Complexity
a.rehash(n) void Post: 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.
12 Two unordered containers aand bcompare 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 distance(Ea1, Ea2) == distance(Eb1, Eb2) and is_-
permutation(Ea1, Ea2, Eb1) 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_equal(), and to the hasher returned by hash_function()) is proportional to Nin the average case
and to N2in the worst case, where Nis a.size(). For unordered_multiset and unordered_multimap,
the complexity of operator== is proportional to PE2
iin the average case and to N2in the worst case,
where Nis a.size(), and Eiis the size of the ith equivalent-key group in a. However, if the respective
elements of each corresponding pair of equivalent-key groups Eaiand Ebiare arranged in the same order
(as is commonly the case, e.g., if aand bare 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 O(N2), 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 operator for
Key is a refinement266 of the partition into equivalent-key groups produced by Pred.
13 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 const iterators.
14 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.
15 The insert and emplace members shall not affect the validity of iterators if (N+n) < z * B, where Nis the
number of elements in the container prior to the insert operation, nis the number of elements inserted, Bis
the container’s bucket count, and zis the container’s maximum load factor.
23.2.5.1 Exception safety guarantees [unord.req.except]
1For 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).
2For 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.
3For 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).
266) Equality comparison is a refinement of partitioning if no two objects that compare equal fall into different partitions.
§ 23.2.5.1 759
c
ISO/IEC N????
4For 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.
23.3 Sequence containers [sequences]
23.3.1 In general [sequences.general]
1The headers <array>,<deque>,<dynarray>,<forward_list>,<list>, and <vector> define template
classes that meet the requirements for sequence containers.
2The headers <queue> and <stack> define container adaptors (23.6) that also meet the requirements for
sequence containers.
Header <array> synopsis
#include <initializer_list>
namespace std {
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;
}
Header <deque> synopsis
#include <initializer_list>
namespace std {
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);
§ 23.3.1 760
c
ISO/IEC N????
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);
}
Header <dynarray> synopsis
#include <initializer_list>
namespace std {
template <class T> class dynarray;
template <class Type, class Alloc>
struct uses_allocator<dynarray<Type>, Alloc>;
template <class T>
bool operator==(const dynarray<T>& x, const dynarray<T>& y);
template <class T>
bool operator<(const dynarray<T>& x, const dynarray<T>& y);
template <class T>
bool operator!=(const dynarray<T>& x, const dynarray<T>& y);
template <class T>
bool operator>(const dynarray<T>& x, const dynarray<T>& y);
template <class T>
bool operator>=(const dynarray<T>& x, const dynarray<T>& y);
template <class T>
bool operator<=(const dynarray<T>& x, const dynarray<T>& y);
}
Header <forward_list> synopsis
#include <initializer_list>
namespace std {
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);
}
Header <list> synopsis
§ 23.3.1 761
c
ISO/IEC N????
#include <initializer_list>
namespace std {
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);
}
Header <vector> synopsis
#include <initializer_list>
namespace std {
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);
template <class Allocator> class vector<bool,Allocator>;
// hash support
template <class T> struct hash;
template <class Allocator> struct hash<vector<bool, Allocator> >;
}
23.3.2 Class template array [array]
23.3.2.1 Class template array overview [array.overview]
1The header <array> defines a class template for storing fixed-size sequences of objects. An array supports
random access iterators. An instance of array<T, N> stores Nelements of type T, so that size() == N is
an invariant. The elements of an array are stored contiguously, meaning that if ais an array<T, N> then
it obeys the identity &a[n] == &a[0] + n for all 0<=n<N.
2An array is an aggregate (8.5.1) that can be initialized with the syntax
§ 23.3.2.1 762
c
ISO/IEC N????
array<T, N> a = { initializer-list };
where initializer-list is a comma-separated list of up to Nelements whose types are convertible to T.
3An array satisfies all of the requirements of a container and of a reversible container (23.2), 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 (23.2.3). 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:
typedef T& reference;
typedef const T& const_reference;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef reverse_iterator<iterator> reverse_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
T elems[N]; // exposition only
// no explicit construct/copy/destroy for aggregate type
void fill(const T& u);
void swap(array&) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
// 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:
constexpr size_type size() const noexcept;
constexpr size_type max_size() const noexcept;
constexpr bool empty() const noexcept;
// element access:
reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;
§ 23.3.2.1 763
c
ISO/IEC N????
reference at(size_type n);
constexpr const_reference at(size_type n) const;
reference front();
constexpr const_reference front() const;
reference back();
constexpr const_reference back() const;
T * data() noexcept;
const T * data() const noexcept;
};
}
4[Note: The member variable elems is shown for exposition only, to emphasize that array is a class aggregate.
The name elems is not part of array’s interface. — end note ]
23.3.2.2 array constructors, copy, and assignment [array.cons]
1The conditions for an aggregate (8.5.1) shall be met. Class array relies on the implicitly-declared special
member functions (12.1,12.4, and 12.8) to conform to the container requirements table in 23.2. In addition
to the requirements specified in the container requirements table, the implicit move constructor and move
assignment operator for array require that Tbe MoveConstructible or MoveAssignable, respectively.
23.3.2.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)));
1Effects:
x.swap(y);
2Complexity: linear in N.
23.3.2.4 array::size [array.size]
template <class T, size_t N> constexpr size_type array<T,N>::size() const noexcept;
1Returns: N
23.3.2.5 array::data [array.data]
T* data() noexcept;
const T* data() const noexcept;
1Returns: elems.
23.3.2.6 array::fill [array.fill]
void fill(const T& u);
1Effects: fill_n(begin(), N, u)
23.3.2.7 array::swap [array.swap]
void swap(array& y) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
1Effects: swap_ranges(begin(), end(), y.begin())
2Throws: Nothing unless one of the element-wise swap calls throws an exception.
3Note: 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.
§ 23.3.2.7 764
c
ISO/IEC N????
23.3.2.8 Zero sized arrays [array.zero]
1array shall provide support for the special case N == 0.
2In the case that N == 0,begin() == end() == unique value. The return value of data() is unspecified.
3The effect of calling front() or back() for a zero-sized array is undefined.
4Member function swap() shall have a noexcept-specification which is equivalent to noexcept(true).
23.3.2.9 Tuple interface to class template array [array.tuple]
tuple_size<array<T, N> >::value
1Return type: integral constant expression.
2Value: N
tuple_element<I, array<T, N> >::type
3Requires: I<N. The program is ill-formed if Iis out of bounds.
4Value: The type T.
template <size_t I, class T, size_t N>
constexpr T& get(array<T, N>& a) noexcept;
5Requires: I<N. The program is ill-formed if Iis out of bounds.
6Returns: A reference to the Ith element of a, where indexing is zero-based.
template <size_t I, class T, size_t N>
constexpr T&& get(array<T, N>&& a) noexcept;
7Effects: Equivalent to return std::move(get<I>(a));
template <size_t I, class T, size_t N>
constexpr const T& get(const array<T, N>& a) noexcept;
8Requires: I<N. The program is ill-formed if Iis out of bounds.
9Returns: A const reference to the Ith element of a, where indexing is zero-based.
23.3.3 Class template deque [deque]
23.3.3.1 Class template deque overview [deque.overview]
1Adeque is a sequence container that, like a vector (23.3.7), supports 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. As with vectors, storage management is handled automatically.
2Adeque satisfies all of the requirements of a container, of a reversible container (given in tables in 23.2), of
a sequence container, including the optional sequence container requirements (23.2.3), and of an allocator-
aware container (Table 99). 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:
§ 23.3.3.1 765
c
ISO/IEC N????
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // See 23.2
typedef implementation-defined const_iterator; // See 23.2
typedef implementation-defined size_type; // See 23.2
typedef implementation-defined difference_type;// See 23.2
typedef T value_type;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// 23.3.3.2, construct/copy/destroy:
explicit deque(const Allocator& = 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);
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;
// 23.3.3.3, capacity:
size_type size() const noexcept;
size_type max_size() const noexcept;
void resize(size_type sz);
void resize(size_type sz, const T& c);
§ 23.3.3.1 766
c
ISO/IEC N????
void shrink_to_fit();
bool empty() const noexcept;
// 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;
// 23.3.3.4, modifiers:
template <class... Args> void emplace_front(Args&&... args);
template <class... Args> void 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&);
void clear() noexcept;
};
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);
// specialized algorithms:
template <class T, class Allocator>
void swap(deque<T,Allocator>& x, deque<T,Allocator>& y);
§ 23.3.3.1 767
c
ISO/IEC N????
}
23.3.3.2 deque constructors, copy, and assignment [deque.cons]
explicit deque(const Allocator& = Allocator());
1Effects: Constructs an empty deque, using the specified allocator.
2Complexity: Constant.
explicit deque(size_type n, const Allocator& = Allocator());
3Effects: Constructs a deque with ndefault-inserted elements using the specified allocator.
4Requires: Tshall be DefaultInsertable into *this.
5Complexity: Linear in n.
deque(size_type n, const T& value,
const Allocator& = Allocator());
6Effects: Constructs a deque with ncopies of value, using the specified allocator.
7Requires: Tshall be CopyInsertable into *this.
8Complexity: Linear in n.
template <class InputIterator>
deque(InputIterator first, InputIterator last,
const Allocator& = Allocator());
9Effects: Constructs a deque equal to the range [first,last), using the specified allocator.
10 Complexity: distance(first, last).
23.3.3.3 deque capacity [deque.capacity]
void resize(size_type sz);
1Effects: If sz <= size(), equivalent to calling pop_back() size() - sz times. If size() < sz,
appends sz - size() default-inserted elements to the sequence.
2Requires: Tshall be MoveInsertable and DefaultInsertable into *this.
void resize(size_type sz, const T& c);
3Effects: If sz <= size(), equivalent to calling pop_back() size() - sz times. If size() < sz,
appends sz - size() copies of cto the sequence.
4Requires: Tshall be MoveInsertable into *this and CopyInsertable into *this.
void shrink_to_fit();
5Requires: Tshall be MoveInsertable into *this.
6Complexity: Linear in the size of the sequence.
7Remarks: 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 ]
§ 23.3.3.3 768
c
ISO/IEC N????
23.3.3.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> void emplace_front(Args&&... args);
template <class... Args> void 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);
1Effects: 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.
2Remarks: If an exception is thrown other than by the copy constructor, move constructor, assignment
operator, or move assignment operator of Tthere are no effects. If an exception is thrown by the move
constructor of a non-CopyInsertable T, the effects are unspecified.
3Complexity: 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);
4Effects: 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 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.
5Complexity: The number of calls to the destructor is the same as the number of elements erased, but
the number of calls to the assignment operator is no more than the lesser of the number of elements
before the erased elements and the number of elements after the erased elements.
6Throws: Nothing unless an exception is thrown by the copy constructor, move constructor, assignment
operator, or move assignment operator of T.
23.3.3.5 deque specialized algorithms [deque.special]
template <class T, class Allocator>
void swap(deque<T,Allocator>& x, deque<T,Allocator>& y);
1Effects:
x.swap(y);
§ 23.3.3.5 769
c
ISO/IEC N????
23.3.4 Class template dynarray [dynarray]
23.3.4.1 Class template dynarray overview [dynarray.overview]
1The header <dynarray> defines a class template for storing sequences of objects where the size is fixed at
construction. A dynarray supports random access iterators. An instance of dynarray<T> stores elements
of type T. The elements of a dynarray are stored contiguously, meaning that if dis a dynarray<T> then it
obeys the identity &d[n] == &d[0] + n for all 0 <= n < d.size().
2Unless otherwise specified, all dynarray operations have the same requirements and semantics as specified
in 23.2.
3All operations except construction, destruction, and fill shall have constant-time complexity.
namespace std {
template <class T>
class dynarray {
public:
// types:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef implementation-defined iterator; // See 23.2
typedef implementation-defined const_iterator; // See 23.2
typedef reverse_iterator<iterator> reverse_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
// 23.3.4.2 construct/copy/destroy:
explicit dynarray(size_type c);
template <class Alloc>
dynarray(size_type c, const Alloc& alloc);
dynarray(size_type c, const T& v);
template <class Alloc>
dynarray(size_type c, const T& v, const Alloc& alloc);
dynarray(const dynarray& d);
template <class Alloc>
dynarray(const dynarray& d, const Alloc& alloc);
dynarray(initializer_list<T>);
template <class Alloc>
dynarray(initializer_list<T>, const Alloc& alloc);
~dynarray();
dynarray& operator=(const dynarray&) = delete;
// iterators:
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cend() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
§ 23.3.4.1 770
c
ISO/IEC N????
const_reverse_iterator crbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crend() const noexcept;
// capacity:
size_type size() const noexcept;
size_type max_size() const noexcept;
bool empty() const noexcept;
// element access:
reference operator[](size_type n);
const_reference operator[](size_type n) const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
reference at(size_type n);
const_reference at(size_type n) const;
// 23.3.4.3 data access:
T* data() noexcept;
const T* data() const noexcept;
// 23.3.4.4 mutating member functions:
void fill(const T& v);
};
}// namespace std
23.3.4.2 dynarray constructor and destructor [dynarray.cons]
explicit dynarray(size_type c);
1Effects: Allocates storage for celements. May or may not invoke the global operator new. The c
elements of the dynarray are default-initialized (8.5).
2Throws: std::bad_array_length when the size requested is larger than implementable. std::bad_-
alloc when there is insufficient memory.
dynarray(size_type c, const T& v);
3Requires: Tshall meet the CopyConstructible requirements.
4Effects: Allocates storage for celements. May or may not invoke the global operator new. The c
elements of the dynarray are direct-initialized (8.5) with argument v.
5Throws: std::bad_array_length when the size requested is larger than implementable. std::bad_-
alloc when there is insufficient memory.
dynarray(const dynarray& d);
6Requires: Tshall meet the CopyConstructible requirements.
§ 23.3.4.2 771
c
ISO/IEC N????
7Effects: Allocates storage for d.size() elements. The d.size() elements of the dynarray are direct-
initialized (8.5) with the corresponding elements of d. May or may not invoke the global operator
new.
8Throws: std::bad_alloc when there is insufficient memory.
template <class Alloc>
dynarray(size_type c, const Alloc& alloc);
template <class Alloc>
dynarray(size_type c, const T& v, const Alloc& alloc);
template <class Alloc>
dynarray(const dynarray& d, const Alloc& alloc);
template <class Alloc>
dynarray(initializer_list<T>, const Alloc& alloc);
9Requires: Alloc shall meet the requirements for an Allocator (17.6.3.5).
10 Effects: Equivalent to the preceding constructors except that each element is constructed with uses-
allocator construction (20.8.7.2).
~dynarray();
11 Effects: Invokes the global operator delete if and only if the constructor invoked the global operator
new.
23.3.4.3 dynarray::data [dynarray.data]
T* data() noexcept;
const T* data() const noexcept;
1Returns: A pointer to the contiguous storage containing the elements.
23.3.4.4 Mutating operations [dynarray.mutate]
void fill(const T& v);
1Effects: fill_n(begin(), size(), v);
23.3.4.5 Zero sized dynarrays [dynarray.zero]
1dynarray shall provide support for the special case of construction with a size of zero. In the case that the
size is zero, begin() == end() == unique value. The return value of data() is unspecified. The effect of
calling front() or back() for a zero-sized dynarray is undefined.
23.3.4.6 Traits [dynarray.traits]
template <class Type, class Alloc>
struct uses_allocator<dynarray<Type>, Alloc> : true_type { };
1Requires: Alloc shall be an Allocator (17.6.3.5). [ Note: Specialization of this trait informs other
library components that dynarray can be constructed with an allocator, even though it does not have
a nested allocator_type.— end note ]
23.3.5 Class template forward_list [forwardlist]
23.3.5.1 Class template forward_list overview [forwardlist.overview]
1Aforward_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
§ 23.3.5.1 772
c
ISO/IEC N????
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 ]
2Aforward_list satisfies all of the requirements of a container (Table 96), except that the size() member
function is not provided. A forward_list also satisfies all of the requirements for an allocator-aware
container (Table 99). In addition, a forward_list provides the assign member functions (Table 100) and
several of the optional container requirements (Table 101). 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.
3[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:
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // See 23.2
typedef implementation-defined const_iterator; // See 23.2
typedef implementation-defined size_type; // See 23.2
typedef implementation-defined difference_type;// See 23.2
typedef T value_type;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
// 23.3.5.2, construct/copy/destroy:
explicit forward_list(const Allocator& = 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);
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;
// 23.3.5.3, iterators:
iterator before_begin() noexcept;
const_iterator before_begin() const noexcept;
§ 23.3.5.1 773
c
ISO/IEC N????
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;
// 23.3.5.4, element access:
reference front();
const_reference front() const;
// 23.3.5.5, modifiers:
template <class... Args> void 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&);
void resize(size_type sz);
void resize(size_type sz, const value_type& c);
void clear() noexcept;
// 23.3.5.6, 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);
§ 23.3.5.1 774
c
ISO/IEC N????
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;
};
// Comparison operators
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);
// 23.3.5.7, specialized algorithms:
template <class T, class Allocator>
void swap(forward_list<T,Allocator>& x, forward_list<T,Allocator>& y);
}
23.3.5.2 forward_list constructors, copy, assignment [forwardlist.cons]
explicit forward_list(const Allocator& = Allocator());
1Effects: Constructs an empty forward_list object using the specified allocator.
2Complexity: Constant.
explicit forward_list(size_type n, const Allocator& = Allocator());
3Effects: Constructs a forward_list object with ndefault-inserted elements using the specified allo-
cator.
4Requires: Tshall be DefaultInsertable into *this.
5Complexity: Linear in n.
forward_list(size_type n, const T& value, const Allocator& = Allocator());
6Effects: Constructs a forward_list object with ncopies of value using the specified allocator.
7Requires: Tshall be CopyInsertable into *this.
8Complexity: Linear in n.
§ 23.3.5.2 775
c
ISO/IEC N????
template <class InputIterator>
forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator());
9Effects: Constructs a forward_list object equal to the range [first,last).
10 Complexity: Linear in distance(first, last).
23.3.5.3 forward_list iterators [forwardlist.iter]
iterator before_begin() noexcept;
const_iterator before_begin() const noexcept;
const_iterator cbefore_begin() const noexcept;
1Returns: A non-dereferenceable iterator that, when incremented, is equal to the iterator returned by
begin().
2Effects: cbefore_begin() is equivalent to const_cast<forward_list const&>(*this).before_-
begin().
3Remarks: before_begin() == end() shall equal false.
23.3.5.4 forward_list element access [forwardlist.access]
reference front();
const_reference front() const;
1Returns: *begin()
23.3.5.5 forward_list modifiers [forwardlist.modifiers]
1None 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 nelements into a forward_list is linear in n, and the
number of calls to the copy or move constructor of Tis exactly equal to n. Erasing nelements from a
forward_list is linear in nand the number of calls to the destructor of type Tis exactly equal to n.
template <class... Args> void emplace_front(Args&&... args);
2Effects: 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);
3Effects: Inserts a copy of xat the beginning of the list.
void pop_front();
4Effects: erase_after(before_begin())
iterator insert_after(const_iterator position, const T& x);
iterator insert_after(const_iterator position, T&& x);
5Requires: position is before_begin() or is a dereferenceable iterator in the range [begin(),end()).
6Effects: Inserts a copy of xafter position.
7Returns: An iterator pointing to the copy of x.
§ 23.3.5.5 776
c
ISO/IEC N????
iterator insert_after(const_iterator position, size_type n, const T& x);
8Requires: position is before_begin() or is a dereferenceable iterator in the range [begin(),end()).
9Effects: Inserts ncopies of xafter position.
10 Returns: An iterator pointing to the last inserted copy of xor position if n == 0.
template <class InputIterator>
iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
11 Requires: position is before_begin() or is a dereferenceable iterator in the range [begin(),end()).
first and last are not iterators in *this.
12 Effects: Inserts copies of elements in [first,last) after position.
13 Returns: An iterator pointing to the last inserted element or position if first == last.
iterator insert_after(const_iterator position, initializer_list<T> il);
14 Effects: insert_after(p, il.begin(), il.end()).
15 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);
16 Requires: position is before_begin() or is a dereferenceable iterator in the range [begin(),end()).
17 Effects: Inserts an object of type value_type constructed with value_type(std::forward<Args>(
args)...) after position.
18 Returns: An iterator pointing to the new object.
iterator erase_after(const_iterator position);
19 Requires: The iterator following position is dereferenceable.
20 Effects: Erases the element pointed to by the iterator following position.
21 Returns: An iterator pointing to the element following the one that was erased, or end() if no such
element exists.
22 Throws: Nothing.
iterator erase_after(const_iterator position, const_iterator last);
23 Requires: All iterators in the range (position,last) are dereferenceable.
24 Effects: Erases the elements in the range (position,last).
25 Returns: last.
26 Throws: Nothing.
void resize(size_type sz);
§ 23.3.5.5 777
c
ISO/IEC N????
27 Effects: If sz < distance(begin(), end()), erases the last distance(begin(), end()) - sz ele-
ments from the list. Otherwise, inserts sz - distance(begin(), end()) default-inserted elements
at the end of the list.
28 Requires: Tshall be DefaultInsertable into *this.
void resize(size_type sz, const value_type& c);
29 Effects: If sz < distance(begin(), end()), erases the last distance(begin(), end()) - sz el-
ements from the list. Otherwise, inserts sz - distance(begin(), end()) elements at the end of
the list such that each new element, e, is initialized by a method equivalent to calling allocator_-
traits<allocator_type>::construct(get_allocator(), std::addressof(e), c).
30 Requires: Tshall be CopyInsertable into *this.
void clear() noexcept;
31 Effects: Erases all elements in the range [begin(),end()).
32 Remarks: Does not invalidate past-the-end iterators.
23.3.5.6 forward_list operations [forwardlist.ops]
void splice_after(const_iterator position, forward_list& x);
void splice_after(const_iterator position, forward_list&& x);
1Requires: position is before_begin() or is a dereferenceable iterator in the range [begin(),end()).
get_allocator() == x.get_allocator().&x != this.
2Effects: Inserts the contents of xafter position, and xbecomes empty. Pointers and references to the
moved elements of xnow 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.
3Throws: Nothing.
4Complexity: O(distance(x.begin(), x.end()))
void splice_after(const_iterator position, forward_list& x, const_iterator i);
void splice_after(const_iterator position, forward_list&& x, const_iterator i);
5Requires: position is before_begin() or is a dereferenceable iterator in the range [begin(),end()).
The iterator following iis a dereferenceable iterator in x.get_allocator() == x.get_allocator().
6Effects: Inserts the element following iinto *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.
7Throws: Nothing.
8Complexity: O(1)
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);
§ 23.3.5.6 778
c
ISO/IEC N????
9Requires: 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().
10 Effects: Inserts elements in the range (first,last) after position and removes the elements from x.
Pointers and references to the moved elements of xnow 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.
11 Complexity: O(distance(first, last))
void remove(const T& value);
template <class Predicate> void remove_if(Predicate pred);
12 Effects: Erases all the elements in the list referred by a list iterator ifor 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.
13 Throws: Nothing unless an exception is thrown by the equality comparison or the predicate.
14 Remarks: Stable (17.6.5.7).
15 Complexity: Exactly distance(begin(), end()) applications of the corresponding predicate.
void unique();
template <class BinaryPredicate> void unique(BinaryPredicate pred);
16 Effects: Erases all but the first element from every consecutive group of equal elements referred to
by the iterator iin 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.
17 Throws: Nothing unless an exception is thrown by the equality comparison or the predicate.
18 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)
19 Requires: comp defines a strict weak ordering (25.4), and *this and xare both sorted according to
this ordering. get_allocator() == x.get_allocator().
20 Effects: Merges the two sorted ranges [begin(), end()) and [x.begin(), x.end()).xis 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 xnow 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.
21 Remarks: Stable (17.6.5.7). The behavior is undefined if this->get_allocator() != x.get_allocator().
22 Complexity: At most distance(begin(), end()) + distance(x.begin(), x.end()) - 1 comparisons.
void sort();
template <class Compare> void sort(Compare comp);
§ 23.3.5.6 779
c
ISO/IEC N????
23 Requires: operator< (for the version with no arguments) or comp (for the version with a comparison
argument) defines a strict weak ordering (25.4).
24 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.
25 Remarks: Stable (17.6.5.7).
26 Complexity: Approximately Nlog Ncomparisons, where Nis distance(begin(), end()).
void reverse() noexcept;
27 Effects: Reverses the order of the elements in the list. Does not affect the validity of iterators and
references.
28 Complexity: Linear time.
23.3.5.7 forward_list specialized algorithms [forwardlist.spec]
template <class T, class Allocator>
void swap(forward_list<T,Allocator>& x, forward_list<T,Allocator>& y);
1Effects: x.swap(y)
23.3.6 Class template list [list]
23.3.6.1 Class template list overview [list.overview]
1Alist 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 (23.3.7) and deques (23.3.3), fast random access to list elements is not supported, but many algo-
rithms only need sequential access anyway.
2Alist satisfies all of the requirements of a container, of a reversible container (given in two tables in 23.2),
of a sequence container, including most of the optional sequence container requirements (23.2.3), and of an
allocator-aware container (Table 99). The exceptions are the operator[] and at member functions, which
are not provided.267 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:
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // see 23.2
typedef implementation-defined const_iterator; // see 23.2
typedef implementation-defined size_type; // see 23.2
typedef implementation-defined difference_type;// see 23.2
typedef T value_type;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
267) These member functions are only provided by containers whose iterators are random access iterators.
§ 23.3.6.1 780
c
ISO/IEC N????
// 23.3.6.2, construct/copy/destroy:
explicit list(const Allocator& = 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);
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;
// 23.3.6.3, 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;
// 23.3.6.4, modifiers:
template <class... Args> void emplace_front(Args&&... args);
void pop_front();
template <class... Args> void emplace_back(Args&&... args);
void push_front(const T& x);
§ 23.3.6.1 781
c
ISO/IEC N????
void push_front(T&& x);
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&);
void clear() noexcept;
// 23.3.6.5, 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 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);
§ 23.3.6.1 782
c
ISO/IEC N????
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);
// specialized algorithms:
template <class T, class Allocator>
void swap(list<T,Allocator>& x, list<T,Allocator>& y);
}
23.3.6.2 list constructors, copy, and assignment [list.cons]
explicit list(const Allocator& = Allocator());
1Effects: Constructs an empty list, using the specified allocator.
2Complexity: Constant.
explicit list(size_type n, const Allocator& = Allocator());
3Effects: Constructs a list with ndefault-inserted elements using the specified allocator.
4Requires: Tshall be DefaultInsertable into *this.
5Complexity: Linear in n.
list(size_type n, const T& value,
const Allocator& = Allocator());
6Effects: Constructs a list with ncopies of value, using the specified allocator.
7Requires: Tshall be CopyInsertable into *this.
8Complexity: Linear in n.
template <class InputIterator>
list(InputIterator first, InputIterator last,
const Allocator& = Allocator());
9Effects: Constructs a list equal to the range [first,last).
10 Complexity: Linear in distance(first, last).
23.3.6.3 list capacity [list.capacity]
void resize(size_type sz);
1Effects: 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());
2Requires: Tshall be DefaultInsertable into *this.
void resize(size_type sz, const T& c);
§ 23.3.6.3 783
c
ISO/IEC N????
3Effects:
if (sz > size())
insert(end(), sz-size(), c);
else if (sz < size()) {
iterator i = begin();
advance(i, sz);
erase(i, end());
}
else
;// do nothing
4Requires: Tshall be CopyInsertable into *this.
23.3.6.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> void emplace_front(Args&&... args);
template <class... Args> void 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);
1Remarks: Does not affect the validity of iterators and references. If an exception is thrown there are
no effects.
2Complexity: 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 Tis 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;
3Effects: Invalidates only the iterators and references to the erased elements.
4Throws: Nothing.
5Complexity: 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 Tis exactly equal to the size of the range.
§ 23.3.6.4 784
c
ISO/IEC N????
23.3.6.5 list operations [list.ops]
1Since lists allow fast insertion and erasing from the middle of a list, certain operations are provided specifically
for them.268
2list 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);
3Requires: &x != this.
4Effects: Inserts the contents of xbefore position and xbecomes empty. Pointers and references to
the moved elements of xnow 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.
5Throws: Nothing.
6Complexity: Constant time.
void splice(const_iterator position, list& x, const_iterator i);
void splice(const_iterator position, list&& x, const_iterator i);
7Effects: Inserts an element pointed to by ifrom list xbefore 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 iitself)
continue to refer to the same element, but now behave as iterators into *this, not into x.
8Requires: iis a valid dereferenceable iterator of x.
9Throws: Nothing.
10 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);
11 Effects: Inserts elements in the range [first,last) before position and removes the elements from
x.
12 Requires: [first, last) is a valid range in x. The result is undefined if position is an iterator in
the range [first,last). Pointers and references to the moved elements of xnow 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.
13 Throws: Nothing.
14 Complexity: Constant time if &x == this; otherwise, linear time.
void remove(const T& value);
template <class Predicate> void remove_if(Predicate pred);
268) As specified in 17.6.3.5, the requirements in this Clause apply only to lists whose allocators compare equal.
§ 23.3.6.5 785
c
ISO/IEC N????
15 Effects: Erases all the elements in the list referred by a list iterator ifor which the following conditions
hold: *i == value, pred(*i) != false. Invalidates only the iterators and references to the erased
elements.
16 Throws: Nothing unless an exception is thrown by *i == value or pred(*i) != false.
17 Remarks: Stable (17.6.5.7).
18 Complexity: Exactly size() applications of the corresponding predicate.
void unique();
template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
19 Effects: Erases all but the first element from every consecutive group of equal elements referred to
by the iterator iin 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.
20 Throws: Nothing unless an exception in thrown by *i == *(i-1) or pred(*i, *(i - 1))
21 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);
22 Requires: comp shall define a strict weak ordering (25.4), and both the list and the argument list shall
be sorted according to this ordering.
23 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 xnow 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.
24 Remarks: Stable (17.6.5.7). 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 this->get_allocator()
!= x.get_allocator().
25 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;
26 Effects: Reverses the order of the elements in the list. Does not affect the validity of iterators and
references.
27 Complexity: Linear time.
void sort();
template <class Compare> void sort(Compare comp);
§ 23.3.6.5 786
c
ISO/IEC N????
28 Requires: operator< (for the first version) or comp (for the second version) shall define a strict weak
ordering (25.4).
29 Effects: Sorts the list according to the operator< or a Compare function object. Does not affect the
validity of iterators and references.
30 Remarks: Stable (17.6.5.7).
31 Complexity: Approximately Nlog(N)comparisons, where N == size().
23.3.6.6 list specialized algorithms [list.special]
template <class T, class Allocator>
void swap(list<T,Allocator>& x, list<T,Allocator>& y);
1Effects:
x.swap(y);
23.3.7 Class template vector [vector]
23.3.7.1 Class template vector overview [vector.overview]
1Avector is a sequence container that supports random access iterators. In addition, it 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. The elements of a
vector are stored contiguously, meaning that if vis a vector<T, Allocator> where Tis some type other
than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
2Avector satisfies all of the requirements of a container and of a reversible container (given in two tables
in 23.2), of a sequence container, including most of the optional sequence container requirements (23.2.3), and
of an allocator-aware container (Table 99). 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:
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // see 23.2
typedef implementation-defined const_iterator; // see 23.2
typedef implementation-defined size_type; // see 23.2
typedef implementation-defined difference_type;// see 23.2
typedef T value_type;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// 23.3.7.2, construct/copy/destroy:
explicit vector(const Allocator& = Allocator());
explicit vector(size_type n, const Allocator& = Allocator());
vector(size_type n, const T& value, const Allocator& = Allocator());
template <class InputIterator>
§ 23.3.7.1 787
c
ISO/IEC N????
vector(InputIterator first, InputIterator last,
const Allocator& = Allocator());
vector(const vector& x);
vector(vector&&);
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);
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;
// 23.3.7.3, capacity:
size_type size() const noexcept;
size_type max_size() const noexcept;
void resize(size_type sz);
void resize(size_type sz, const T& c);
size_type capacity() const noexcept;
bool empty() const noexcept;
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;
// 23.3.7.4, data access
T* data() noexcept;
const T* data() const noexcept;
§ 23.3.7.1 788
c
ISO/IEC N????
// 23.3.7.5, modifiers:
template <class... Args> void 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&);
void clear() noexcept;
};
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);
// 23.3.7.6, specialized algorithms:
template <class T, class Allocator>
void swap(vector<T,Allocator>& x, vector<T,Allocator>& y);
}
23.3.7.2 vector constructors, copy, and assignment [vector.cons]
explicit vector(const Allocator& = Allocator());
1Effects: Constructs an empty vector, using the specified allocator.
2Complexity: Constant.
explicit vector(size_type n, const Allocator& = Allocator());
3Effects: Constructs a vector with ndefault-inserted elements using the specified allocator.
4Requires: Tshall be DefaultInsertable into *this.
5Complexity: Linear in n.
vector(size_type n, const T& value,
const Allocator& = Allocator());
§ 23.3.7.2 789
c
ISO/IEC N????
6Effects: Constructs a vector with ncopies of value, using the specified allocator.
7Requires: Tshall be CopyInsertable into *this.
8Complexity: Linear in n.
template <class InputIterator>
vector(InputIterator first, InputIterator last,
const Allocator& = Allocator());
9Effects: Constructs a vector equal to the range [first,last), using the specified allocator.
10 Complexity: Makes only Ncalls to the copy constructor of T(where Nis 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 Ncalls to the copy constructor of Tand order log(N)reallocations if they
are just input iterators.
23.3.7.3 vector capacity [vector.capacity]
size_type capacity() const noexcept;
1Returns: The total number of elements that the vector can hold without requiring reallocation.
void reserve(size_type n);
2Requires: Tshall be MoveInsertable into *this.
3Effects: 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.
4Complexity: It does not change the size of the sequence and takes at most linear time in the size of
the sequence.
5Throws: length_error if n > max_size().269
6Remarks: 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();
7Requires: Tshall be MoveInsertable into *this.
8Complexity: Linear in the size of the sequence.
9Remarks: 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 ] If
an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no
effects.
void swap(vector& x);
269) reserve() uses Allocator::allocate() which may throw an appropriate exception.
§ 23.3.7.3 790
c
ISO/IEC N????
10 Effects: Exchanges the contents and capacity() of *this with that of x.
11 Complexity: Constant time.
void resize(size_type sz);
12 Effects: If sz <= size(), equivalent to calling pop_back() size() - sz times. If size() < sz,
appends sz - size() default-inserted elements to the sequence.
13 Requires: Tshall be MoveInsertable and DefaultInsertable into *this.
14 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);
15 Effects: If sz <= size(), equivalent to calling pop_back() size() - sz times. If size() < sz,
appends sz - size() copies of cto the sequence.
16 Requires: Tshall be MoveInsertable into *this and CopyInsertable into *this.
17 Remarks: If an exception is thrown other than by the move constructor of a non-CopyInsertable T
there are no effects.
23.3.7.4 vector data [vector.data]
T* data() noexcept;
const T* data() const noexcept;
1Returns: A pointer such that [data(),data() + size()) is a valid range. For a non-empty vector,
data() == &front().
2Complexity: Constant time.
23.3.7.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> void 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);
1Remarks: Causes reallocation if the new size is greater than the old capacity. 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 Tor by any InputIterator operation there are no effects. If an exception is thrown by the move
constructor of a non-CopyInsertable T, the effects are unspecified.
2Complexity: The complexity is linear in the number of elements inserted plus the distance to the end
of the vector.
§ 23.3.7.5 791
c
ISO/IEC N????
iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);
3Effects: Invalidates iterators and references at or after the point of the erase.
4Complexity: The destructor of Tis called the number of times equal to the number of the elements
erased, but the move assignment operator of Tis called the number of times equal to the number of
elements in the vector after the erased elements.
5Throws: Nothing unless an exception is thrown by the copy constructor, move constructor, assignment
operator, or move assignment operator of T.
23.3.7.6 vector specialized algorithms [vector.special]
template <class T, class Allocator>
void swap(vector<T,Allocator>& x, vector<T,Allocator>& y);
1Effects:
x.swap(y);
23.3.8 Class vector<bool> [vector.bool]
1To optimize space allocation, a specialization of vector for bool elements is provided:
namespace std {
template <class Allocator> class vector<bool, Allocator> {
public:
// types:
typedef bool const_reference;
typedef implementation-defined iterator; // see 23.2
typedef implementation-defined const_iterator; // see 23.2
typedef implementation-defined size_type; // see 23.2
typedef implementation-defined difference_type;// see 23.2
typedef bool value_type;
typedef Allocator allocator_type;
typedef implementation-defined pointer;
typedef implementation-defined const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_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:
explicit vector(const Allocator& = Allocator());
explicit vector(size_type n, const Allocator& = Allocator());
vector(size_type n, const bool& value,
const Allocator& = Allocator());
§ 23.3.8 792
c
ISO/IEC N????
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:
size_type size() const noexcept;
size_type max_size() const noexcept;
void resize(size_type sz, bool c = false);
size_type capacity() const noexcept;
bool empty() const noexcept;
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> void emplace_back(Args&&... args);
void push_back(const bool& x);
§ 23.3.8 793
c
ISO/IEC N????
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;
};
}
2Unless 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 (20.8.8.2) is not used to construct these values.
3There is no requirement that the data be stored as a contiguous allocation of bool values. A space-optimized
representation of bits is recommended instead.
4reference is a class that simulates the behavior of references of a single bit in vector<bool>. The conversion
operator 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;
5Effects: Replaces each element in the container with its complement.
static void swap(reference x, reference y) noexcept;
6Effects: exchanges the contents of xand yas if by
bool b = x;
x = y;
y = b;
template <class Allocator> struct hash<vector<bool, Allocator> >;
7The template specialization shall meet the requirements of class template hash (20.10.12).
23.4 Associative containers [associative]
23.4.1 In general [associative.general]
1The header <map> defines the class templates map and multimap; the header <set> defines the class templates
set and multiset.
23.4.2 Header <map> synopsis [associative.map.syn]
#include <initializer_list>
namespace std {
§ 23.4.2 794
c
ISO/IEC N????
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);
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);
}
23.4.3 Header <set> synopsis [associative.set.syn]
#include <initializer_list>
namespace std {
§ 23.4.3 795
c
ISO/IEC N????
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);
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);
}
23.4.4 Class template map [map]
23.4.4.1 Class template map overview [map.overview]
1Amap is an associative container that supports unique keys (contains at most one of each key value) and
§ 23.4.4.1 796
c
ISO/IEC N????
provides for fast retrieval of values of another type Tbased on the keys. The map class supports bidirectional
iterators.
2Amap satisfies all of the requirements of a container, of a reversible container (23.2), of an associative
container (23.2.4), and of an allocator-aware container (Table 99). A map also provides most operations
described in (23.2.4) for unique keys. This means that a map supports the a_uniq operations in (23.2.4)
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:
typedef Key key_type;
typedef T mapped_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // see 23.2
typedef implementation-defined const_iterator; // see 23.2
typedef implementation-defined size_type; // see 23.2
typedef implementation-defined difference_type;// see 23.2
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
class value_compare {
friend class map;
protected:
Compare comp;
value_compare(Compare c) : comp(c) {}
public:
typedef bool result_type;
typedef value_type first_argument_type;
typedef value_type second_argument_type;
bool operator()(const value_type& x, const value_type& y) const {
return comp(x.first, y.first);
}
};
// 23.4.4.2, construct/copy/destroy:
explicit map(const Compare& comp = Compare(),
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&);
§ 23.4.4.1 797
c
ISO/IEC N????
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);
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;
// 23.4.4.3, 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;
// 23.4.4.4, 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);
template <class P> pair<iterator, bool> insert(P&& x);
iterator insert(const_iterator position, const 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>);
iterator erase(const_iterator position);
§ 23.4.4.1 798
c
ISO/IEC N????
size_type erase(const key_type& x);
iterator erase(const_iterator first, const_iterator last);
void swap(map&);
void clear() noexcept;
// observers:
key_compare key_comp() const;
value_compare value_comp() const;
// 23.4.4.5, 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 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,
§ 23.4.4.1 799
c
ISO/IEC N????
const map<Key,T,Compare,Allocator>& y);
// 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);
}
23.4.4.2 map constructors, copy, and assignment [map.cons]
explicit map(const Compare& comp = Compare(),
const Allocator& = Allocator());
1Effects: Constructs an empty map using the specified comparison object and allocator.
2Complexity: Constant.
template <class InputIterator>
map(InputIterator first, InputIterator last,
const Compare& comp = Compare(), const Allocator& = Allocator());
3Requires: If the iterator’s indirection operator returns an lvalue or a const rvalue pair<key_type,
mapped_type>, then both key_type and mapped_type shall be CopyInsertable into *this.
4Effects: Constructs an empty map using the specified comparison object and allocator, and inserts
elements from the range [first,last).
5Complexity: Linear in Nif the range [first,last) is already sorted using comp and otherwise Nlog N,
where Nis last -first.
23.4.4.3 map element access [map.access]
T& operator[](const key_type& x);
1Effects: If there is no key equivalent to xin the map, inserts value_type(x, T()) into the map.
2Requires: key_type shall be CopyInsertable and mapped_type shall be DefaultInsertable into
*this.
3Returns: A reference to the mapped_type corresponding to xin *this.
4Complexity: logarithmic.
T& operator[](key_type&& x);
5Effects: If there is no key equivalent to xin the map, inserts value_type(std::move(x), T()) into
the map.
6Requires: mapped_type shall be DefaultInsertable into *this.
7Returns: A reference to the mapped_type corresponding to xin *this.
8Complexity: logarithmic.
T& at(const key_type& x);
const T& at(const key_type& x) const;
9Returns: A reference to the mapped_type corresponding to xin *this.
10 Throws: An exception object of type out_of_range if no such element is present.
11 Complexity: logarithmic.
§ 23.4.4.3 800
c
ISO/IEC N????
23.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);
template <class InputIterator>
void insert(InputIterator first, InputIterator last);
1Effects: 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)).
2Remarks: These signatures shall not participate in overload resolution unless std::is_constructible<value_-
type, P&&>::value is true.
23.4.4.5 map operations [map.ops]
iterator find(const key_type& x);
const_iterator find(const key_type& x) const;
iterator lower_bound(const key_type& x);
const_iterator lower_bound(const key_type& x) const;
iterator upper_bound(const key_type& x);
const_iterator upper_bound(const key_type &x) const;
pair<iterator, iterator>
equal_range(const key_type &x);
pair<const_iterator, const_iterator>
equal_range(const key_type& x) const;
1The find,lower_bound,upper_bound and equal_range member functions each have two versions,
one const and the other non-const. In each case the behavior of the two functions is identical except
that the const version returns a const_iterator and the non-const version an iterator (23.2.4).
23.4.4.6 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);
1Effects:
x.swap(y);
23.4.5 Class template multimap [multimap]
23.4.5.1 Class template multimap overview [multimap.overview]
1Amultimap 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 Tbased on the keys. The
multimap class supports bidirectional iterators.
2Amultimap satisfies all of the requirements of a container and of a reversible container (23.2), of an asso-
ciative container (23.2.4), and of an allocator-aware container (Table 99). A multimap also provides most
operations described in (23.2.4) for equal keys. This means that a multimap supports the a_eq operations
in (23.2.4) 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>,
§ 23.4.5.1 801
c
ISO/IEC N????
class Allocator = allocator<pair<const Key, T> > >
class multimap {
public:
// types:
typedef Key key_type;
typedef T mapped_type;
typedef pair<const Key,T> value_type;
typedef Compare key_compare;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // see 23.2
typedef implementation-defined const_iterator; // see 23.2
typedef implementation-defined size_type; // see 23.2
typedef implementation-defined difference_type;// see 23.2
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
class value_compare {
friend class multimap;
protected:
Compare comp;
value_compare(Compare c) : comp(c) { }
public:
typedef bool result_type;
typedef value_type first_argument_type;
typedef value_type second_argument_type;
bool operator()(const value_type& x, const value_type& y) const {
return comp(x.first, y.first);
}
};
// construct/copy/destroy:
explicit multimap(const Compare& comp = Compare(),
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();
§ 23.4.5.1 802
c
ISO/IEC N????
multimap& operator=(const multimap& x);
multimap& operator=(multimap&& x);
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;
// 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);
template <class P> iterator insert(P&& x);
iterator insert(const_iterator position, const 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>);
iterator erase(const_iterator position);
size_type erase(const key_type& x);
iterator erase(const_iterator first, const_iterator last);
void swap(multimap&);
void clear() noexcept;
// 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;
§ 23.4.5.1 803
c
ISO/IEC N????
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 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);
// 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);
}
23.4.5.2 multimap constructors [multimap.cons]
explicit multimap(const Compare& comp = Compare(),
const Allocator& = Allocator());
1Effects: Constructs an empty multimap using the specified comparison object and allocator.
2Complexity: Constant.
template <class InputIterator>
§ 23.4.5.2 804
c
ISO/IEC N????
multimap(InputIterator first, InputIterator last,
const Compare& comp = Compare(),
const Allocator& = Allocator());
3Requires: If the iterator’s indirection operator returns an lvalue or a const rvalue pair<key_type,
mapped_type>, then both key_type and mapped_type shall be CopyInsertable into *this.
4Effects: Constructs an empty multimap using the specified comparison object and allocator, and inserts
elements from the range [first,last).
5Complexity: Linear in Nif the range [first,last) is already sorted using comp and otherwise Nlog N,
where Nis last - first.
23.4.5.3 multimap modifiers [multimap.modifiers]
template <class P> iterator insert(P&& x);
template <class P> iterator insert(const_iterator position, P&& x);
1Effects: 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)).
2Remarks: These signatures shall not participate in overload resolution unless std::is_constructible<value_-
type, P&&>::value is true.
23.4.5.4 multimap operations [multimap.ops]
iterator find(const key_type &x);
const_iterator find(const key_type& x) const;
iterator lower_bound(const key_type& x);
const_iterator lower_bound(const key_type& x) const;
pair<iterator, iterator>
equal_range(const key_type& x);
pair<const_iterator, const_iterator>
equal_range(const key_type& x) const;
1The find,lower_bound,upper_bound, and equal_range member functions each have two versions,
one const and one non-const. In each case the behavior of the two versions is identical except that the
const version returns a const_iterator and the non-const version an iterator (23.2.4).
23.4.5.5 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);
1Effects:
x.swap(y);
23.4.6 Class template set [set]
23.4.6.1 Class template set overview [set.overview]
1Aset 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.
2Aset satisfies all of the requirements of a container, of a reversible container (23.2), of an associative
container (23.2.4), and of an allocator-aware container (Table 99). A set also provides most operations
§ 23.4.6.1 805
c
ISO/IEC N????
described in (23.2.4) for unique keys. This means that a set supports the a_uniq operations in (23.2.4) 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:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // See 23.2
typedef implementation-defined const_iterator; // See 23.2
typedef implementation-defined size_type; // See 23.2
typedef implementation-defined difference_type;// See 23.2
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// 23.4.6.2, construct/copy/destroy:
explicit set(const Compare& comp = Compare(),
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);
set& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
// iterators:
iterator begin() noexcept;
const_iterator begin() const noexcept;
§ 23.4.6.1 806
c
ISO/IEC N????
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>);
iterator erase(const_iterator position);
size_type erase(const key_type& x);
iterator erase(const_iterator first, const_iterator last);
void swap(set&);
void clear() noexcept;
// 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;
§ 23.4.6.1 807
c
ISO/IEC N????
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 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);
// specialized algorithms:
template <class Key, class Compare, class Allocator>
void swap(set<Key,Compare,Allocator>& x,
set<Key,Compare,Allocator>& y);
}
23.4.6.2 set constructors, copy, and assignment [set.cons]
explicit set(const Compare& comp = Compare(),
const Allocator& = Allocator());
1Effects: Constructs an empty set using the specified comparison objects and allocator.
2Complexity: Constant.
template <class InputIterator>
set(InputIterator first, InputIterator last,
const Compare& comp = Compare(), const Allocator& = Allocator());
3Effects: Constructs an empty set using the specified comparison object and allocator, and inserts
elements from the range [first,last).
4Requires: If the iterator’s indirection operator returns an lvalue or a non-const rvalue, then Key shall
be CopyInsertable into *this.
5Complexity: Linear in Nif the range [first,last) is already sorted using comp and otherwise Nlog N,
where Nis last - first.
§ 23.4.6.2 808
c
ISO/IEC N????
23.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);
1Effects:
x.swap(y);
23.4.7 Class template multiset [multiset]
23.4.7.1 Class template multiset overview [multiset.overview]
1Amultiset 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.
2Amultiset satisfies all of the requirements of a container, of a reversible container (23.2), of an associative
container (23.2.4), and of an allocator-aware container (Table 99). multiset also provides most opera-
tions described in (23.2.4) for duplicate keys. This means that a multiset supports the a_eq operations
in (23.2.4) 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:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined iterator; // see 23.2
typedef implementation-defined const_iterator; // see 23.2
typedef implementation-defined size_type; // see 23.2
typedef implementation-defined difference_type;// see 23.2
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// construct/copy/destroy:
explicit multiset(const Compare& comp = Compare(),
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&);
§ 23.4.7.1 809
c
ISO/IEC N????
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);
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>);
iterator erase(const_iterator position);
size_type erase(const key_type& x);
iterator erase(const_iterator first, const_iterator last);
void swap(multiset&);
void clear() noexcept;
// observers:
key_compare key_comp() const;
§ 23.4.7.1 810
c
ISO/IEC N????
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 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);
// specialized algorithms:
template <class Key, class Compare, class Allocator>
void swap(multiset<Key,Compare,Allocator>& x,
multiset<Key,Compare,Allocator>& y);
}
23.4.7.2 multiset constructors [multiset.cons]
§ 23.4.7.2 811
c
ISO/IEC N????
explicit multiset(const Compare& comp = Compare(),
const Allocator& = Allocator());
1Effects: Constructs an empty set using the specified comparison object and allocator.
2Complexity: Constant.
template <class InputIterator>
multiset(InputIterator first, last,
const Compare& comp = Compare(), const Allocator& = Allocator());
3Requires: If the iterator’s indirection operator returns an lvalue or a const rvalue, then Key shall be
CopyInsertable into *this.
4Effects: Constructs an empty multiset using the specified comparison object and allocator, and inserts
elements from the range [first,last).
5Complexity: Linear in Nif the range [first,last) is already sorted using comp and otherwise Nlog N,
where Nis last - first.
23.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);
1Effects:
x.swap(y);
23.5 Unordered associative containers [unord]
23.5.1 In general [unord.general]
1The 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.
23.5.2 Header <unordered_map> synopsis [unord.map.syn]
#include <initializer_list>
namespace std {
// 23.5.4, class template unordered_map:
template <class Key,
class T,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
class unordered_map;
// 23.5.5, class template unordered_multimap:
template <class Key,
class T,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
class unordered_multimap;
§ 23.5.2 812
c
ISO/IEC N????
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);
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);
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 std
23.5.3 Header <unordered_set> synopsis [unord.set.syn]
#include <initializer_list>
namespace std {
// 23.5.6, class template unordered_set:
template <class Key,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class unordered_set;
// 23.5.7, class template unordered_multiset:
template <class Key,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::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);
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);
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);
§ 23.5.3 813
c
ISO/IEC N????
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 std
23.5.4 Class template unordered_map [unord.map]
23.5.4.1 Class template unordered_map overview [unord.map.overview]
1An 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.
2An unordered_map satisfies all of the requirements of a container, of an unordered associative container, and
of an allocator-aware container (Table 99). 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 std::pair<const Key, T>.
3This 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 = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<const Key, T> > >
class unordered_map
{
public:
// types
typedef Key key_type;
typedef std::pair<const Key, T> value_type;
typedef T mapped_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined size_type;
typedef implementation-defined difference_type;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef implementation-defined local_iterator;
typedef implementation-defined const_local_iterator;
// construct/destroy/copy
explicit unordered_map(size_type n = see below ,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
template <class InputIterator>
§ 23.5.4.1 814
c
ISO/IEC N????
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>,
size_type = 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&&);
unordered_map& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
// size and capacity
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() 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;
// 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);
template <class P> pair<iterator, bool> insert(P&& obj);
§ 23.5.4.1 815
c
ISO/IEC N????
iterator insert(const_iterator hint, const 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>);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(unordered_map&);
// observers
hasher hash_function() const;
key_equal key_eq() const;
// lookup
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
size_type count(const key_type& k) const;
std::pair<iterator, iterator> equal_range(const key_type& k);
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
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 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);
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);
§ 23.5.4.1 816
c
ISO/IEC N????
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);
}
23.5.4.2 unordered_map constructors [unord.map.cnstr]
explicit unordered_map(size_type n = see below ,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
1Effects: Constructs an empty unordered_map using the specified hash function, key equality func-
tion, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. max_load_factor() returns 1.0.
2Complexity: 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());
3Effects: Constructs an empty unordered_map using the specified hash function, key equality func-
tion, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. Then inserts elements from the range [f,l).max_load_factor() returns
1.0.
4Complexity: Average case linear, worst case quadratic.
23.5.4.3 unordered_map element access [unord.map.elem]
mapped_type& operator[](const key_type& k);
mapped_type& operator[](key_type&& k);
1Requires: mapped_type shall be DefaultInsertable into *this. For the first operator, key_type shall
be CopyInsertable into *this. For the second operator, key_type shall be MoveConstructible.
2Effects: If the unordered_map does not already contain an element whose key is equivalent to k, the
first operator inserts the value value_type(k, mapped_type()) and the second operator inserts the
value value_type(std::move(k), mapped_type()).
3Returns: A reference to x.second, where xis the (unique) element whose key is equivalent to k.
4Complexity: Average case O(1), worst case O(size()).
mapped_type& at(const key_type& k);
const mapped_type& at(const key_type& k) const;
5Returns: A reference to x.second, where xis the (unique) element whose key is equivalent to k.
6Throws: An exception object of type out_of_range if no such element is present.
§ 23.5.4.3 817
c
ISO/IEC N????
23.5.4.4 unordered_map modifiers [unord.map.modifiers]
template <class P>
pair<iterator, bool> insert(P&& obj);
1Effects: Equivalent to return emplace(std::forward<P>(obj)).
2Remarks: This signature shall not participate in overload resolution unless std::is_constructible<value_-
type, P&&>::value is true.
template <class P>
iterator insert(const_iterator hint, P&& obj);
3Effects: Equivalent to return emplace_hint(hint, std::forward<P>(obj)).
4Remarks: This signature shall not participate in overload resolution unless std::is_constructible<value_-
type, P&&>::value is true.
23.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);
1Effects: x.swap(y).
23.5.5 Class template unordered_multimap [unord.multimap]
23.5.5.1 Class template unordered_multimap overview [unord.multimap.overview]
1An 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.
2An unordered_multimap satisfies all of the requirements of a container, of an unordered associative con-
tainer, and of an allocator-aware container (Table 99). 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 std::pair<const Key, T>.
3This section only describes operations on unordered_multimap that are not described in one of the require-
ment tables, or for which there is additional semantic information.
namespace std {
template <class Key,
class T,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<const Key, T> > >
class unordered_multimap
{
public:
// types
typedef Key key_type;
typedef std::pair<const Key, T> value_type;
typedef T mapped_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
§ 23.5.5.1 818
c
ISO/IEC N????
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined size_type;
typedef implementation-defined difference_type;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef implementation-defined local_iterator;
typedef implementation-defined const_local_iterator;
// construct/destroy/copy
explicit unordered_multimap(size_type n = see below ,
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>,
size_type = 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&&);
unordered_multimap& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
// size and capacity
§ 23.5.5.1 819
c
ISO/IEC N????
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() 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;
// 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);
template <class P> iterator insert(P&& obj);
iterator insert(const_iterator hint, const 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>);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(unordered_multimap&);
// observers
hasher hash_function() const;
key_equal key_eq() const;
// lookup
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
size_type count(const key_type& k) const;
std::pair<iterator, iterator> equal_range(const key_type& k);
std::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;
§ 23.5.5.1 820
c
ISO/IEC N????
void max_load_factor(float z);
void rehash(size_type n);
void reserve(size_type n);
};
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);
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);
}
23.5.5.2 unordered_multimap constructors [unord.multimap.cnstr]
explicit unordered_multimap(size_type n = see below ,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
1Effects: Constructs an empty unordered_multimap using the specified hash function, key equality
function, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. max_load_factor() returns 1.0.
2Complexity: 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());
3Effects: Constructs an empty unordered_multimap using the specified hash function, key equality
function, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. Then inserts elements from the range [f,l).max_load_factor() returns
1.0.
4Complexity: Average case linear, worst case quadratic.
23.5.5.3 unordered_multimap modifiers [unord.multimap.modifiers]
template <class P>
iterator insert(P&& obj);
1Effects: Equivalent to return emplace(std::forward<P>(obj)).
2Remarks: This signature shall not participate in overload resolution unless std::is_constructible<value_-
type, P&&>::value is true.
template <class P>
iterator insert(const_iterator hint, P&& obj);
§ 23.5.5.3 821
c
ISO/IEC N????
3Effects: Equivalent to return emplace_hint(hint, std::forward<P>(obj)).
4Remarks: This signature shall not participate in overload resolution unless std::is_constructible<value_-
type, P&&>::value is true.
23.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);
1Effects: x.swap(y).
23.5.6 Class template unordered_set [unord.set]
23.5.6.1 Class template unordered_set overview [unord.set.overview]
1An 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.
2An unordered_set satisfies all of the requirements of a container, of an unordered associative container, and
of an allocator-aware container (Table 99). 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 const iterator types. It is unspecified whether they are the same type.
3This 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 = std::equal_to<Key>,
class Allocator = std::allocator<Key> >
class unordered_set
{
public:
// types
typedef Key key_type;
typedef Key value_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined size_type;
typedef implementation-defined difference_type;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef implementation-defined local_iterator;
typedef implementation-defined const_local_iterator;
// construct/destroy/copy
explicit unordered_set(size_type n = see below ,
const hasher& hf = hasher(),
§ 23.5.6.1 822
c
ISO/IEC N????
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>,
size_type = 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&&);
unordered_set& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
// size and capacity
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() 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;
// modifiers
template <class... Args> pair<iterator, bool> emplace(Args&&... args);
§ 23.5.6.1 823
c
ISO/IEC N????
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>);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(unordered_set&);
// observers
hasher hash_function() const;
key_equal key_eq() const;
// lookup
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
size_type count(const key_type& k) const;
std::pair<iterator, iterator> equal_range(const key_type& k);
std::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 Key, class Hash, class Pred, class Alloc>
void swap(unordered_set<Key, Hash, Pred, Alloc>& x,
unordered_set<Key, Hash, Pred, Alloc>& 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,
§ 23.5.6.1 824
c
ISO/IEC N????
const unordered_set<Key, Hash, Pred, Alloc>& b);
}
23.5.6.2 unordered_set constructors [unord.set.cnstr]
explicit unordered_set(size_type n = see below ,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
1Effects: Constructs an empty unordered_set using the specified hash function, key equality func-
tion, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. max_load_factor() returns 1.0.
2Complexity: 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());
3Effects: Constructs an empty unordered_set using the specified hash function, key equality func-
tion, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. Then inserts elements from the range [f,l).max_load_factor() returns
1.0.
4Complexity: Average case linear, worst case quadratic.
23.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);
1Effects: x.swap(y).
23.5.7 Class template unordered_multiset [unord.multiset]
23.5.7.1 Class template unordered_multiset overview [unord.multiset.overview]
1An 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.
2An unordered_multiset satisfies all of the requirements of a container, of an unordered associative con-
tainer, and of an allocator-aware container (Table 99). 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 const iterator types. It is unspecified
whether they are the same type.
3This section only describes operations on unordered_multiset that are not described in one of the require-
ment tables, or for which there is additional semantic information.
namespace std {
template <class Key,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
§ 23.5.7.1 825
c
ISO/IEC N????
class Allocator = std::allocator<Key> >
class unordered_multiset
{
public:
// types
typedef Key key_type;
typedef Key value_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Allocator allocator_type;
typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef implementation-defined size_type;
typedef implementation-defined difference_type;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef implementation-defined local_iterator;
typedef implementation-defined const_local_iterator;
// construct/destroy/copy
explicit unordered_multiset(size_type n = see below ,
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>,
size_type = 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)
§ 23.5.7.1 826
c
ISO/IEC N????
: 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&&);
unordered_multiset& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
// size and capacity
bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() 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;
// 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>);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(unordered_multiset&);
// observers
hasher hash_function() const;
key_equal key_eq() const;
// lookup
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
size_type count(const key_type& k) const;
std::pair<iterator, iterator> equal_range(const key_type& k);
std::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;
§ 23.5.7.1 827
c
ISO/IEC N????
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 Key, class Hash, class Pred, class Alloc>
void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x,
unordered_multiset<Key, Hash, Pred, Alloc>& y);
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);
}
23.5.7.2 unordered_multiset constructors [unord.multiset.cnstr]
explicit unordered_multiset(size_type n = see below ,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
1Effects: Constructs an empty unordered_multiset using the specified hash function, key equality
function, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. max_load_factor() returns 1.0.
2Complexity: 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());
3Effects: Constructs an empty unordered_multiset using the specified hash function, key equality
function, and allocator, and using at least nbuckets. If nis not provided, the number of buckets is
implementation-defined. Then inserts elements from the range [f,l).max_load_factor() returns
1.0.
4Complexity: Average case linear, worst case quadratic.
23.5.7.3 unordered_multiset swap [unord.multiset.swap]
§ 23.5.7.3 828
c
ISO/IEC N????
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);
1Effects: x.swap(y);
23.6 Container adaptors [container.adaptors]
23.6.1 In general [container.adaptors.general]
1The headers <queue> and <stack> define the container adaptors queue,priority_queue, and stack. These
container adaptors meet the requirements for sequence containers.
2The 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.
3For 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).
23.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)));
}
23.6.3 Class template queue [queue]
23.6.3.1 queue definition [queue.defn]
1Any sequence container supporting operations front(),back(),push_back() and pop_front() can be
used to instantiate queue. In particular, list (23.3.6) and deque (23.3.3) can be used.
namespace std {
§ 23.6.3.1 829
c
ISO/IEC N????
template <class T, class Container = deque<T> >
class queue {
public:
typedef typename Container::value_type value_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::size_type size_type;
typedef Container container_type;
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> void emplace(Args&&... args)
{ c.emplace_back(std::forward<Args>(args)...); }
void pop() { c.pop_front(); }
void swap(queue& q) noexcept(noexcept(swap(c, q.c)))
{ using std::swap; swap(c, q.c); }
};
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 { };
}
§ 23.6.3.1 830
c
ISO/IEC N????
23.6.3.2 queue constructors [queue.cons]
explicit queue(const Container& cont);
1Effects: Initializes cwith cont.
explicit queue(Container&& cont = Container());
2Effects: Initializes cwith std::move(cont).
23.6.3.3 queue constructors with allocators [queue.cons.alloc]
1If uses_allocator<container_type, Alloc>::value is false the constructors in this subclause shall not
participate in overload resolution.
template <class Alloc>
explicit queue(const Alloc& a);
2Effects: Initializes cwith a.
template <class Alloc>
queue(const container_type& cont, const Alloc& a);
3Effects: Initializes cwith cont as the first argument and aas the second argument.
template <class Alloc>
queue(container_type&& cont, const Alloc& a);
4Effects: Initializes cwith std::move(cont) as the first argument and aas the second argument.
template <class Alloc>
queue(const queue& q, const Alloc& a);
5Effects: Initializes cwith q.c as the first argument and aas the second argument.
template <class Alloc>
queue(queue&& q, const Alloc& a);
6Effects: Initializes cwith std::move(q.c) as the first argument and aas the second argument.
23.6.3.4 queue operators [queue.ops]
template <class T, class Container>
bool operator==(const queue<T, Container>& x,
const queue<T, Container>& y);
1Returns: x.c == y.c.
template <class T, class Container>
bool operator!=(const queue<T, Container>& x,
const queue<T, Container>& y);
2Returns: x.c != y.c.
§ 23.6.3.4 831
c
ISO/IEC N????
template <class T, class Container>
bool operator< (const queue<T, Container>& x,
const queue<T, Container>& y);
3Returns: x.c < y.c.
template <class T, class Container>
bool operator<=(const queue<T, Container>& x,
const queue<T, Container>& y);
4Returns: x.c <= y.c.
template <class T, class Container>
bool operator> (const queue<T, Container>& x,
const queue<T, Container>& y);
5Returns: x.c > y.c.
template <class T, class Container>
bool operator>=(const queue<T, Container>& x,
const queue<T, Container>& y);
6Returns: x.c >= y.c.
23.6.3.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)));
1Effects: x.swap(y).
23.6.4 Class template priority_queue [priority.queue]
1Any 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 (23.3.7) and deque (23.3.3)
can be used. Instantiating priority_queue also involves supplying a function or function object for mak-
ing priority comparisons; the library assumes that the function or function object defines a strict weak
ordering (25.4).
namespace std {
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> >
class priority_queue {
public:
typedef typename Container::value_type value_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::size_type size_type;
typedef Container container_type;
protected:
Container c;
Compare comp;
public:
priority_queue(const Compare& x, const Container&);
§ 23.6.4 832
c
ISO/IEC N????
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(
noexcept(swap(c, q.c)) && noexcept(swap(comp, q.comp)))
{ using std::swap; swap(c, q.c); swap(comp, q.comp); }
};
// 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 { };
}
23.6.4.1 priority_queue constructors [priqueue.cons]
priority_queue(const Compare& x,
const Container& y);
explicit priority_queue(const Compare& x = Compare(),
Container&& y = Container());
1Requires: xshall define a strict weak ordering (25.4).
2Effects: Initializes comp with xand cwith 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());
§ 23.6.4.1 833
c
ISO/IEC N????
3Requires: xshall define a strict weak ordering (25.4).
4Effects: Initializes comp with xand cwith 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).
23.6.4.2 priority_queue constructors with allocators [priqueue.cons.alloc]
1If uses_allocator<container_type, Alloc>::value is false the constructors in this subclause shall not
participate in overload resolution.
template <class Alloc>
explicit priority_queue(const Alloc& a);
2Effects: Initializes cwith aand value-initializes comp.
template <class Alloc>
priority_queue(const Compare& compare, const Alloc& a);
3Effects: Initializes cwith aand initializes comp with compare.
template <class Alloc>
priority_queue(const Compare& compare, const Container& cont, const Alloc& a);
4Effects: Initializes cwith cont as the first argument and aas the second argument, and initializes comp
with compare.
template <class Alloc>
priority_queue(const Compare& compare, Container&& cont, const Alloc& a);
5Effects: Initializes cwith std::move(cont) as the first argument and aas the second argument, and
initializes comp with compare.
template <class Alloc>
priority_queue(const priority_queue& q, const Alloc& a);
6Effects: Initializes cwith q.c as the first argument and aas the second argument, and initializes comp
with q.comp.
template <class Alloc>
priority_queue(priority_queue&& q, const Alloc& a);
7Effects: Initializes cwith std::move(q.c) as the first argument and aas the second argument, and
initializes comp with std::move(q.comp).
23.6.4.3 priority_queue members [priqueue.members]
void push(const value_type& x);
1Effects:
c.push_back(x);
push_heap(c.begin(), c.end(), comp);
void push(value_type&& x);
§ 23.6.4.3 834
c
ISO/IEC N????
2Effects:
c.push_back(std::move(x));
push_heap(c.begin(), c.end(), comp);
template <class... Args> void emplace(Args&&... args)
3Effects:
c.emplace_back(std::forward<Args>(args)...);
push_heap(c.begin(), c.end(), comp);
void pop();
4Effects:
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
23.6.4.4 priority_queue specialized algorithms [priqueue.special]
template <class T, class Container, Compare>
void swap(priority_queue<T, Container, Compare>& x,
priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y)));
1Effects: x.swap(y).
23.6.5 Class template stack [stack]
1Any sequence container supporting operations back(),push_back() and pop_back() can be used to in-
stantiate stack. In particular, vector (23.3.7), list (23.3.6) and deque (23.3.3) can be used.
23.6.5.1 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)));
}
23.6.5.2 stack definition [stack.defn]
§ 23.6.5.2 835
c
ISO/IEC N????
namespace std {
template <class T, class Container = deque<T> >
class stack {
public:
typedef typename Container::value_type value_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::size_type size_type;
typedef Container container_type;
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> void emplace(Args&&... args)
{ c.emplace_back(std::forward<Args>(args)...); }
void pop() { c.pop_back(); }
void swap(stack& s) noexcept(noexcept(swap(c, s.c)))
{ using std::swap; swap(c, s.c); }
};
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 Allocator>
void swap(stack<T,Allocator>& x, stack<T,Allocator>& y);
template <class T, class Container, class Alloc>
struct uses_allocator<stack<T, Container>, Alloc>
: uses_allocator<Container, Alloc>::type { };
}
23.6.5.3 stack constructors [stack.cons]
§ 23.6.5.3 836
c
ISO/IEC N????
explicit stack(const Container& cont);
1Effects: Initializes cwith cont.
explicit stack(Container&& cont = Container());
2Effects: Initializes cwith std::move(cont).
23.6.5.4 stack constructors with allocators [stack.cons.alloc]
1If uses_allocator<container_type, Alloc>::value is false the constructors in this subclause shall not
participate in overload resolution.
template <class Alloc>
explicit stack(const Alloc& a);
2Effects: Initializes cwith a.
template <class Alloc>
stack(const container_type& cont, const Alloc& a);
3Effects: Initializes cwith cont as the first argument and aas the second argument.
template <class Alloc>
stack(container_type&& cont, const Alloc& a);
4Effects: Initializes cwith std::move(cont) as the first argument and aas the second argument.
template <class Alloc>
stack(const stack& s, const Alloc& a);
5Effects: Initializes cwith s.c as the first argument and aas the second argument.
template <class Alloc>
stack(stack&& s, const Alloc& a);
6Effects: Initializes cwith std::move(s.c) as the first argument and aas the second argument.
23.6.5.5 stack operators [stack.ops]
template <class T, class Container>
bool operator==(const stack<T, Container>& x,
const stack<T, Container>& y);
1Returns: x.c == y.c.
template <class T, class Container>
bool operator!=(const stack<T, Container>& x,
const stack<T, Container>& y);
2Returns: x.c != y.c.
§ 23.6.5.5 837
c
ISO/IEC N????
template <class T, class Container>
bool operator< (const stack<T, Container>& x,
const stack<T, Container>& y);
3Returns: x.c < y.c.
template <class T, class Container>
bool operator<=(const stack<T, Container>& x,
const stack<T, Container>& y);
4Returns: x.c <= y.c.
template <class T, class Container>
bool operator> (const stack<T, Container>& x,
const stack<T, Container>& y);
5Returns: x.c > y.c.
template <class T, class Container>
bool operator>=(const stack<T, Container>& x,
const stack<T, Container>& y);
6Returns: x.c >= y.c.
23.6.5.6 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)));
1Effects: x.swap(y).
§ 23.6.5.6 838
c
ISO/IEC N????
24 Iterators library [iterators]
24.1 General [iterators.general]
1This Clause describes components that C++ programs may use to perform iterations over containers (Clause
23), streams (27.7), and stream buffers (27.6).
2The following subclauses describe iterator requirements, and components for iterator primitives, predefined
iterators, and stream iterators, as summarized in Table 104.
Table 104 — Iterators library summary
Subclause Header(s)
24.2 Requirements
24.4 Iterator primitives <iterator>
24.5 Predefined iterators
24.6 Stream iterators
24.2 Iterator requirements [iterator.requirements]
24.2.1 In general [iterator.requirements.general]
1Iterators 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. All input iterators isupport the expression *i, resulting
in a value of some object type T, called the value type of the iterator. All output iterators support the
expression *i = o where ois a value of some type that is in the set of types that are writable to the
particular iterator type of i. All iterators ifor which the expression (*i).m is well-defined, support the
expression i->m with the same semantics as (*i).m. For every iterator type Xfor which equality is defined,
there is a corresponding signed integer type called the difference type of the iterator.
2Since 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 105.
Table 105 — Relations among iterator categories
Random Access Bidirectional Forward Input
Output
3Forward 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 when-
ever 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.
4Iterators that further satisfy the requirements of output iterators are called mutable iterators. Nonmutable
iterators are referred to as constant iterators.
§ 24.2.1 839
c
ISO/IEC N????
5Just 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 ifor 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;), xmust 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.
6An iterator jis called reachable from an iterator iif and only if there is a finite sequence of applications of
the expression ++i that makes i == j. If jis reachable from i, they refer to elements of the same sequence.
7Most of the library’s algorithmic templates that operate on data structures have interfaces that use ranges.
Arange 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 iand up to but not including the element pointed to by j. Range [i,j) is valid if and only if
jis reachable from i. The result of the application of functions in the library to invalid ranges is undefined.
8All 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.
9Destruction of an iterator may invalidate pointers and references previously obtained from that iterator.
10 An invalid iterator is an iterator that may be singular.270
11 In the following sections, aand bdenote values of type Xor const X,difference_type and reference refer
to the types iterator_traits<X>::difference_type and iterator_traits<X>::reference, respectively,
ndenotes a value of difference_type,u,tmp, and mdenote identifiers, rdenotes a value of X&,tdenotes
a value of value type T,odenotes a value of some type that is writable to the output iterator. [ Note: For
an iterator type Xthere must be an instantiation of iterator_traits<X> (24.4.1). — end note ]
24.2.2 Iterator [iterator.iterators]
1The 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 (24.2.3) or write (24.2.4) values, or to
provide a richer set of iterator movements (24.2.5,24.2.6,24.2.7).)
2A type Xsatisfies the Iterator requirements if:
Xsatisfies the CopyConstructible,CopyAssignable, and Destructible requirements (17.6.3.1) and
lvalues of type Xare swappable (17.6.3.2), and
the expressions in Table 106 are valid and have the indicated semantics.
Table 106 — Iterator requirements
Expression Return type Operational Assertion/note
semantics pre-/post-condition
*r reference pre: ris dereferenceable.
++r X&
270) This definition applies to pointers, since pointers are iterators. The effect of dereferencing an iterator that has been
invalidated is undefined.
§ 24.2.2 840
c
ISO/IEC N????
24.2.3 Input iterators [input.iterators]
1A class or pointer type Xsatisfies the requirements of an input iterator for the value type Tif X satisfies the
Iterator (24.2.2) and EqualityComparable (Table 17) requirements and the expressions in Table 107 are
valid and have the indicated semantics.
2In Table 107, 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 ahas the property pdefined as follows: bhas property pand a value ihas property pif
(*i==x) or if (*i!=x and ++i has property p). — end example ]
Table 107 — 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) pre: (a, b) is in the domain
of ==.
*a convertible to Tpre: ais 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 pre: ais dereferenceable.
++r X& pre: ris dereferenceable.
post: ris dereferenceable or
ris past-the-end.
post: any copies of the
previous value of rare 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; }
3[Note: For input iterators, a == b does not imply ++a == ++b. (Equality does not guarantee the substi-
tution 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
aCopyAssignable type (Table 23). These algorithms can be used with istreams as the source of the input
data through the istream_iterator class template. — end note ]
24.2.4 Output iterators [output.iterators]
1A class or pointer type Xsatisfies the requirements of an output iterator if Xsatisfies the Iterator require-
ments (24.2.2) and the expressions in Table 108 are valid and have the indicated semantics.
§ 24.2.4 841
c
ISO/IEC N????
Table 108 — Output iterator requirements (in addition to
Iterator)
Expression Return type Operational Assertion/note
semantics pre-/post-condition
*r = o result is not
used
Remark: After this operation
ris not required to be
dereferenceable.
post: ris incrementable.
++r X& &r == &++r.
Remark: After this operation
ris not required to be
dereferenceable.
post: ris incrementable.
r++ convertible to
const X&
{ X tmp = r;
++r;
return tmp; }
Remark: After this operation
ris not required to be
dereferenceable.
post: ris incrementable.
*r++ = o result is not
used
Remark: After this operation
ris not required to be
dereferenceable.
post: ris incrementable.
2[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 ]
24.2.5 Forward iterators [forward.iterators]
1A class or pointer type Xsatisfies the requirements of a forward iterator if
Xsatisfies the requirements of an input iterator (24.2.3),
X satisfies the DefaultConstructible requirements (17.6.3.1),
if Xis a mutable iterator, reference is a reference to T; if Xis a const iterator, reference is a reference
to const T,
the expressions in Table 109 are valid and have the indicated semantics, and
objects of type Xoffer the multi-pass guarantee, described below.
2The 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 ]
3Two dereferenceable iterators aand bof type Xoffer the multi-pass guarantee if:
a == b implies ++a == ++b and
Xis a pointer type or the expression (void)++X(a), *a is equivalent to the expression *a.
§ 24.2.5 842
c
ISO/IEC N????
4[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 109 — 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
5If aand bare equal, then either aand bare both dereferenceable or else neither is dereferenceable.
6If aand bare both dereferenceable, then a == b if and only if *a and *b are bound to the same object.
24.2.6 Bidirectional iterators [bidirectional.iterators]
1A class or pointer type Xsatisfies 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 110.
Table 110 — Bidirectional iterator requirements (in addition to
forward iterator)
Expression Return type Operational Assertion/note
semantics pre-/post-condition
--r X& pre: there exists ssuch that
r == ++s.
post: ris dereferenceable.
--(++r) == r.
--r == --s implies r == s.
&r == &--r.
r-- convertible to
const X&
{ X tmp = r;
--r;
return tmp; }
*r-- reference
2[Note: Bidirectional iterators allow algorithms to move iterators backward as well as forward. — end note ]
24.2.7 Random access iterators [random.access.iterators]
1A class or pointer type Xsatisfies 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 111.
§ 24.2.7 843
c
ISO/IEC N????
Table 111 — 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;
a - n X { X tmp = a;
return tmp -= n; }
b - a difference_-
type
return n pre: there exists a value nof
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)
24.3 Header <iterator> synopsis [iterator.synopsis]
namespace std {
// 24.4, primitives:
template<class Iterator> struct iterator_traits;
template<class T> struct iterator_traits<T*>;
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&> struct iterator;
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 { };
§ 24.3 844
c
ISO/IEC N????
// 24.4.4, iterator operations:
template <class InputIterator, class Distance>
void advance(InputIterator& i, Distance n);
template <class InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);
template <class ForwardIterator>
ForwardIterator next(ForwardIterator x,
typename std::iterator_traits<ForwardIterator>::difference_type n = 1);
template <class BidirectionalIterator>
BidirectionalIterator prev(BidirectionalIterator x,
typename std::iterator_traits<BidirectionalIterator>::difference_type n = 1);
// 24.5, predefined iterators:
template <class Iterator> class reverse_iterator;
template <class Iterator1, class Iterator2>
bool operator==(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator!=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
auto operator-(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y) ->decltype(y.base() - x.base());
template <class Iterator>
reverse_iterator<Iterator>
operator+(
typename reverse_iterator<Iterator>::difference_type n,
const reverse_iterator<Iterator>& x);
template <class Container> class back_insert_iterator;
template <class Container>
back_insert_iterator<Container> back_inserter(Container& x);
§ 24.3 845
c
ISO/IEC N????
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>
bool operator==(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator!=(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<=(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>=(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
auto operator-(
const move_iterator<Iterator1>& x,
const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
template <class Iterator>
move_iterator<Iterator> operator+(
typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
template <class Iterator>
move_iterator<Iterator> make_move_iterator(Iterator i);
// 24.6, 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;
§ 24.3 846
c
ISO/IEC N????
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;
// 24.7, range access:
template <class C> auto begin(C& c) -> decltype(c.begin());
template <class C> auto begin(const C& c) -> decltype(c.begin());
template <class C> auto end(C& c) -> decltype(c.end());
template <class C> auto end(const C& c) -> decltype(c.end());
template <class T, size_t N> T* begin(T (&array)[N]);
template <class T, size_t N> T* end(T (&array)[N]);
template <class C> auto cbegin(const C& c) -> decltype(std::begin(c));
template <class C> auto cend(const C& c) -> decltype(std::end(c));
template <class C> auto rbegin(C& c) -> decltype(c.rbegin());
template <class C> auto rbegin(const C& c) -> decltype(c.rbegin());
template <class C> auto rend(C& c) -> decltype(c.rend());
template <class C> auto rend(const C& c) -> decltype(c.rend());
template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);
template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);
template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il);
template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);
template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));
template <class C> auto crend(const C& c) -> decltype(std::rend(c));
}
24.4 Iterator primitives [iterator.primitives]
1To simplify the task of defining iterators, the library provides several classes and functions:
24.4.1 Iterator traits [iterator.traits]
1To 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.
§ 24.4.1 847
c
ISO/IEC N????
2The template iterator_traits<Iterator> is defined as
namespace std {
template<class Iterator> struct iterator_traits {
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
typedef typename Iterator::iterator_category iterator_category;
};
}
3It is specialized for pointers as
namespace std {
template<class T> struct iterator_traits<T*> {
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef random_access_iterator_tag iterator_category;
};
}
and for pointers to const as
namespace std {
template<class T> struct iterator_traits<const T*> {
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef const T* pointer;
typedef const T& reference;
typedef random_access_iterator_tag iterator_category;
};
}
4[Note: If there is an additional pointer type _ _ far such that the difference of two _ _ far is of type long,
an implementation may define
template<class T> struct iterator_traits<T _ _ far*> {
typedef long difference_type;
typedef T value_type;
typedef T _ _ far* pointer;
typedef T _ _ far& reference;
typedef random_access_iterator_tag iterator_category;
};
— end note ]
5[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;
§ 24.4.1 848
c
ISO/IEC N????
*last = tmp;
n -= 2;
}
}
— end example ]
24.4.2 Basic iterator [iterator.basic]
1The iterator template may be used as a base class to ease the definition of required types for new iterators.
namespace std {
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator {
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
}
24.4.3 Standard iterator tags [std.iterator.tags]
1It is often desirable for a function template specialization to find out what is the most specific cate-
gory 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 { };
}
2[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> > {
typedef std::ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef bidirectional_iterator_tag iterator_category;
};
Typically, however, it would be easier to derive BinaryTreeIterator<T> from iterator<bidirectional_-
iterator_tag,T,ptrdiff_t,T*,T&>.— end example ]
3[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) {
§ 24.4.3 849
c
ISO/IEC N????
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 ]
4[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.
};
5Then there is no need to specialize the iterator_traits template. — end example ]
24.4.4 Iterator operations [iterator.operations]
1Since 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>
void advance(InputIterator& i, Distance n);
2Requires: nshall be negative only for bidirectional and random access iterators.
3Effects: Increments (or decrements for negative n) iterator reference iby n.
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);
4Effects: 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.
5Requires: 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 ForwardIterator>
ForwardIterator next(ForwardIterator x,
typename std::iterator_traits<ForwardIterator>::difference_type n = 1);
6Effects: Equivalent to advance(x, n); return x;
§ 24.4.4 850
c
ISO/IEC N????
template <class BidirectionalIterator>
BidirectionalIterator prev(BidirectionalIterator x,
typename std::iterator_traits<BidirectionalIterator>::difference_type n = 1);
7Effects: Equivalent to advance(x, -n); return x;
24.5 Iterator adaptors [predef.iterators]
24.5.1 Reverse iterators [reverse.iterators]
1Class 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 iis established by the identity: &*(reverse_iterator(i)) == &*(i
- 1).
24.5.1.1 Class template reverse_iterator [reverse.iterator]
namespace std {
template <class Iterator>
class reverse_iterator : public
iterator<typename iterator_traits<Iterator>::iterator_category,
typename iterator_traits<Iterator>::value_type,
typename iterator_traits<Iterator>::difference_type,
typename iterator_traits<Iterator>::pointer,
typename iterator_traits<Iterator>::reference> {
public:
typedef Iterator iterator_type;
typedef typename iterator_traits<Iterator>::difference_type difference_type;
typedef typename iterator_traits<Iterator>::reference reference;
typedef typename iterator_traits<Iterator>::pointer pointer;
reverse_iterator();
explicit reverse_iterator(Iterator x);
template <class U> reverse_iterator(const reverse_iterator<U>& u);
template <class U> reverse_iterator& operator=(const reverse_iterator<U>& u);
Iterator base() const; // explicit
reference operator*() const;
pointer operator->() const;
reverse_iterator& operator++();
reverse_iterator operator++(int);
reverse_iterator& operator--();
reverse_iterator operator--(int);
reverse_iterator operator+ (difference_type n) const;
reverse_iterator& operator+=(difference_type n);
reverse_iterator operator- (difference_type n) const;
reverse_iterator& operator-=(difference_type n);
unspecified operator[](difference_type n) const;
protected:
Iterator current;
private:
Iterator deref_tmp; // exposition only
};
template <class Iterator1, class Iterator2>
§ 24.5.1.1 851
c
ISO/IEC N????
bool operator==(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator!=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
auto operator-(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
template <class Iterator>
reverse_iterator<Iterator> operator+(
typename reverse_iterator<Iterator>::difference_type n,
const reverse_iterator<Iterator>& x);
}
24.5.1.2 reverse_iterator requirements [reverse.iter.requirements]
1The template parameter Iterator shall meet all the requirements of a Bidirectional Iterator (24.2.6).
2Additionally, Iterator shall meet the requirements of a Random Access Iterator (24.2.7) if any of the mem-
bers operator+ (24.5.1.3.8), operator- (24.5.1.3.10), operator+= (24.5.1.3.9), operator-= (24.5.1.3.11),
operator [] (24.5.1.3.12), or the global operators operator< (24.5.1.3.14), operator> (24.5.1.3.16),
operator <= (24.5.1.3.18), operator>= (24.5.1.3.17), operator- (24.5.1.3.19) or operator+ (24.5.1.3.20) are
referenced in a way that requires instantiation (14.7.1).
24.5.1.3 reverse_iterator operations [reverse.iter.ops]
24.5.1.3.1 reverse_iterator constructor [reverse.iter.cons]
reverse_iterator();
1Effects: 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.
explicit reverse_iterator(Iterator x);
2Effects: Initializes current with x.
template <class U> reverse_iterator(const reverse_iterator<U> &u);
§ 24.5.1.3.1 852
c
ISO/IEC N????
3Effects: Initializes current with u.current.
24.5.1.3.2 reverse_iterator::operator= [reverse.iter.op=]
template <class U>
reverse_iterator&
operator=(const reverse_iterator<U>& u);
1Effects: Assigns u.base() to current.
2Returns: *this.
24.5.1.3.3 Conversion [reverse.iter.conv]
Iterator base() const; // explicit
1Returns: current.
24.5.1.3.4 operator* [reverse.iter.op.star]
reference operator*() const;
1Effects:
deref_tmp = current;
--deref_tmp;
return *deref_tmp;
2[Note: This operation must use an auxiliary member variable rather than a temporary variable to
avoid returning a reference that persists beyond the lifetime of its associated iterator. (See 24.2.)
— end note ]
24.5.1.3.5 operator-> [reverse.iter.opref]
pointer operator->() const;
1Returns: &(operator*()).
24.5.1.3.6 operator++ [reverse.iter.op++]
reverse_iterator& operator++();
1Effects: --current;
2Returns: *this.
reverse_iterator operator++(int);
3Effects:
reverse_iterator tmp = *this;
--current;
return tmp;
§ 24.5.1.3.6 853
c
ISO/IEC N????
24.5.1.3.7 operator-- [reverse.iter.op--]
reverse_iterator& operator--();
1Effects: ++current
2Returns: *this.
reverse_iterator operator--(int);
3Effects:
reverse_iterator tmp = *this;
++current;
return tmp;
24.5.1.3.8 operator+ [reverse.iter.op+]
reverse_iterator
operator+(typename reverse_iterator<Iterator>::difference_type n) const;
1Returns: reverse_iterator(current-n).
24.5.1.3.9 operator+= [reverse.iter.op+=]
reverse_iterator&
operator+=(typename reverse_iterator<Iterator>::difference_type n);
1Effects: current -= n;
2Returns: *this.
24.5.1.3.10 operator- [reverse.iter.op-]
reverse_iterator
operator-(typename reverse_iterator<Iterator>::difference_type n) const;
1Returns: reverse_iterator(current+n).
24.5.1.3.11 operator-= [reverse.iter.op-=]
reverse_iterator&
operator-=(typename reverse_iterator<Iterator>::difference_type n);
1Effects: current += n;
2Returns: *this.
24.5.1.3.12 operator[] [reverse.iter.opindex]
unspecified operator[](
typename reverse_iterator<Iterator>::difference_type n) const;
1Returns: current[-n-1].
24.5.1.3.13 operator== [reverse.iter.op==]
template <class Iterator1, class Iterator2>
bool operator==(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
1Returns: x.current == y.current.
§ 24.5.1.3.13 854
c
ISO/IEC N????
24.5.1.3.14 operator< [reverse.iter.op<]
template <class Iterator1, class Iterator2>
bool operator<(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
1Returns: x.current > y.current.
24.5.1.3.15 operator!= [reverse.iter.op!=]
template <class Iterator1, class Iterator2>
bool operator!=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
1Returns: x.current != y.current.
24.5.1.3.16 operator> [reverse.iter.op>]
template <class Iterator1, class Iterator2>
bool operator>(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
1Returns: x.current < y.current.
24.5.1.3.17 operator>= [reverse.iter.op>=]
template <class Iterator1, class Iterator2>
bool operator>=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
1Returns: x.current <= y.current.
24.5.1.3.18 operator<= [reverse.iter.op<=]
template <class Iterator1, class Iterator2>
bool operator<=(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y);
1Returns: x.current >= y.current.
24.5.1.3.19 operator- [reverse.iter.opdiff]
template <class Iterator1, class Iterator2>
auto operator-(
const reverse_iterator<Iterator1>& x,
const reverse_iterator<Iterator2>& y) -> decltype(y.base() - x.base());
1Returns: y.current - x.current.
24.5.1.3.20 operator+ [reverse.iter.opsum]
template <class Iterator>
reverse_iterator<Iterator> operator+(
typename reverse_iterator<Iterator>::difference_type n,
const reverse_iterator<Iterator>& x);
1Returns: reverse_iterator<Iterator> (x.current - n).
§ 24.5.1.3.20 855
c
ISO/IEC N????
24.5.2 Insert iterators [insert.iterators]
1To 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.
2An 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 require-
ments 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 xright 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.
24.5.2.1 Class template back_insert_iterator [back.insert.iterator]
namespace std {
template <class Container>
class back_insert_iterator :
public iterator<output_iterator_tag,void,void,void,void> {
protected:
Container* container;
public:
typedef Container container_type;
explicit back_insert_iterator(Container& x);
back_insert_iterator<Container>&
operator=(const typename Container::value_type& value);
back_insert_iterator<Container>&
operator=(typename Container::value_type&& value);
back_insert_iterator<Container>& operator*();
back_insert_iterator<Container>& operator++();
back_insert_iterator<Container> operator++(int);
};
template <class Container>
back_insert_iterator<Container> back_inserter(Container& x);
}
24.5.2.2 back_insert_iterator operations [back.insert.iter.ops]
24.5.2.2.1 back_insert_iterator constructor [back.insert.iter.cons]
explicit back_insert_iterator(Container& x);
1Effects: Initializes container with &x.
24.5.2.2.2 back_insert_iterator::operator= [back.insert.iter.op=]
back_insert_iterator<Container>&
operator=(const typename Container::value_type& value);
§ 24.5.2.2.2 856
c
ISO/IEC N????
1Effects: container->push_back(value);
2Returns: *this.
back_insert_iterator<Container>&
operator=(typename Container::value_type&& value);
3Effects: container->push_back(std::move(value));
4Returns: *this.
24.5.2.2.3 back_insert_iterator::operator* [back.insert.iter.op*]
back_insert_iterator<Container>& operator*();
1Returns: *this.
24.5.2.2.4 back_insert_iterator::operator++ [back.insert.iter.op++]
back_insert_iterator<Container>& operator++();
back_insert_iterator<Container> operator++(int);
1Returns: *this.
24.5.2.2.5 back_inserter [back.inserter]
template <class Container>
back_insert_iterator<Container> back_inserter(Container& x);
1Returns: back_insert_iterator<Container>(x).
24.5.2.3 Class template front_insert_iterator [front.insert.iterator]
namespace std {
template <class Container>
class front_insert_iterator :
public iterator<output_iterator_tag,void,void,void,void> {
protected:
Container* container;
public:
typedef Container container_type;
explicit front_insert_iterator(Container& x);
front_insert_iterator<Container>&
operator=(const typename Container::value_type& value);
front_insert_iterator<Container>&
operator=(typename Container::value_type&& value);
front_insert_iterator<Container>& operator*();
front_insert_iterator<Container>& operator++();
front_insert_iterator<Container> operator++(int);
};
template <class Container>
front_insert_iterator<Container> front_inserter(Container& x);
}
24.5.2.4 front_insert_iterator operations [front.insert.iter.ops]
24.5.2.4.1 front_insert_iterator constructor [front.insert.iter.cons]
§ 24.5.2.4.1 857
c
ISO/IEC N????
explicit front_insert_iterator(Container& x);
1Effects: Initializes container with &x.
24.5.2.4.2 front_insert_iterator::operator= [front.insert.iter.op=]
front_insert_iterator<Container>&
operator=(const typename Container::value_type& value);
1Effects: container->push_front(value);
2Returns: *this.
front_insert_iterator<Container>&
operator=(typename Container::value_type&& value);
3Effects: container->push_front(std::move(value));
4Returns: *this.
24.5.2.4.3 front_insert_iterator::operator* [front.insert.iter.op*]
front_insert_iterator<Container>& operator*();
1Returns: *this.
24.5.2.4.4 front_insert_iterator::operator++ [front.insert.iter.op++]
front_insert_iterator<Container>& operator++();
front_insert_iterator<Container> operator++(int);
1Returns: *this.
24.5.2.4.5 front_inserter [front.inserter]
template <class Container>
front_insert_iterator<Container> front_inserter(Container& x);
1Returns: front_insert_iterator<Container>(x).
24.5.2.5 Class template insert_iterator [insert.iterator]
namespace std {
template <class Container>
class insert_iterator :
public iterator<output_iterator_tag,void,void,void,void> {
protected:
Container* container;
typename Container::iterator iter;
public:
typedef Container container_type;
insert_iterator(Container& x, typename Container::iterator i);
insert_iterator<Container>&
operator=(const typename Container::value_type& value);
insert_iterator<Container>&
operator=(typename Container::value_type&& value);
insert_iterator<Container>& operator*();
insert_iterator<Container>& operator++();
§ 24.5.2.5 858
c
ISO/IEC N????
insert_iterator<Container>& operator++(int);
};
template <class Container>
insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
}
24.5.2.6 insert_iterator operations [insert.iter.ops]
24.5.2.6.1 insert_iterator constructor [insert.iter.cons]
insert_iterator(Container& x, typename Container::iterator i);
1Effects: Initializes container with &x and iter with i.
24.5.2.6.2 insert_iterator::operator= [insert.iter.op=]
insert_iterator<Container>&
operator=(const typename Container::value_type& value);
1Effects:
iter = container->insert(iter, value);
++iter;
2Returns: *this.
insert_iterator<Container>&
operator=(typename Container::value_type&& value);
3Effects:
iter = container->insert(iter, std::move(value));
++iter;
4Returns: *this.
24.5.2.6.3 insert_iterator::operator* [insert.iter.op*]
insert_iterator<Container>& operator*();
1Returns: *this.
24.5.2.6.4 insert_iterator::operator++ [insert.iter.op++]
insert_iterator<Container>& operator++();
insert_iterator<Container>& operator++(int);
1Returns: *this.
24.5.2.6.5 inserter [inserter]
template <class Container>
insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
1Returns: insert_iterator<Container>(x, i).
§ 24.5.2.6.5 859
c
ISO/IEC N????
24.5.3 Move iterators [move.iterators]
1Class 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 indi-
rection operator to an rvalue reference. Some generic algorithms can be called with move iterators to replace
copying with moving.
2[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 ]
24.5.3.1 Class template move_iterator [move.iterator]
namespace std {
template <class Iterator>
class move_iterator {
public:
typedef Iterator iterator_type;
typedef typename iterator_traits<Iterator>::difference_type difference_type;
typedef Iterator pointer;
typedef typename iterator_traits<Iterator>::value_type value_type;
typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
typedef value_type&& reference;
move_iterator();
explicit move_iterator(Iterator i);
template <class U> move_iterator(const move_iterator<U>& u);
template <class U> move_iterator& operator=(const move_iterator<U>& u);
iterator_type base() const;
reference operator*() const;
pointer operator->() const;
move_iterator& operator++();
move_iterator operator++(int);
move_iterator& operator--();
move_iterator operator--(int);
move_iterator operator+(difference_type n) const;
move_iterator& operator+=(difference_type n);
move_iterator operator-(difference_type n) const;
move_iterator& operator-=(difference_type n);
unspecified operator[](difference_type n) const;
private:
Iterator current; // exposition only
};
template <class Iterator1, class Iterator2>
bool operator==(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator!=(
§ 24.5.3.1 860
c
ISO/IEC N????
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator<=(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
bool operator>=(
const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
template <class Iterator1, class Iterator2>
auto operator-(
const move_iterator<Iterator1>& x,
const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
template <class Iterator>
move_iterator<Iterator> operator+(
typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
template <class Iterator>
move_iterator<Iterator> make_move_iterator(Iterator i);
}
24.5.3.2 move_iterator requirements [move.iter.requirements]
1The template parameter Iterator shall meet the requirements for an Input Iterator (24.2.3). Additionally,
if any of the bidirectional or random access traversal functions are instantiated, the template parameter shall
meet the requirements for a Bidirectional Iterator (24.2.6) or a Random Access Iterator (24.2.7), respectively.
24.5.3.3 move_iterator operations [move.iter.ops]
24.5.3.3.1 move_iterator constructors [move.iter.op.const]
move_iterator();
1Effects: 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.
explicit move_iterator(Iterator i);
2Effects: Constructs a move_iterator, initializing current with i.
template <class U> move_iterator(const move_iterator<U>& u);
3Effects: Constructs a move_iterator, initializing current with u.base().
4Requires: Ushall be convertible to Iterator.
24.5.3.3.2 move_iterator::operator= [move.iter.op=]
template <class U> move_iterator& operator=(const move_iterator<U>& u);
1Effects: Assigns u.base() to current.
2Requires: Ushall be convertible to Iterator.
§ 24.5.3.3.2 861
c
ISO/IEC N????
24.5.3.3.3 move_iterator conversion [move.iter.op.conv]
Iterator base() const;
1Returns: current.
24.5.3.3.4 move_iterator::operator* [move.iter.op.star]
reference operator*() const;
1Returns: std::move(*current).
24.5.3.3.5 move_iterator::operator-> [move.iter.op.ref]
pointer operator->() const;
1Returns: current.
24.5.3.3.6 move_iterator::operator++ [move.iter.op.incr]
move_iterator& operator++();
1Effects: ++current.
2Returns: *this.
move_iterator operator++(int);
3Effects:
move_iterator tmp = *this;
++current;
return tmp;
24.5.3.3.7 move_iterator::operator-- [move.iter.op.decr]
move_iterator& operator--();
1Effects: --current.
2Returns: *this.
move_iterator operator--(int);
3Effects:
move_iterator tmp = *this;
--current;
return tmp;
24.5.3.3.8 move_iterator::operator+ [move.iter.op.+]
move_iterator operator+(difference_type n) const;
1Returns: move_iterator(current + n).
24.5.3.3.9 move_iterator::operator+= [move.iter.op.+=]
move_iterator& operator+=(difference_type n);
1Effects: current += n.
2Returns: *this.
§ 24.5.3.3.9 862
c
ISO/IEC N????
24.5.3.3.10 move_iterator::operator- [move.iter.op.-]
move_iterator operator-(difference_type n) const;
1Returns: move_iterator(current - n).
24.5.3.3.11 move_iterator::operator-= [move.iter.op.-=]
move_iterator& operator-=(difference_type n);
1Effects: current -= n.
2Returns: *this.
24.5.3.3.12 move_iterator::operator[] [move.iter.op.index]
unspecified operator[](difference_type n) const;
1Returns: std::move(current[n]).
24.5.3.3.13 move_iterator comparisons [move.iter.op.comp]
template <class Iterator1, class Iterator2>
bool operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
1Returns: x.base() == y.base().
template <class Iterator1, class Iterator2>
bool operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
2Returns: !(x == y).
template <class Iterator1, class Iterator2>
bool operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
3Returns: x.base() < y.base().
template <class Iterator1, class Iterator2>
bool operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
4Returns: !(y < x).
template <class Iterator1, class Iterator2>
bool operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
5Returns: y<x.
template <class Iterator1, class Iterator2>
bool operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
6Returns: !(x < y).
§ 24.5.3.3.13 863
c
ISO/IEC N????
24.5.3.3.14 move_iterator non-member functions [move.iter.nonmember]
template <class Iterator1, class Iterator2>
auto operator-(
const move_iterator<Iterator1>& x,
const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
1Returns: x.base() - y.base().
template <class Iterator>
move_iterator<Iterator> operator+(
typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator>& x);
2Returns: x+n.
template <class Iterator>
move_iterator<Iterator> make_move_iterator(Iterator i);
3Returns: move_iterator<Iterator>(i).
24.6 Stream iterators [stream.iterators]
1To 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 ]
24.6.1 Class template istream_iterator [istream.iterator]
1The class template istream_iterator is an input iterator (24.2.3) 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.
2Two 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 iterator<input_iterator_tag, T, Distance, const T*, const T&> {
public:
typedef charT char_type;
typedef traits traits_type;
§ 24.6.1 864
c
ISO/IEC N????
typedef basic_istream<charT,traits> istream_type;
see below 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<T,charT,traits,Distance>& operator++();
istream_iterator<T,charT,traits,Distance> 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);
}
24.6.1.1 istream_iterator constructors and destructor [istream.iterator.cons]
see below istream_iterator();
1Effects: Constructs the end-of-stream iterator. If Tis a literal type, then this constructor shall be a
constexpr constructor.
2Postcondition: in_stream == 0.
istream_iterator(istream_type& s);
3Effects: Initializes in_stream with &s.value may be initialized during construction or the first time it
is referenced.
4Postcondition: in_stream == &s.
istream_iterator(const istream_iterator& x) = default;
5Effects: Constructs a copy of x. If Tis a literal type, then this constructor shall be a trivial copy
constructor.
6Postcondition: in_stream == x.in_stream.
~istream_iterator() = default;
7Effects: The iterator is destroyed. If Tis a literal type, then this destructor shall be a trivial destructor.
24.6.1.2 istream_iterator operations [istream.iterator.ops]
const T& operator*() const;
1Returns: value.
§ 24.6.1.2 865
c
ISO/IEC N????
const T* operator->() const;
2Returns: &(operator*()).
istream_iterator<T,charT,traits,Distance>& operator++();
3Requires: in_stream != 0.
4Effects: *in_stream >>value.
5Returns: *this.
istream_iterator<T,charT,traits,Distance> operator++(int);
6Requires: in_stream != 0.
7Effects:
istream_iterator<T,charT,traits,Distance> 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);
8Returns: 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);
9Returns: !(x == y)
24.6.2 Class template ostream_iterator [ostream.iterator]
1ostream_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 Tis 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++;
2ostream_iterator is defined as:
namespace std {
template <class T, class charT = char, class traits = char_traits<charT> >
class ostream_iterator:
public iterator<output_iterator_tag, void, void, void, void> {
public:
typedef charT char_type;
typedef traits traits_type;
typedef basic_ostream<charT,traits> ostream_type;
ostream_iterator(ostream_type& s);
ostream_iterator(ostream_type& s, const charT* delimiter);
§ 24.6.2 866
c
ISO/IEC N????
ostream_iterator(const ostream_iterator<T,charT,traits>& x);
~ostream_iterator();
ostream_iterator<T,charT,traits>& operator=(const T& value);
ostream_iterator<T,charT,traits>& operator*();
ostream_iterator<T,charT,traits>& operator++();
ostream_iterator<T,charT,traits>& operator++(int);
private:
basic_ostream<charT,traits>* out_stream; // exposition only
const charT* delim; // exposition only
};
}
24.6.2.1 ostream_iterator constructors and destructor [ostream.iterator.cons.des]
ostream_iterator(ostream_type& s);
1Effects: Initializes out_stream with &s and delim with null.
ostream_iterator(ostream_type& s, const charT* delimiter);
2Effects: Initializes out_stream with &s and delim with delimiter.
ostream_iterator(const ostream_iterator& x);
3Effects: Constructs a copy of x.
~ostream_iterator();
4Effects: The iterator is destroyed.
24.6.2.2 ostream_iterator operations [ostream.iterator.ops]
ostream_iterator& operator=(const T& value);
1Effects:
*out_stream << value;
if(delim != 0)
*out_stream << delim ;
return (*this);
ostream_iterator& operator*();
2Returns: *this.
ostream_iterator& operator++();
ostream_iterator& operator++(int);
3Returns: *this.
§ 24.6.2.2 867
c
ISO/IEC N????
24.6.3 Class template istreambuf_iterator [istreambuf.iterator]
1The class template istreambuf_iterator defines an input iterator (24.2.3) that reads successive characters
from the streambuf for which it was constructed. operator* provides access to the current input character, if
any. [ Note: operator-> may return a proxy. — end note ] 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.
2The 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 iterator<input_iterator_tag, charT,
typename traits::off_type, unspecified , charT> {
public:
typedef charT char_type;
typedef traits traits_type;
typedef typename traits::int_type int_type;
typedef basic_streambuf<charT,traits> streambuf_type;
typedef basic_istream<charT,traits> istream_type;
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;
pointer operator->() const;
istreambuf_iterator<charT,traits>& 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);
}
24.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_;
§ 24.6.3.1 868
c
ISO/IEC N????
basic_streambuf<charT,traits>* sbuf_;
proxy(charT c, basic_streambuf<charT,traits>* sbuf)
: keep_(c), sbuf_(sbuf) { }
public:
charT operator*() { return keep_; }
};
}
1Class istreambuf_iterator<charT,traits>::proxy is for exposition only. An implementation is permit-
ted 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.
24.6.3.2 istreambuf_iterator constructors [istreambuf.iterator.cons]
constexpr istreambuf_iterator() noexcept;
1Effects: Constructs the end-of-stream iterator.
istreambuf_iterator(basic_istream<charT,traits>& s) noexcept;
istreambuf_iterator(basic_streambuf<charT,traits>* s) noexcept;
2Effects: Constructs an istreambuf_iterator<> that uses the basic_streambuf<> object *(s.rdbuf()),
or *s, respectively. Constructs an end-of-stream iterator if s.rdbuf() is null.
istreambuf_iterator(const proxy& p) noexcept;
3Effects: Constructs a istreambuf_iterator<> that uses the basic_streambuf<> object pointed to
by the proxy object’s constructor argument p.
24.6.3.3 istreambuf_iterator::operator* [istreambuf.iterator::op*]
charT operator*() const
1Returns: The character obtained via the streambuf member sbuf_->sgetc().
24.6.3.4 istreambuf_iterator::operator++ [istreambuf.iterator::op++]
istreambuf_iterator<charT,traits>&
istreambuf_iterator<charT,traits>::operator++();
1Effects: sbuf_->sbumpc().
2Returns: *this.
proxy istreambuf_iterator<charT,traits>::operator++(int);
3Returns: proxy(sbuf_->sbumpc(), sbuf_).
24.6.3.5 istreambuf_iterator::equal [istreambuf.iterator::equal]
bool equal(const istreambuf_iterator<charT,traits>& b) const;
1Returns: true if and only if both iterators are at end-of-stream, or neither is at end-of-stream, regard-
less of what streambuf object they use.
§ 24.6.3.5 869
c
ISO/IEC N????
24.6.3.6 operator== [istreambuf.iterator::op==]
template <class charT, class traits>
bool operator==(const istreambuf_iterator<charT,traits>& a,
const istreambuf_iterator<charT,traits>& b);
1Returns: a.equal(b).
24.6.3.7 operator!= [istreambuf.iterator::op!=]
template <class charT, class traits>
bool operator!=(const istreambuf_iterator<charT,traits>& a,
const istreambuf_iterator<charT,traits>& b);
1Returns: !a.equal(b).
24.6.4 Class template ostreambuf_iterator [ostreambuf.iterator]
namespace std {
template <class charT, class traits = char_traits<charT> >
class ostreambuf_iterator :
public iterator<output_iterator_tag, void, void, void, void> {
public:
typedef charT char_type;
typedef traits traits_type;
typedef basic_streambuf<charT,traits> streambuf_type;
typedef basic_ostream<charT,traits> ostream_type;
public:
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
};
}
1The 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.
24.6.4.1 ostreambuf_iterator constructors [ostreambuf.iter.cons]
ostreambuf_iterator(ostream_type& s) noexcept;
1Requires: s.rdbuf() shall not null pointer.
2Effects: Initializes sbuf_ with s.rdbuf().
ostreambuf_iterator(streambuf_type* s) noexcept;
3Requires: sshall not be a null pointer.
4Effects: Initializes sbuf_ with s.
§ 24.6.4.1 870
c
ISO/IEC N????
24.6.4.2 ostreambuf_iterator operations [ostreambuf.iter.ops]
ostreambuf_iterator<charT,traits>&
operator=(charT c);
1Effects: If failed() yields false, calls sbuf_->sputc(c); otherwise has no effect.
2Returns: *this.
ostreambuf_iterator<charT,traits>& operator*();
3Returns: *this.
ostreambuf_iterator<charT,traits>& operator++();
ostreambuf_iterator<charT,traits>& operator++(int);
4Returns: *this.
bool failed() const noexcept;
5Returns: true if in any prior use of member operator=, the call to sbuf_->sputc() returned
traits::eof(); or false otherwise.
24.7 range access [iterator.range]
1In addition to being available via inclusion of the <iterator> header, the function templates in 24.7 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> auto begin(C& c) -> decltype(c.begin());
template <class C> auto begin(const C& c) -> decltype(c.begin());
2Returns: c.begin().
template <class C> auto end(C& c) -> decltype(c.end());
template <class C> auto end(const C& c) -> decltype(c.end());
3Returns: c.end().
template <class T, size_t N> T* begin(T (&array)[N]);
4Returns: array.
template <class T, size_t N> T* end(T (&array)[N]);
5Returns: array + N.
template <class C> auto cbegin(const C& c) -> decltype(std::begin(c));
6Returns: std::begin(c).
template <class C> auto cend(const C& c) -> decltype(std::end(c));
§ 24.7 871
c
ISO/IEC N????
7Returns: std::end(c).
template <class C> auto rbegin(C& c) -> decltype(c.rbegin());
template <class C> auto rbegin(const C& c) -> decltype(c.rbegin());
8Returns: c.rbegin().
template <class C> auto rend(C& c) -> decltype(c.rend());
template <class C> auto rend(const C& c) -> decltype(c.rend());
9Returns: c.rend().
template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);
10 Returns: reverse_iterator<T*>(array + N).
template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);
11 Returns: reverse_iterator<T*>(array).
template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il);
12 Returns: reverse_iterator<const E*>(il.end()).
template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);
13 Returns: reverse_iterator<const E*>(il.begin()).
template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));
14 Returns: std::rbegin(c).
template <class C> auto crend(const C& c) -> decltype(std::rend(c));
15 Returns: std::rend(c).
§ 24.7 872
c
ISO/IEC N????
25 Algorithms library [algorithms]
25.1 General [algorithms.general]
1This Clause describes components that C++ programs may use to perform algorithmic operations on con-
tainers (Clause 23) and other sequences.
2The following subclauses describe components for non-modifying sequence operation, modifying sequence
operations, sorting and related operations, and algorithms from the ISO C library, as summarized in Ta-
ble 112.
Table 112 — Algorithms library summary
Subclause Header(s)
25.2 Non-modifying sequence operations
25.3 Mutating sequence operations <algorithm>
25.4 Sorting and related operations
25.5 C library algorithms <cstdlib>
Header <algorithm> synopsis
#include <initializer_list>
namespace std {
// 25.2, non-modifying sequence operations:
template <class InputIterator, class Predicate>
bool all_of(InputIterator first, InputIterator last, Predicate pred);
template <class InputIterator, class Predicate>
bool any_of(InputIterator first, InputIterator last, Predicate pred);
template <class InputIterator, class Predicate>
bool none_of(InputIterator first, InputIterator last, Predicate pred);
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
template<class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last,
const T& value);
template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
Predicate pred);
template<class InputIterator, class Predicate>
InputIterator find_if_not(InputIterator first, InputIterator last,
Predicate pred);
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2);
template<class ForwardIterator1, class ForwardIterator2,
class BinaryPredicate>
ForwardIterator1
§ 25.1 873
c
ISO/IEC N????
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred);
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 ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first,
ForwardIterator last);
template<class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first,
ForwardIterator last,
BinaryPredicate pred);
template<class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator 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 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 InputIterator1, class InputIterator2>
bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2);
§ 25.1 874
c
ISO/IEC N????
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 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);
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 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);
// 25.3, modifying sequence operations:
// 25.3.1, copy:
template<class InputIterator, class OutputIterator>
§ 25.1 875
c
ISO/IEC N????
OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result);
template<class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n(InputIterator first, Size n,
OutputIterator result);
template<class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred);
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward(
BidirectionalIterator1 first, BidirectionalIterator1 last,
BidirectionalIterator2 result);
// 25.3.2, move:
template<class InputIterator, class OutputIterator>
OutputIterator move(InputIterator first, InputIterator last,
OutputIterator result);
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 move_backward(
BidirectionalIterator1 first, BidirectionalIterator1 last,
BidirectionalIterator2 result);
// 25.3.3, swap:
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges(ForwardIterator1 first1,
ForwardIterator1 last1, ForwardIterator2 first2);
template<class ForwardIterator1, class ForwardIterator2>
void iter_swap(ForwardIterator1 a, ForwardIterator2 b);
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 ForwardIterator, class T>
void replace(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 InputIterator, class OutputIterator, class T>
OutputIterator replace_copy(InputIterator first, InputIterator last,
OutputIterator 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 ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value);
§ 25.1 876
c
ISO/IEC N????
template<class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T& value);
template<class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last,
Generator gen);
template<class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen);
template<class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T& value);
template<class ForwardIterator, class Predicate>
ForwardIterator remove_if(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 InputIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred);
template<class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class BinaryPredicate>
ForwardIterator unique(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 BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last);
template<class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy(BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result);
template<class ForwardIterator>
ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last);
template<class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy(
ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result);
template<class RandomAccessIterator>
void random_shuffle(RandomAccessIterator first,
RandomAccessIterator last);
template<class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(RandomAccessIterator first,
RandomAccessIterator last,
§ 25.1 877
c
ISO/IEC N????
RandomNumberGenerator&& rand);
template<class RandomAccessIterator, class UniformRandomNumberGenerator>
void shuffle(RandomAccessIterator first,
RandomAccessIterator last,
UniformRandomNumberGenerator&& rand);
// 25.3.13, partitions:
template <class InputIterator, class Predicate>
bool is_partitioned(InputIterator first, InputIterator last, Predicate pred);
template<class ForwardIterator, class Predicate>
ForwardIterator partition(ForwardIterator first,
ForwardIterator last,
Predicate pred);
template<class BidirectionalIterator, class Predicate>
BidirectionalIterator stable_partition(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 ForwardIterator, class Predicate>
ForwardIterator partition_point(ForwardIterator first,
ForwardIterator last,
Predicate pred);
// 25.4, sorting and related operations:
// 25.4.1, 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 RandomAccessIterator>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
template<class RandomAccessIterator, class Compare>
void stable_sort(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 InputIterator, class RandomAccessIterator>
RandomAccessIterator partial_sort_copy(
InputIterator first, InputIterator last,
RandomAccessIterator result_first,
§ 25.1 878
c
ISO/IEC N????
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 ForwardIterator>
bool is_sorted(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
bool is_sorted(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 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);
// 25.4.3, 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);
§ 25.1 879
c
ISO/IEC N????
// 25.4.4, 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 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);
// 25.4.5, 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 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 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 InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(
InputIterator1 first1, InputIterator1 last1,
§ 25.1 880
c
ISO/IEC N????
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 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);
// 25.4.6, 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 RandomAccessIterator>
RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last);
template<class RandomAccessIterator, class Compare>
RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
§ 25.1 881
c
ISO/IEC N????
// 25.4.7, minimum and maximum:
template<class T> const T& min(const T& a, const T& b);
template<class T, class Compare>
const T& min(const T& a, const T& b, Compare comp);
template<class T>
T min(initializer_list<T> t);
template<class T, class Compare>
T min(initializer_list<T> t, Compare comp);
template<class T> const T& max(const T& a, const T& b);
template<class T, class Compare>
const T& max(const T& a, const T& b, Compare comp);
template<class T>
T max(initializer_list<T> t);
template<class T, class Compare>
T max(initializer_list<T> t, Compare comp);
template<class T> pair<const T&, const T&> minmax(const T& a, const T& b);
template<class T, class Compare>
pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp);
template<class T>
pair<T, T> minmax(initializer_list<T> t);
template<class T, class Compare>
pair<T, T> minmax(initializer_list<T> t, Compare comp);
template<class ForwardIterator>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
Compare comp);
template<class ForwardIterator>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
Compare comp);
template<class ForwardIterator>
pair<ForwardIterator, ForwardIterator>
minmax_element(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
pair<ForwardIterator, ForwardIterator>
minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);
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);
// 25.4.9, permutations:
template<class BidirectionalIterator>
§ 25.1 882
c
ISO/IEC N????
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);
}
3All of the algorithms are separated from the particular implementations of data structures and are param-
eterized 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.
4For purposes of determining the existence of data races, algorithms shall not modify objects referenced
through an iterator argument unless the specification requires such modification.
5Throughout this Clause, the names of template parameters are used to express type requirements. If an al-
gorithm’s template parameter is InputIterator,InputIterator1, or InputIterator2, the actual template
argument shall satisfy the requirements of an input iterator (24.2.3). If an algorithm’s template parameter
is OutputIterator,OutputIterator1, or OutputIterator2, the actual template argument shall satisfy
the requirements of an output iterator (24.2.4). If an algorithm’s template parameter is ForwardIterator,
ForwardIterator1, or ForwardIterator2, the actual template argument shall satisfy the requirements of a
forward iterator (24.2.5). If an algorithm’s template parameter is BidirectionalIterator,Bidirectional-
Iterator1, or BidirectionalIterator2, the actual template argument shall satisfy the requirements of
a bidirectional iterator (24.2.6). If an algorithm’s template parameter is RandomAccessIterator,Random-
AccessIterator1, or RandomAccessIterator2, the actual template argument shall satisfy the requirements
of a random-access iterator (24.2.7).
6If 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 (24.2). [ Note: This requirement does not affect arguments that
are declared as OutputIterator,OutputIterator1, or OutputIterator2, because output iterators must
always be mutable. — end note ]
7Both in-place and copying versions are provided for certain algorithms.271 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).
8The Predicate parameter is used whenever an algorithm expects a function object (20.10) 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 4). The function
object pred shall not apply any non-constant function through the dereferenced iterator.
9The BinaryPredicate parameter is used whenever an algorithm expects a function object that when ap-
plied to the result of dereferencing two corresponding iterators or to dereferencing an iterator and type
Twhen Tis 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 4).
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,
271) 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.
§ 25.1 883
c
ISO/IEC N????
value) contextually converted to bool (Clause 4). binary_pred shall not apply any non-constant function
through the dereferenced iterators.
10 [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> (20.10.3),
or some equivalent solution. — end note ]
11 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.
12 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);
25.2 Non-modifying sequence operations [alg.nonmodifying]
25.2.1 All of [alg.all_of]
template <class InputIterator, class Predicate>
bool all_of(InputIterator first, InputIterator last, Predicate pred);
1Returns: true if [first,last) is empty or if pred(*i) is true for every iterator iin the range
[first,last), and false otherwise.
2Complexity: At most last - first applications of the predicate.
25.2.2 Any of [alg.any_of]
template <class InputIterator, class Predicate>
bool any_of(InputIterator first, InputIterator last, Predicate pred);
1Returns: false if [first,last) is empty or if there is no iterator iin the range [first,last) such
that pred(*i) is true, and true otherwise.
2Complexity: At most last - first applications of the predicate.
25.2.3 None of [alg.none_of]
template <class InputIterator, class Predicate>
bool none_of(InputIterator first, InputIterator last, Predicate pred);
1Returns: true if [first,last) is empty or if pred(*i) is false for every iterator iin the range
[first,last), and false otherwise.
2Complexity: At most last - first applications of the predicate.
25.2.4 For each [alg.foreach]
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
1Requires: Function shall meet the requirements of MoveConstructible (Table 20). [ Note: Function
need not meet the requirements of CopyConstructible (Table 21). — end note ]
§ 25.2.4 884
c
ISO/IEC N????
2Effects: Applies fto 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, fmay apply nonconstant functions through the dereferenced iterator. — end note ]
3Returns: std::move(f).
4Complexity: Applies fexactly last - first times.
5Remarks: If freturns a result, the result is ignored.
25.2.5 Find [alg.find]
template<class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last,
const T& value);
template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
Predicate pred);
template<class InputIterator, class Predicate>
InputIterator find_if_not(InputIterator first, InputIterator last,
Predicate pred);
1Returns: The first iterator iin the range [first,last) for which the following corresponding condi-
tions hold: *i == value,pred(*i) != false,pred(*i) == false. Returns last if no such iterator
is found.
2Complexity: At most last - first applications of the corresponding predicate.
25.2.6 Find end [alg.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);
1Effects: Finds a subsequence of equal values in a sequence.
2Returns: The last iterator iin the range [first1,last1 - (last2 - first2)) such that for any 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.
3Complexity: At most (last2 - first2) * (last1 - first1 - (last2 - first2) + 1) applica-
tions of the corresponding predicate.
25.2.7 Find first [alg.find.first.of]
template<class InputIterator, class ForwardIterator>
InputIterator
find_first_of(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2);
§ 25.2.7 885
c
ISO/IEC N????
template<class InputIterator, class ForwardIterator,
class BinaryPredicate>
InputIterator
find_first_of(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
BinaryPredicate pred);
1Effects: Finds an element that matches one of a set of values.
2Returns: The first iterator iin the range [first1,last1) such that for some iterator jin 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.
3Complexity: At most (last1-first1) * (last2-first2) applications of the corresponding predi-
cate.
25.2.8 Adjacent find [alg.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);
1Returns: The first iterator isuch that both iand i+1are 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.
2Complexity: For a nonempty range, exactly min((i - first) + 1, (last - first) - 1) applica-
tions of the corresponding predicate, where iis adjacent_find’s return value.
25.2.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 InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred);
1Effects: Returns the number of iterators iin the range [first,last) for which the following corre-
sponding conditions hold: *i == value, pred(*i) != false.
2Complexity: Exactly last - first applications of the corresponding predicate.
25.2.10 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,
§ 25.2.10 886
c
ISO/IEC N????
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);
1Remarks: If last2 was not given in the argument list, it denotes first2 + (last1 - first1) below.
2Returns: A pair of iterators iand jsuch that j == first2 + (i - first1) and iis the first iterator
in the range [first1,last1) for which the following corresponding conditions hold:
jis in the range [first2, last2).
!(*i == *(first2 + (i - first1)))
pred(*i, *(first2 + (i - first1))) == false
Returns the pair first1 + min(last1 - first1, last2 - first2) and first2 + min(last1 -
first1, last2 - first2) if such an iterator iis not found.
3Complexity: At most last1 - first1 applications of the corresponding predicate.
25.2.11 Equal [alg.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);
1Remarks: If last2 was not given in the argument list, it denotes first2 + (last1 - first1) below.
2Returns: If last1 - first1 != last2 - first2, return false. Otherwise return true if for every
iterator iin the range [first1,last1) the following corresponding conditions hold: *i == *(first2
+ (i - first1)), pred(*i, *(first2 + (i - first1))) != false. Otherwise, returns false.
3Complexity: No applications of the corresponding predicate if InputIterator1 and InputIterator2
meet the requirements of random access iterators and last1 - first1 != last2 - first2. Other-
wise, at most min(last1 - first1, last2 - first2) applications of the corresponding predicate.
§ 25.2.11 887
c
ISO/IEC N????
25.2.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);
1Requires: ForwardIterator1 and ForwardIterator2 shall have the same value type. The comparison
function shall be an equivalence relation.
2Remarks: If last2 was not given in the argument list, it denotes first2 + (last1 - first1) below.
3Returns: 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.
4Complexity: No applications of the corresponding predicate if ForwardIterator1 and ForwardIter-
ator2 meet the requirements of random access iterators and last1 - first1 != last2 - first2.
Otherwise, exactly distance(first1, last1) 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 O(N2), where Nhas the value distance(first1, last1).
25.2.13 Search [alg.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);
1Effects: Finds a subsequence of equal values in a sequence.
2Returns: The first iterator iin the range [first1,last1 - (last2-first2)) such that for any non-
negative integer nless 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.
3Complexity: At most (last1 - first1) * (last2 - first2) applications of the corresponding
predicate.
§ 25.2.13 888
c
ISO/IEC N????
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);
4Requires: The type Size shall be convertible to integral type (4.7,12.3).
5Effects: Finds a subsequence of equal values in a sequence.
6Returns: The first iterator iin the range [first,last-count) such that for any non-negative integer
nless than count the following corresponding conditions hold: *(i + n) == value, pred(*(i +
n),value) != false. Returns last if no such iterator is found.
7Complexity: At most last - first applications of the corresponding predicate.
25.3 Mutating sequence operations [alg.modifying.operations]
25.3.1 Copy [alg.copy]
template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result);
1Effects: 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).
2Returns: result + (last - first).
3Requires: result shall not be in the range [first,last).
4Complexity: Exactly last - first assignments.
template<class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n(InputIterator first, Size n,
OutputIterator result);
5Effects: For each non-negative integer i<n, performs *(result + i) = *(first + i).
6Returns: result + n.
7Complexity: Exactly nassignments.
template<class InputIterator, class OutputIterator, class Predicate>
OutputIterator copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred);
8Requires: The ranges [first,last) and [result,result + (last - first)) shall not overlap.
9Effects: Copies all of the elements referred to by the iterator iin the range [first,last) for which
pred(*i) is true.
10 Returns: The end of the resulting range.
11 Complexity: Exactly last - first applications of the corresponding predicate.
12 Remarks: Stable (17.6.5.7).
§ 25.3.1 889
c
ISO/IEC N????
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2
copy_backward(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result);
13 Effects: Copies elements in the range [first,last) into the range [result - (last-first),result
)starting from last - 1 and proceeding to first.272 For each positive integer n <= (last - first),
performs *(result - n) = *(last - n).
14 Requires: result shall not be in the range (first,last].
15 Returns: result - (last - first).
16 Complexity: Exactly last - first assignments.
25.3.2 Move [alg.move]
template<class InputIterator, class OutputIterator>
OutputIterator move(InputIterator first, InputIterator last,
OutputIterator result);
1Effects: 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)).
2Returns: result + (last - first).
3Requires: result shall not be in the range [first,last).
4Complexity: Exactly last - first move assignments.
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2
move_backward(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result);
5Effects: Moves elements in the range [first,last) into the range [result - (last-first),result
)starting from last - 1 and proceeding to first.273 For each positive integer n <= (last - first),
performs *(result - n) = std::move(*(last - n)).
6Requires: result shall not be in the range (first,last].
7Returns: result - (last - first).
8Complexity: Exactly last - first assignments.
25.3.3 swap [alg.swap]
template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator2
swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2);
272) copy_backward should be used instead of copy when last is in the range [result - (last - first),result).
273) move_backward should be used instead of move when last is in the range [result - (last - first),result).
§ 25.3.3 890
c
ISO/IEC N????
1Effects: For each non-negative integer n < (last1 - first1) performs: swap(*(first1 + n),
*(first2 + n)).
2Requires: The two ranges [first1,last1) and [first2,first2 + (last1 - first1)) shall not
overlap. *(first1 + n) shall be swappable with (17.6.3.2)*(first2 + n).
3Returns: first2 + (last1 - first1).
4Complexity: Exactly last1 - first1 swaps.
template<class ForwardIterator1, class ForwardIterator2>
void iter_swap(ForwardIterator1 a, ForwardIterator2 b);
5Effects: swap(*a, *b).
6Requires: aand bshall be dereferenceable. *a shall be swappable with (17.6.3.2)*b.
25.3.4 Transform [alg.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);
1Effects: Assigns through every iterator iin 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))).
2Requires: 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)].274
3Returns: result + (last1 - first1).
4Complexity: Exactly last1 - first1 applications of op or binary_op.
5Remarks: result may be equal to first in case of unary transform, or to first1 or first2 in case
of binary transform.
25.3.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 ForwardIterator, class Predicate, class T>
void replace_if(ForwardIterator first, ForwardIterator last,
Predicate pred, const T& new_value);
274) The use of fully closed ranges is intentional.
§ 25.3.5 891
c
ISO/IEC N????
1Requires: The expression *first = new_value shall be valid.
2Effects: Substitutes elements referred by the iterator iin the range [first,last) with new_value,
when the following corresponding conditions hold: *i == old_value,pred(*i) != false.
3Complexity: 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 InputIterator, class OutputIterator, class Predicate, class T>
OutputIterator
replace_copy_if(InputIterator first, InputIterator last,
OutputIterator result,
Predicate pred, const T& new_value);
4Requires: The results of the expressions *first and new_value shall be writable to the result output
iterator. The ranges [first,last) and [result,result + (last - first)) shall not overlap.
5Effects: Assigns to every iterator iin 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
6Returns: result + (last - first).
7Complexity: Exactly last - first applications of the corresponding predicate.
25.3.6 Fill [alg.fill]
template<class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value);
template<class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T& value);
1Requires: The expression value shall be writable to the output iterator. The type Size shall be
convertible to an integral type (4.7,12.3).
2Effects: The first algorithm assigns value through all the iterators in the range [first,last). The
second algorithm assigns value through all the iterators in the range [first,first + n) if nis
positive, otherwise it does nothing.
3Returns: fill_n returns first + n for non-negative values of nand first for negative values.
4Complexity: Exactly last - first,n, or 0 assignments, respectively.
25.3.7 Generate [alg.generate]
template<class ForwardIterator, class Generator>
void generate(ForwardIterator first, ForwardIterator last,
Generator gen);
template<class OutputIterator, class Size, class Generator>
OutputIterator generate_n(OutputIterator first, Size n, Generator gen);
§ 25.3.7 892
c
ISO/IEC N????
1Effects: The first algorithm invokes the function object gen and assigns the return value of gen through
all the iterators in the range [first,last). The second algorithm invokes the function object gen
and assigns the return value of gen through all the iterators in the range [first,first + n) if nis
positive, otherwise it does nothing.
2Requires: gen takes no arguments, Size shall be convertible to an integral type (4.7,12.3).
3Returns: generate_n returns first + n for non-negative values of nand first for negative values.
4Complexity: Exactly last - first,n, or 0 invocations of gen and assignments, respectively.
25.3.8 Remove [alg.remove]
template<class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T& value);
template<class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
Predicate pred);
1Requires: The type of *first shall satisfy the MoveAssignable requirements (Table 22).
2Effects: Eliminates all the elements referred to by iterator iin the range [first,last) for which the
following corresponding conditions hold: *i == value, pred(*i) != false.
3Returns: The end of the resulting range.
4Remarks: Stable (17.6.5.7).
5Complexity: Exactly last - first applications of the corresponding predicate.
6Note: each element in the range [ret,last), where ret is the returned value, has a valid but unspeci-
fied state, because the algorithms can eliminate elements by moving from elements that were originally
in that range.
template<class InputIterator, class OutputIterator, class T>
OutputIterator
remove_copy(InputIterator first, InputIterator last,
OutputIterator result, const T& value);
template<class InputIterator, class OutputIterator, class Predicate>
OutputIterator
remove_copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred);
7Requires: The ranges [first,last) and [result,result + (last - first)) shall not overlap. The
expression *result = *first shall ve valid.
8Effects: Copies all the elements referred to by the iterator iin the range [first,last) for which the
following corresponding conditions do not hold: *i == value, pred(*i) != false.
9Returns: The end of the resulting range.
10 Complexity: Exactly last - first applications of the corresponding predicate.
11 Remarks: Stable (17.6.5.7).
§ 25.3.8 893
c
ISO/IEC N????
25.3.9 Unique [alg.unique]
template<class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class BinaryPredicate>
ForwardIterator unique(ForwardIterator first, ForwardIterator last,
BinaryPredicate pred);
1Effects: For a nonempty range, eliminates all but the first element from every consecutive group of
equivalent elements referred to by the iterator iin the range [first + 1,last) for which the following
conditions hold: *(i - 1) == *i or pred(*(i - 1), *i) != false.
2Requires: The comparison function shall be an equivalence relation. The type of *first shall satisfy
the MoveAssignable requirements (Table 22).
3Returns: The end of the resulting range.
4Complexity: 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 InputIterator, class OutputIterator,
class BinaryPredicate>
OutputIterator
unique_copy(InputIterator first, InputIterator last,
OutputIterator result, BinaryPredicate pred);
5Requires: 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.
If neither InputIterator nor OutputIterator meets the requirements of forward iterator then the
value type of InputIterator shall be CopyConstructible (Table 21) and CopyAssignable (Table 23).
Otherwise CopyConstructible is not required.
6Effects: Copies only the first element from every consecutive group of equal elements referred to by
the iterator iin the range [first,last) for which the following corresponding conditions hold: *i
== *(i - 1) or pred(*i, *(i - 1)) != false.
7Returns: The end of the resulting range.
8Complexity: For nonempty ranges, exactly last - first - 1 applications of the corresponding pred-
icate.
25.3.10 Reverse [alg.reverse]
template<class BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last);
1Effects: For each non-negative integer i < (last - first)/2, applies iter_swap to all pairs of iter-
ators first + i, (last - i) - 1.
2Requires: *first shall be swappable (17.6.3.2).
3Complexity: Exactly (last - first)/2 swaps.
§ 25.3.10 894
c
ISO/IEC N????
template<class BidirectionalIterator, class OutputIterator>
OutputIterator
reverse_copy(BidirectionalIterator first,
BidirectionalIterator last, OutputIterator result);
4Effects: Copies the range [first,last) to the range [result,result+(last-first)) such that
for any non-negative integer i < (last - first) the following assignment takes place: *(result +
(last - first) - 1 - i) = *(first + i).
5Requires: The ranges [first,last) and [result,result+(last-first)) shall not overlap.
6Returns: result + (last - first).
7Complexity: Exactly last - first assignments.
25.3.11 Rotate [alg.rotate]
template<class ForwardIterator>
ForwardIterator rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last);
1Effects: For each non-negative integer i < (last - first), places the element from the position
first + i into position first + (i + (last - middle)) % (last - first).
2Returns: first + (last - middle).
3Remarks: This is a left rotate.
4Requires: [first,middle) and [middle,last) shall be valid ranges. ForwardIterator shall satisfy
the requirements of ValueSwappable (17.6.3.2). The type of *first shall satisfy the requirements of
MoveConstructible (Table 20) and the requirements of MoveAssignable (Table 22).
5Complexity: At most last - first swaps.
template<class ForwardIterator, class OutputIterator>
OutputIterator
rotate_copy(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result);
6Effects: 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)).
7Returns: result + (last - first).
8Requires: The ranges [first,last) and [result,result + (last - first)) shall not overlap.
9Complexity: Exactly last - first assignments.
25.3.12 Random shuffle [alg.random.shuffle]
template<class RandomAccessIterator>
void random_shuffle(RandomAccessIterator first,
RandomAccessIterator last);
template<class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(RandomAccessIterator first,
RandomAccessIterator last,
RandomNumberGenerator&& rand);
§ 25.3.12 895
c
ISO/IEC N????
template<class RandomAccessIterator, class UniformRandomNumberGenerator>
void shuffle(RandomAccessIterator first,
RandomAccessIterator last,
UniformRandomNumberGenerator&& g);
1Effects: Permutes the elements in the range [first,last) such that each possible permutation of
those elements has equal probability of appearance.
2Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
random number generating function object rand shall have a return type that is convertible to
iterator_traits<RandomAccessIterator>::difference_type, and the call rand(n) shall return
a randomly chosen value in the interval [0,n), for n>0of type iterator_traits<RandomAccess-
Iterator>::difference_type. The type UniformRandomNumberGenerator shall meet the require-
ments of a uniform random number generator (26.5.1.3) type whose return type is convertible to
iterator_traits<RandomAccessIterator>::difference_type.
3Complexity: Exactly (last - first) - 1 swaps.
4Remarks: To the extent that the implementation of these functions makes use of random numbers, the
implementation shall use the following sources of randomness:
The underlying source of random numbers for the first form of the function is implementation-defined.
An implementation may use the rand function from the standard C library.
In the second form of the function, the function object rand shall serve as the implementation’s source
of randomness.
In the third shuffle form of the function, the object gshall serve as the implementation’s source of
randomness.
25.3.13 Partitions [alg.partitions]
template <class InputIterator, class Predicate>
bool is_partitioned(InputIterator first, InputIterator last, Predicate pred);
1Requires: InputIterator’s value type shall be convertible to Predicate’s argument type.
2Returns: 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.
3Complexity: Linear. At most last - first applications of pred.
template<class ForwardIterator, class Predicate>
ForwardIterator
partition(ForwardIterator first,
ForwardIterator last, Predicate pred);
4Effects: Places all the elements in the range [first,last) that satisfy pred before all the elements
that do not satisfy it.
5Returns: An iterator isuch that for any iterator jin the range [first,i) pred(*j) != false, and
for any iterator kin the range [i,last),pred(*k) == false.
6Requires: ForwardIterator shall satisfy the requirements of ValueSwappable (17.6.3.2).
7Complexity: If ForwardIterator meets the requirements for a BidirectionalIterator, at most (last -
first) / 2 swaps are done; otherwise at most last - first swaps are done. Exactly last - first
applications of the predicate are done.
§ 25.3.13 896
c
ISO/IEC N????
template<class BidirectionalIterator, class Predicate>
BidirectionalIterator
stable_partition(BidirectionalIterator first,
BidirectionalIterator last, Predicate pred);
8Effects: Places all the elements in the range [first,last) that satisfy pred before all the elements
that do not satisfy it.
9Returns: An iterator isuch that for any iterator jin the range [first,i),pred(*j) != false, and
for any iterator kin the range [i,last),pred(*k) == false. The relative order of the elements in
both groups is preserved.
10 Requires: BidirectionalIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable
(Table 22).
11 Complexity: At most (last - first) * log(last - first) swaps, but only linear number of swaps
if there is enough extra memory. Exactly last - first 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);
12 Requires: InputIterator’s value type shall be Assignable, and shall be writable to the out_true
and out_false OutputIterators, and shall be convertible to Predicate’s argument type. The input
range shall not overlap with either of the output ranges.
13 Effects: For each iterator iin [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.
14 Returns: A pair psuch 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.
15 Complexity: Exactly last - first applications of pred.
template<class ForwardIterator, class Predicate>
ForwardIterator partition_point(ForwardIterator first,
ForwardIterator last,
Predicate pred);
16 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.
17 Returns: An iterator mid such that all_of(first, mid, pred) and none_of(mid, last, pred) are
both true.
18 Complexity: O(log(last first)) applications of pred.
25.4 Sorting and related operations [alg.sorting]
1All the operations in 25.4 have two versions: one that takes a function object of type Compare and one that
uses an operator<.
2Compare is a function object type (20.10). The return value of the function call operation applied to an
object of type Compare, when contextually converted to bool (Clause 4), yields true if the first argument
§ 25.4 897
c
ISO/IEC N????
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.
3For 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 25.4.3 to work
correctly, comp has to induce a strict weak ordering on the values.
4The 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 ]
5A sequence is sorted with respect to a comparator comp if for any iterator ipointing to the sequence and any
non-negative integer nsuch that i+nis a valid iterator pointing to an element of the sequence, comp(*(i
+ n), *i) == false.
6A sequence [start,finish) is partitioned with respect to an expression f(e) if there exists an integer n
such that for all 0 <= i < distance(start, finish),f(*(start + i)) is true if and only if i<n.
7In 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 aand
bare considered equivalent if and only if !(a < b) && !(b < a).
25.4.1 Sorting [alg.sort]
25.4.1.1 sort [sort]
template<class RandomAccessIterator>
void sort(RandomAccessIterator first, RandomAccessIterator last);
template<class RandomAccessIterator, class Compare>
void sort(RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
1Effects: Sorts the elements in the range [first,last).
2Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable
(Table 22).
3Complexity: O(Nlog(N)) (where N== last - first) comparisons.
25.4.1.2 stable_sort [stable.sort]
template<class RandomAccessIterator>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
template<class RandomAccessIterator, class Compare>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
§ 25.4.1.2 898
c
ISO/IEC N????
1Effects: Sorts the elements in the range [first,last).
2Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable
(Table 22).
3Complexity: It does at most Nlog2(N)(where N== last - first) comparisons; if enough extra
memory is available, it is Nlog(N).
4Remarks: Stable (17.6.5.7).
25.4.1.3 partial_sort [partial.sort]
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);
1Effects: 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.
2Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable
(Table 22).
3Complexity: It takes approximately (last - first) * log(middle - first) comparisons.
25.4.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 InputIterator, class RandomAccessIterator,
class Compare>
RandomAccessIterator
partial_sort_copy(InputIterator first, InputIterator last,
RandomAccessIterator result_first,
RandomAccessIterator result_last,
Compare comp);
1Effects: 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)).
2Returns: The smaller of: result_last or result_first + (last - first).
3Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
type of *result_first shall satisfy the requirements of MoveConstructible (Table 20) and of Move-
Assignable (Table 22).
4Complexity: Approximately (last - first) * log(min(last - first, result_last - result_-
first)) comparisons.
§ 25.4.1.4 899
c
ISO/IEC N????
25.4.1.5 is_sorted [is.sorted]
template<class ForwardIterator>
bool is_sorted(ForwardIterator first, ForwardIterator last);
1Returns: is_sorted_until(first, last) == last
template<class ForwardIterator, class Compare>
bool is_sorted(ForwardIterator first, ForwardIterator last,
Compare comp);
2Returns: is_sorted_until(first, last, comp) == last
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);
3Returns: If distance(first, last) < 2, returns last. Otherwise, returns the last iterator iin
[first,last] for which the range [first,i) is sorted.
4Complexity: Linear.
25.4.2 Nth element [alg.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);
1After 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. Also for any iterator iin the range [first,nth) and any
iterator jin the range [nth,last) it holds that: !(*j < *i) or comp(*j, *i) == false.
2Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable
(Table 22).
3Complexity: Linear on average.
25.4.3 Binary search [alg.binary.search]
1All 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.
25.4.3.1 lower_bound [lower.bound]
§ 25.4.3.1 900
c
ISO/IEC N????
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);
1Requires: The elements eof [first,last) shall be partitioned with respect to the expression e <
value or comp(e, value).
2Returns: The furthermost iterator iin the range [first,last] such that for any iterator jin the
range [first,i) the following corresponding conditions hold: *j < value or comp(*j, value) !=
false.
3Complexity: At most log2(last first) + O(1) comparisons.
25.4.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);
1Requires: The elements eof [first,last) shall be partitioned with respect to the expression !(value
< e) or !comp(value, e).
2Returns: The furthermost iterator iin the range [first,last] such that for any iterator jin the
range [first,i) the following corresponding conditions hold: !(value < *j) or comp(value, *j)
== false.
3Complexity: At most log2(last first) + O(1) comparisons.
25.4.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);
1Requires: The elements eof [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 eof
[first, last),e < value shall imply !(value < e) or comp(e, value) shall imply !comp(value,
e).
2Returns:
§ 25.4.3.3 901
c
ISO/IEC N????
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))
3Complexity: At most 2log2(last first) + O(1) comparisons.
25.4.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);
1Requires: The elements eof [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 eof [first,
last),e < value implies !(value < e) or comp(e, value) implies !comp(value, e).
2Returns: true if there is an iterator iin the range [first,last) that satisfies the corresponding condi-
tions: !(*i < value) && !(value < *i) or comp(*i, value) == false && comp(value, *i) ==
false.
3Complexity: At most log2(last - first) +O(1) comparisons.
25.4.4 Merge [alg.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);
1Effects: 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.
2Requires: 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.
3Returns: result + (last1 - first1) + (last2 - first2).
4Complexity: At most (last1 - first1) + (last2 - first2) - 1 comparisons.
5Remarks: Stable (17.6.5.7).
§ 25.4.4 902
c
ISO/IEC N????
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);
6Effects: 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 iin [first,last) other than first, the condition *i < *(i - 1) or, respectively,
comp(*i, *(i - 1)) will be false.
7Requires: The ranges [first,middle) and [middle,last) shall be sorted with respect to operator<
or comp.BidirectionalIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The
type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable
(Table 22).
8Complexity: When enough additional memory is available, (last - first) - 1 comparisons. If no
additional memory is available, an algorithm with complexity Nlog(N)(where Nis equal to last -
first) may be used.
9Remarks: Stable (17.6.5.7).
25.4.5 Set operations on sorted structures [alg.set.operations]
1This section defines all the basic set operations on sorted structures. They also work with multisets (23.4.7)
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.
25.4.5.1 includes [includes]
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);
1Returns: true if [first2,last2) is empty or if every element in the range [first2,last2) is con-
tained in the range [first1,last1). Returns false otherwise.
2Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
25.4.5.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);
§ 25.4.5.2 903
c
ISO/IEC N????
template<class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator
set_union(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
1Effects: 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.
2Requires: The resulting range shall not overlap with either of the original ranges.
3Returns: The end of the constructed range.
4Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
5Remarks: If [first1,last1) contains melements that are equivalent to each other and [first2,
last2) contains nelements that are equivalent to them, then all melements from the first range shall
be copied to the output range, in order, and then max(nm, 0) elements from the second range shall
be copied to the output range, in order.
25.4.5.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 InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator
set_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
1Effects: 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.
2Requires: The resulting range shall not overlap with either of the original ranges.
3Returns: The end of the constructed range.
4Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
5Remarks: If [first1,last1) contains melements that are equivalent to each other and [first2,
last2) contains nelements that are equivalent to them, the first min(m, n)elements shall be copied
from the first range to the output range, in order.
25.4.5.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 InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
§ 25.4.5.4 904
c
ISO/IEC N????
OutputIterator
set_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
1Effects: 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.
2Requires: The resulting range shall not overlap with either of the original ranges.
3Returns: The end of the constructed range.
4Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
5Remarks: If [first1,last1) contains melements that are equivalent to each other and [first2,
last2) contains nelements that are equivalent to them, the last max(mn, 0) elements from [first1,
last1) shall be copied to the output range.
25.4.5.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 InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator
set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
1Effects: 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.
2Requires: The resulting range shall not overlap with either of the original ranges.
3Returns: The end of the constructed range.
4Complexity: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons.
5Remarks: If [first1,last1) contains melements that are equivalent to each other and [first2,
last2) contains nelements that are equivalent to them, then |mn|of those elements shall be copied
to the output range: the last mnof these elements from [first1,last1) if m>n, and the last
nmof these elements from [first2,last2) if m<n.
25.4.6 Heap operations [alg.heap.operations]
1Aheap is a particular organization of elements in a range between two random access iterators [a,b). Its
two key properties are:
(1) There is no element greater than *a in the range and
(2) *a may be removed by pop_heap(), or a new element added by push_heap(), in O(log(N)) time.
2These properties make heaps useful as priority queues.
3make_heap() converts a range into a heap and sort_heap() turns a heap into a sorted sequence.
§ 25.4.6 905
c
ISO/IEC N????
25.4.6.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);
1Effects: Places the value in the location last - 1 into the resulting heap [first,last).
2Requires: The range [first,last - 1) shall be a valid heap. The type of *first shall satisfy the
MoveConstructible requirements (Table 20) and the MoveAssignable requirements (Table 22).
3Complexity: At most log(last - first) comparisons.
25.4.6.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);
1Requires: The range [first,last) shall be a valid non-empty heap. RandomAccessIterator shall sat-
isfy the requirements of ValueSwappable (17.6.3.2). The type of *first shall satisfy the requirements
of MoveConstructible (Table 20) and of MoveAssignable (Table 22).
2Effects: Swaps the value in the location first with the value in the location last - 1 and makes
[first,last - 1) into a heap.
3Complexity: At most 2 * log(last - first) comparisons.
25.4.6.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);
1Effects: Constructs a heap out of the range [first,last).
2Requires: The type of *first shall satisfy the MoveConstructible requirements (Table 20) and the
MoveAssignable requirements (Table 22).
3Complexity: At most 3 * (last - first) comparisons.
25.4.6.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);
1Effects: Sorts elements in the heap [first,last).
§ 25.4.6.4 906
c
ISO/IEC N????
2Requires: The range [first,last) shall be a valid heap. RandomAccessIterator shall satisfy the
requirements of ValueSwappable (17.6.3.2). The type of *first shall satisfy the requirements of
MoveConstructible (Table 20) and of MoveAssignable (Table 22).
3Complexity: At most Nlog(N)comparisons (where N == last - first).
25.4.6.5 is_heap [is.heap]
template<class RandomAccessIterator>
bool is_heap(RandomAccessIterator first, RandomAccessIterator last);
1Returns: is_heap_until(first, last) == last
template<class RandomAccessIterator, class Compare>
bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
2Returns: is_heap_until(first, last, comp) == last
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);
3Returns: If distance(first, last) < 2, returns last. Otherwise, returns the last iterator iin
[first,last] for which the range [first,i) is a heap.
4Complexity: Linear.
25.4.7 Minimum and maximum [alg.min.max]
template<class T> const T& min(const T& a, const T& b);
template<class T, class Compare>
const T& min(const T& a, const T& b, Compare comp);
1Requires: Type Tis LessThanComparable (Table 18).
2Returns: The smaller value.
3Remarks: Returns the first argument when the arguments are equivalent.
template<class T>
T min(initializer_list<T> t);
template<class T, class Compare>
T min(initializer_list<T> t, Compare comp);
4Requires: Tis LessThanComparable and CopyConstructible and t.size() > 0.
5Returns: The smallest value in the initializer_list.
6Remarks: Returns a copy of the leftmost argument when several arguments are equivalent to the
smallest.
template<class T> const T& max(const T& a, const T& b);
template<class T, class Compare>
const T& max(const T& a, const T& b, Compare comp);
§ 25.4.7 907
c
ISO/IEC N????
7Requires: Type Tis LessThanComparable (Table 18).
8Returns: The larger value.
9Remarks: Returns the first argument when the arguments are equivalent.
template<class T>
T max(initializer_list<T> t);
template<class T, class Compare>
T max(initializer_list<T> t, Compare comp);
10 Requires: Tis LessThanComparable and CopyConstructible and t.size() > 0.
11 Returns: The largest value in the initializer_list.
12 Remarks: Returns a copy of the leftmost argument when several arguments are equivalent to the
largest.
template<class T> pair<const T&, const T&> minmax(const T& a, const T& b);
template<class T, class Compare>
pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp);
13 Requires: Type Tshall be LessThanComparable (Table 18).
14 Returns: pair<const T&, const T&>(b, a) if bis smaller than a, and pair<const T&, const
T&>(a, b) otherwise.
15 Remarks: Returns pair<const T&, const T&>(a, b) when the arguments are equivalent.
16 Complexity: Exactly one comparison.
template<class T>
pair<T, T> minmax(initializer_list<T> t);
template<class T, class Compare>
pair<T, T> minmax(initializer_list<T> t, Compare comp);
17 Requires: Tis LessThanComparable and CopyConstructible and t.size() > 0.
18 Returns: pair<T, T>(x, y), where xhas the smallest and yhas the largest value in the initializer
list.
19 Remarks: xis a copy of the leftmost argument when several arguments are equivalent to the smallest.
yis a copy of the rightmost argument when several arguments are equivalent to the largest.
20 Complexity: At most (3/2) * t.size() applications of the corresponding predicate.
template<class ForwardIterator>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
Compare comp);
21 Returns: The first iterator iin the range [first,last) such that for any iterator jin the range
[first,last) the following corresponding conditions hold: !(*j < *i) or comp(*j, *i) == false.
Returns last if first == last.
22 Complexity: Exactly max((last - first) - 1, 0) applications of the corresponding comparisons.
§ 25.4.7 908
c
ISO/IEC N????
template<class ForwardIterator>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
Compare comp);
23 Returns: The first iterator iin the range [first,last) such that for any iterator jin the range
[first,last) the following corresponding conditions hold: !(*i < *j) or comp(*i, *j) == false.
Returns last if first == last.
24 Complexity: Exactly max((last - first) - 1, 0) applications of the corresponding comparisons.
template<class ForwardIterator>
pair<ForwardIterator, ForwardIterator>
minmax_element(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
pair<ForwardIterator, ForwardIterator>
minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);
25 Returns: make_pair(first, first) if [first,last) is empty, otherwise make_pair(m, M), where
mis the first iterator in [first,last) such that no iterator in the range refers to a smaller element,
and where Mis the last iterator in [first,last) such that no iterator in the range refers to a larger
element.
26 Complexity: At most max(b3
2(N1)c,0) applications of the corresponding predicate, where Nis
distance(first, last).
25.4.8 Lexicographical comparison [alg.lex.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);
1Returns: 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.
2Complexity: At most 2*min((last1 - first1), (last2 - first2)) applications of the correspond-
ing comparison.
3Remarks: If two sequences have the same number of elements and their corresponding elements 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.
for ( ; first1 != last1 && first2 != last2 ; ++first1, ++first2) {
if (*first1 < *first2) return true;
if (*first2 < *first1) return false;
}
return first1 == last1 && first2 != last2;
§ 25.4.8 909
c
ISO/IEC N????
4Remarks: An empty sequence is lexicographically less than any non-empty sequence, but not less than
any empty sequence.
25.4.9 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);
1Effects: Takes a sequence defined by the range [first,last) and transforms it into the next permu-
tation. The next permutation is found by assuming that the set of all permutations is lexicographically
sorted with respect to operator< or comp. If such a permutation exists, it returns true. Otherwise, it
transforms the sequence into the smallest permutation, that is, the ascendingly sorted one, and returns
false.
2Requires: BidirectionalIterator shall satisfy the requirements of ValueSwappable (17.6.3.2).
3Complexity: 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);
4Effects: 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.
5Returns: true if such a permutation exists. Otherwise, it transforms the sequence into the largest
permutation, that is, the descendingly sorted one, and returns false.
6Requires: BidirectionalIterator shall satisfy the requirements of ValueSwappable (17.6.3.2).
7Complexity: At most (last - first)/2 swaps.
25.5 C library algorithms [alg.c.library]
1Table 113 describes some of the contents of the header <cstdlib>.
Table 113 — Header <cstdlib> synopsis
Type Name(s)
Type:size_t
Functions:bsearch qsort
2The contents are the same as the Standard C library header <stdlib.h> with the following exceptions:
3The function signature:
bsearch(const void *, const void *, size_t, size_t,
int (*)(const void *, const void *));
§ 25.5 910
c
ISO/IEC N????
is replaced by the two declarations:
extern "C" void* bsearch(const void* key, const void* base,
size_t nmemb, size_t size,
int (*compar)(const void*, const void*));
extern "C++" void* bsearch(const void* key, const void* base,
size_t nmemb, size_t size,
int (*compar)(const void*, const void*));
both of which have the same behavior as the original declaration.
4The function signature:
qsort(void *, size_t, size_t,
int (*)(const void *, const void *));
is replaced by the two declarations:
extern "C" void qsort(void* base, size_t nmemb, size_t size,
int (*compar)(const void*, const void*));
extern "C++" void qsort(void* base, size_t nmemb, size_t size,
int (*compar)(const void*, const void*));
both of which have the same behavior as the original declaration. The behavior is undefined unless the
objects in the array pointed to by base are of trivial type.
[Note: Because the function argument compar() may throw an exception, bsearch() and qsort() are
allowed to propagate the exception (17.6.5.12). — end note ]
See also: ISO C 7.10.5.
§ 25.5 911
c
ISO/IEC N????
26 Numerics library [numerics]
26.1 General [numerics.general]
1This Clause describes components that C++ programs may use to perform seminumerical operations.
2The following subclauses describe components for complex number types, random number generation, nu-
meric (n-at-a-time) arrays, generalized numeric algorithms, and facilities included from the ISO C library,
as summarized in Table 114.
Table 114 — Numerics library summary
Subclause Header(s)
26.2 Requirements
26.3 Floating-Point Environment <cfenv>
26.4 Complex Numbers <complex>
26.5 Random number generation <random>
26.6 Numeric arrays <valarray>
26.7 Generalized numeric operations <numeric>
26.8 C library <cmath>
<ctgmath>
<tgmath.h>
<cstdlib>
26.2 Numeric type requirements [numeric.requirements]
1The 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 Tthat satisfies the following
requirements:275
Tis not an abstract class (it has no pure virtual member functions);
Tis not a reference type;
Tis not cv-qualified;
If Tis a class, it has a public default constructor;
If Tis a class, it has a public copy constructor with the signature T::T(const T&)
If Tis a class, it has a public destructor;
If Tis a class, it has a public assignment operator whose signature is either T& T::operator=(const
T&) or T& T::operator=(T)
If Tis 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 default constructor, followed
by assignment, is semantically equivalent to initialization of raw storage using the copy constructor.
275) In other words, value types. These include arithmetic types, pointers, the library class complex, and instantiations of
valarray for value types.
§ 26.2 912
c
ISO/IEC N????
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 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 (23.3.7) instead of valarray
for that class; — end note ]
If Tis a class, it does not overload unary operator&.
2If any operation on Tthrows an exception the effects are undefined.
3In addition, many member and related functions of valarray<T> can be successfully instantiated and will
exhibit well-defined behavior if and only if Tsatisfies additional requirements specified for each such member
or related function.
4[Example: It is valid to instantiate valarray<complex>, but operator>() will not be successfully in-
stantiated for valarray<complex> operands, since complex does not have any ordering operators. — end
example ]
26.3 The floating-point environment [cfenv]
26.3.1 Header <cfenv> synopsis [cfenv.syn]
namespace std {
// types
typedef object type fenv_t;
typedef integer type fexcept_t;
// 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(void);
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);
}
1The header also defines the macros:
FE_ALL_EXCEPT
FE_DIVBYZERO
FE_INEXACT
FE_INVALID
FE_OVERFLOW
§ 26.3.1 913
c
ISO/IEC N????
FE_UNDERFLOW
FE_DOWNWARD
FE_TONEAREST
FE_TOWARDZERO
FE_UPWARD
FE_DFL_ENV
2The header defines all functions, types, and macros the same as Clause 7.6 of the C standard.
3The floating-point environment has thread storage duration (3.7.2). The initial state for a thread’s floating-
point environment is the state of the floating-point environment of the thread that constructs the correspond-
ing std::thread object (30.3.1) 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 ]
4A separate floating-point environment shall be maintained for each thread. Each function accesses the
environment corresponding to its calling thread.
26.4 Complex numbers [complex.numbers]
1The header <complex> defines a class template, and numerous functions for representing and manipulating
complex numbers.
2The 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 (3.9).
3If the result of a function is not mathematically defined or not in the range of representable values for its
type, the behavior is undefined.
4If zis an lvalue expression of type cv std::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 ais an expression of type cv std::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].
26.4.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>;
// 26.4.6, 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>&);
§ 26.4.1 914
c
ISO/IEC N????
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>&);
// 26.4.7, 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);
// 26.4.8, 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>&);
§ 26.4.1 915
c
ISO/IEC N????
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>&);
}
26.4.2 Class template complex [complex]
namespace std {
template<class T>
class complex {
public:
typedef T value_type;
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>&);
};
}
1The class complex describes an object that can store the Cartesian components, real() and imag(), of a
complex number.
26.4.3 complex specializations [complex.special]
namespace std {
template<> class complex<float> {
public:
typedef float value_type;
§ 26.4.3 916
c
ISO/IEC N????
constexpr complex(float re = 0.0f, float im = 0.0f);
explicit constexpr complex(const complex<double>&);
explicit constexpr 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:
typedef double value_type;
constexpr complex(double re = 0.0, double im = 0.0);
constexpr complex(const complex<float>&);
explicit constexpr 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:
typedef long double value_type;
§ 26.4.3 917
c
ISO/IEC N????
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>&);
};
}
26.4.4 complex member functions [complex.members]
template<class T> constexpr complex(const T& re = T(), const T& im = T());
1Effects: Constructs an object of class complex.
2Postcondition: 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.
26.4.5 complex member operators [complex.member.ops]
complex<T>& operator+=(const T& rhs);
1Effects: 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.
2Returns: *this.
§ 26.4.5 918
c
ISO/IEC N????
complex<T>& operator-=(const T& rhs);
3Effects: 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.
4Returns: *this.
complex<T>& operator*=(const T& rhs);
5Effects: Multiplies the scalar value rhs by the complex value *this and stores the result in *this.
6Returns: *this.
complex<T>& operator/=(const T& rhs);
7Effects: Divides the scalar value rhs into the complex value *this and stores the result in *this.
8Returns: *this.
complex<T>& operator+=(const complex<T>& rhs);
9Effects: Adds the complex value rhs to the complex value *this and stores the sum in *this.
10 Returns: *this.
complex<T>& operator-=(const complex<T>& rhs);
11 Effects: Subtracts the complex value rhs from the complex value *this and stores the difference in
*this.
12 Returns: *this.
complex<T>& operator*=(const complex<T>& rhs);
13 Effects: Multiplies the complex value rhs by the complex value *this and stores the product in *this.
Returns: *this.
complex<T>& operator/=(const complex<T>& rhs);
14 Effects: Divides the complex value rhs into the complex value *this and stores the quotient in *this.
15 Returns: *this.
26.4.6 complex non-member operations [complex.ops]
template<class T> complex<T> operator+(const complex<T>& lhs);
1Remarks: unary operator.
2Returns: complex<T>(lhs).
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);
§ 26.4.6 919
c
ISO/IEC N????
3Returns: complex<T>(lhs) += rhs.
template<class T> complex<T> operator-(const complex<T>& lhs);
4Remarks: unary operator.
5Returns: complex<T>(-lhs.real(),-lhs.imag()).
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);
6Returns: 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);
7Returns: 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);
8Returns: complex<T>(lhs) /= rhs.
template<class T>
bool constexpr 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);
9Returns: lhs.real() == rhs.real() && lhs.imag() == rhs.imag().
10 Remarks: The imaginary part is assumed to be T(), or 0.0, for the Targuments.
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);
11 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);
§ 26.4.6 920
c
ISO/IEC N????
12 Effects: Extracts a complex number xof the form: u,(u), or (u,v), where uis the real part and vis
the imaginary part (27.7.2.2).
13 Requires: The input values shall be convertible to T.
If bad input is encountered, calls is.setstate(ios_base::failbit) (which may throw ios::failure
(27.5.5.4)).
14 Returns: is.
15 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);
16 Effects: inserts the complex number xonto the stream oas if it were implemented as follows:
template<class T, class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& o, const complex<T>& x) {
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();
}
17 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 std::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.
26.4.7 complex value operations [complex.value.ops]
template<class T> constexpr T real(const complex<T>& x);
1Returns: x.real().
template<class T> constexpr T imag(const complex<T>& x);
2Returns: x.imag().
template<class T> T abs(const complex<T>& x);
3Returns: The magnitude of x.
template<class T> T arg(const complex<T>& x);
4Returns: The phase angle of x, or atan2(imag(x), real(x)).
template<class T> T norm(const complex<T>& x);
§ 26.4.7 921
c
ISO/IEC N????
5Returns: The squared magnitude of x.
template<class T> complex<T> conj(const complex<T>& x);
6Returns: The complex conjugate of x.
template<class T> complex<T> proj(const complex<T>& x);
7Returns: The projection of xonto the Riemann sphere.
8Remarks: 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);
9Returns: The complex value corresponding to a complex number whose magnitude is rho and whose
phase angle is theta.
26.4.8 complex transcendentals [complex.transcendentals]
template<class T> complex<T> acos(const complex<T>& x);
1Returns: The complex arc cosine of x.
2Remarks: Behaves the same as C function cacos, defined in 7.3.5.1.
template<class T> complex<T> asin(const complex<T>& x);
3Returns: The complex arc sine of x.
4Remarks: Behaves the same as C function casin, defined in 7.3.5.2.
template<class T> complex<T> atan(const complex<T>& x);
5Returns: The complex arc tangent of x.
6Remarks: Behaves the same as C function catan, defined in 7.3.5.3.
template<class T> complex<T> acosh(const complex<T>& x);
7Returns: The complex arc hyperbolic cosine of x.
8Remarks: Behaves the same as C function cacosh, defined in 7.3.6.1.
template<class T> complex<T> asinh(const complex<T>& x);
9Returns: The complex arc hyperbolic sine of x.
10 Remarks: Behaves the same as C function casinh, defined in 7.3.6.2.
template<class T> complex<T> atanh(const complex<T>& x);
11 Returns: The complex arc hyperbolic tangent of x.
12 Remarks: Behaves the same as C function catanh, defined in 7.3.6.3.
§ 26.4.8 922
c
ISO/IEC N????
template<class T> complex<T> cos(const complex<T>& x);
13 Returns: The complex cosine of x.
template<class T> complex<T> cosh(const complex<T>& x);
14 Returns: The complex hyperbolic cosine of x.
template<class T> complex<T> exp(const complex<T>& x);
15 Returns: The complex base e exponential of x.
template<class T> complex<T> log(const complex<T>& x);
16 Remarks: the branch cuts are along the negative real axis.
17 Returns: The complex natural (base e) logarithm of x, in the range of a strip mathematically un-
bounded along the real axis and in the interval [-i times pi,i times pi] along the imaginary axis.
When xis a negative real number, imag(log(x)) is pi.
template<class T> complex<T> log10(const complex<T>& x);
18 Remarks: the branch cuts are along the negative real axis.
19 Returns: The complex common (base 10) logarithm of x, defined as log(x)/log(10).
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);
20 Remarks: the branch cuts are along the negative real axis.
21 Returns: The complex power of base xraised to the y-th power, defined as exp(y*log(x)). The value
returned for pow(0,0) is implementation-defined.
template<class T> complex<T> sin (const complex<T>& x);
22 Returns: The complex sine of x.
template<class T> complex<T> sinh (const complex<T>& x);
23 Returns: The complex hyperbolic sine of x.
template<class T> complex<T> sqrt (const complex<T>& x);
24 Remarks: the branch cuts are along the negative real axis.
25 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.
§ 26.4.8 923
c
ISO/IEC N????
template<class T> complex<T> tan (const complex<T>& x);
26 Returns: The complex tangent of x.
template<class T> complex<T> tanh (const complex<T>& x);
27 Returns: The complex hyperbolic tangent of x.
26.4.9 Additional overloads [cmplx.over]
1The following function templates shall have additional overloads:
arg norm
conj proj
imag real
2The additional overloads shall be sufficient to ensure:
1. If the argument has type long double, then it is effectively cast to complex<long double>.
2. Otherwise, if the argument has type double or an integer type, then it is effectively cast to complex<
double>.
3. Otherwise, if the argument has type float, then it is effectively cast to complex<float>.
3Function template pow shall have additional overloads sufficient to ensure, for a call with at least one
argument of type complex<T>:
1. If either argument has type complex<long double> or type long double, then both arguments are
effectively cast to complex<long double>.
2. Otherwise, if either argument has type complex<double>,double, or an integer type, then both
arguments are effectively cast to complex<double>.
3. Otherwise, if either argument has type complex<float> or float, then both arguments are effectively
cast to complex<float>.
26.4.10 Header <ccomplex> [ccmplx]
1The header behaves as if it simply includes the header <complex>.
26.5 Random number generation [rand]
1This subclause defines a facility for generating (pseudo-)random numbers.
2In addition to a few utilities, four categories of entities are described: uniform random number generators,
random number engines,random number engine adaptors, and random number distributions. These catego-
rizations 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 number generator object eas 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 ]
3Each of the entities specified via this subclause has an associated arithmetic type (3.9.1) identified as
result_type. With Tas the result_type thus associated with such an entity, that entity is character-
ized:
a) as boolean or equivalently as boolean-valued, if Tis bool;
b) otherwise as integral or equivalently as integer-valued, if numeric_limits<T>::is_integer is true;
§ 26.5 924
c
ISO/IEC N????
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
numeric_limits<T>::is_signed.
4Unless otherwise specified, all descriptions of calculations in this subclause use mathematical real numbers.
5Throughout this subclause, the operators bitand ,bitor , and xor denote the respective conventional bitwise
operations. Further:
a) the operator rshift denotes a bitwise right shift with zero-valued bits appearing in the high bits of the
result, and
b) the operator lshiftwdenotes a bitwise left shift with zero-valued bits appearing in the low bits of the
result, and whose result is always taken modulo 2w.
26.5.1 Requirements [rand.req]
26.5.1.1 General requirements [rand.req.genl]
1Throughout this subclause 26.5, the effect of instantiating a template:
a) that has a template type parameter named Sseq is undefined unless the corresponding template argu-
ment is cv-unqualified and satisfies the requirements of seed sequence (26.5.1.2).
b) that has a template type parameter named URNG is undefined unless the corresponding template argu-
ment is cv-unqualified and satisfies the requirements of uniform random number generator (26.5.1.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 (26.5.1.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.
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.
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.
2Throughout this subclause 26.5, phrases of the form “xis an iterator of a specific kind” shall be interpreted
as equivalent to the more formal requirement that “xis a value of a type satisfying the requirements of the
specified iterator type.
3Throughout this subclause 26.5, any constructor that can be called with a single argument and that satisfies
a requirement specified in this subclause shall be declared explicit.
26.5.1.2 Seed sequence requirements [rand.req.seedseq]
1Aseed sequence is an object that consumes a sequence of integer-valued data and produces a requested
number of unsigned integer values i,0i < 232, 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 ]
2A class Ssatisfies the requirements of a seed sequence if the expressions shown in Table 115 are valid and
have the indicated semantics, and if Salso satisfies all other requirements of this section 26.5.1.2. In that
Table and throughout this section:
a) Tis the type named by S’s associated result_type;
b) qis a value of Sand ris a possibly const value of S;
§ 26.5.1.2 925
c
ISO/IEC N????
c) ib and ie are input iterators with an unsigned integer value_type of at least 32 bits;
d) rb and re are mutable random access iterators with an unsigned integer value_type of at least 32
bits;
e) ob is an output iterator; and
f) il is a value of initializer_list<T>.
Table 115 — Seed sequence requirements
Expression Return type Pre/post-condition Complexity
S::result_type T T is an unsigned integer
type (3.9.1) 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 [ib,ie).
O(ie ib)
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 [rb,re)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.
O(re rb)
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.
O(r.size())
26.5.1.3 Uniform random number generator requirements [rand.req.urng]
1Auniform random number generator gof type Gis 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 ]
§ 26.5.1.3 926
c
ISO/IEC N????
2A class Gsatisfies the requirements of a uniform random number generator if the expressions shown in
Table 116 are valid and have the indicated semantics, and if Galso satisfies all other requirements of this
section 26.5.1.3. In that Table and throughout this section:
a) Tis the type named by G’s associated result_type, and
b) gis a value of G.
Table 116 — Uniform random number generator requirements
Expression Return type Pre/post-condition Complexity
G::result_type T T is an unsigned integer
type (3.9.1).
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
3The following relation shall hold: G::min() < G::max().
26.5.1.4 Random number engine requirements [rand.req.eng]
1Arandom number engine (commonly shortened to engine)eof type Eis a uniform random number generator
that additionally meets the requirements (e.g., for seeding and for input/output) specified in this section.
2At any given time, ehas a state eifor some integer i0. Upon construction, ehas an initial state e0. An
engine’s state may be established via a constructor, a seed function, assignment, or a suitable operator>>.
3E’s specification shall define:
a) the size of E’s state in multiples of the size of result_type, given as an integral constant expression;
b) the transition algorithm TA by which e’s state eiis advanced to its successor state ei+1; and
c) the generation algorithm GA by which an engine’s state is mapped to a value of type result_type.
4A class Ethat satisfies the requirements of a uniform random number generator (26.5.1.3) also satisfies
the requirements of a random number engine if the expressions shown in Table 117 are valid and have the
indicated semantics, and if Ealso satisfies all other requirements of this section 26.5.1.4. In that Table and
throughout this section:
a) Tis the type named by E’s associated result_type;
b) eis a value of E,vis an lvalue of E,xand yare (possibly const) values of E;
c) sis a value of T;
d) qis an lvalue satisfying the requirements of a seed sequence (26.5.1.2);
e) zis a value of type unsigned long long;
f) os is an lvalue of the type of some class template specialization basic_ostream<charT, traits>; and
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 21 and Clause 27.
§ 26.5.1.4 927
c
ISO/IEC N????
Table 117 — 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.
O(size of state)
E(x) Creates an engine that
compares equal to x.
O(size of state)
E(s) Creates an engine with initial
state determined by s.
O(size of state)
E(q)276 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 post: e == E(). same as E()
e.seed(s) void post: e == E(s). same as E(s)
e.seed(q) void post: e == E(q). same as E(q)
e() T Advances e’s state eito ei+1
=TA(ei)and returns GA(ei).
per Table 116
e.discard(z) 277 void Advances e’s state eito ei+zby
any means equivalent to z
consecutive calls e().
no worse than
the complexity
of zconsecutive
calls e()
x == y bool This operator is an equivalence
relation. With Sxand Syas the
infinite sequences of values that
would be generated by repeated
future calls to x() and y(),
respectively, returns true if
Sx=Sy; else returns false.
O(size of state)
x != y bool !(x == y).O(size of state)
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.
post: The os.fmtflags and fill
character are unchanged.
O(size of state)
276) This constructor (as well as the subsequent corresponding seed() function) may be particularly useful to applications
requiring a large number of independent random sequences.
277) 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 zconsecutive calls e().
§ 26.5.1.4 928
c
ISO/IEC N????
Expression Return type Pre/post-condition Complexity
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 [27.5.5.4]). 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.
pre: 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.
post: The is.fmtflags are
unchanged.
O(size of state)
5Eshall meet the requirements of CopyConstructible (Table 21) and CopyAssignable (Table 23) types.
These operations shall each be of complexity no worse than O(size of state).
26.5.1.5 Random number engine adaptor requirements [rand.req.adapt]
1Arandom number engine adaptor (commonly shortened to adaptor)aof type Ais 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 bof type Badapted
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.
2The requirements of a random number engine type shall be interpreted as follows with respect to a random
number engine adaptor type.
A::A();
3Effects: The base engine is initialized as if by its default constructor.
bool operator==(const A& a1, const A& a2);
4Returns: true if a1’s base engine is equal to a2’s base engine. Otherwise returns false.
A::A(result_type s);
§ 26.5.1.5 929
c
ISO/IEC N????
5Effects: The base engine is initialized with s.
template<class Sseq> void A::A(Sseq& q);
6Effects: The base engine is initialized with q.
void seed();
7Effects: With bas the base engine, invokes b.seed().
void seed(result_type s);
8Effects: With bas the base engine, invokes b.seed(s).
template<class Sseq> void seed(Sseq& q);
9Effects: With bas the base engine, invokes b.seed(q).
10 Ashall also satisfy the following additional requirements:
a) The complexity of each function shall not exceed the complexity of the corresponding function applied
to the base engine.
b) The state of Ashall include the state of its base engine. The size of A’s state shall be no less than the
size of the base engine.
c) Copying A’s state (e.g., during copy construction or copy assignment) shall include copying the state
of the base engine of A.
d) The textual representation of Ashall include the textual representation of its base engine.
26.5.1.6 Random number distribution requirements [rand.req.dist]
1Arandom number distribution (commonly shortened to distribution)dof type Dis 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 P(zi). A distribution’s specification identifies its
associated probability function p(z)or P(zi).
2An 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, p(z|a, b)or P(zi|a, b), to name specific parameters, or by writing, for example, p(z|{p})or
P(zi|{p}), to denote a distribution’s parameters ptaken as a whole.
3A class Dsatisfies the requirements of a random number distribution if the expressions shown in Table 118 are
valid and have the indicated semantics, and if Dand its associated types also satisfy all other requirements
of this section 26.5.1.6. In that Table and throughout this section,
a) Tis the type named by D’s associated result_type;
b) Pis the type named by D’s associated param_type;
c) dis a value of D, and xand yare (possibly const) values of D;
d) glb and lub are values of Trespectively 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;
§ 26.5.1.6 930
c
ISO/IEC N????
e) pis a (possibly const) value of P;
f) g,g1, and g2 are lvalues of a type satisfying the requirements of a uniform random number generator
[26.5.1.3];
g) os is an lvalue of the type of some class template specialization basic_ostream<charT, traits>; and
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 21 and 27.
Table 118 — Random number distribution requirements
Expression Return type Pre/post-condition Complexity
D::result_type T T is an arithmetic type (3.9.1). 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 ddo not
depend on values produced by
any engine prior to invoking
reset.
constant
x.param() P Returns a value psuch that
D(p).param() == p.
no worse than
the complexity
of D(p)
d.param(p) void post: d.param() == p. no worse than
the complexity
of D(p)
d(g) T With p=d.param(), the
sequence of numbers returned
by successive invocations with
the same object gis randomly
distributed according to the
associated p(z|{p})or
P(zi|{p})function.
amortized
constant
number of
invocations of g
d(g,p) T The sequence of numbers
returned by successive
invocations with the same
objects gand pis randomly
distributed according to the
associated p(z|{p})or
P(zi|{p})function.
amortized
constant
number of
invocations of g
x.min() T Returns glb. constant
x.max() T Returns lub. constant
§ 26.5.1.6 931
c
ISO/IEC N????
Expression Return type Pre/post-condition Complexity
x == y bool This operator is an equivalence
relation. Returns true if
x.param() == y.param() and
S1=S2, where S1and S2are
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.
post: 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 dis unchanged by
the operation and calls
is.setstate(ios::failbit)
(which may throw
ios::failure [27.5.5.4]).
pre: 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.
post: The is.fmtflags are
unchanged.
4Dshall satisfy the requirements of CopyConstructible (Table 21) and CopyAssignable (Table 23) types.
5The 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 Dbetween any of the invocations d(g).
6If a textual representation is written using os << x and that representation is restored into the same or
a different object yof 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).
7It is unspecified whether D::param_type is declared as a (nested) class or via a typedef. In this subclause
26.5, declarations of D::param_type are in the form of typedefs for convenience of exposition only.
8Pshall satisfy the requirements of CopyConstructible (Table 21), CopyAssignable (Table 23), and EqualityComparable
(Table 17) types.
9For each of the constructors of Dtaking arguments corresponding to parameters of the distribution, P
shall have a corresponding constructor subject to the same requirements and taking arguments identical
§ 26.5.1.6 932
c
ISO/IEC N????
in number, type, and default values. Moreover, for each of the member functions of Dthat return values
corresponding to parameters of the distribution, Pshall have a corresponding member function with the
identical name, type, and semantics.
10 Pshall have a declaration of the form
typedef D distribution_type;
26.5.2 Header <random> synopsis [rand.synopsis]
#include <initializer_list>
namespace std {
// 26.5.3.1, class template linear_congruential_engine
template<class UIntType, UIntType a, UIntType c, UIntType m>
class linear_congruential_engine;
// 26.5.3.2, 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;
// 26.5.3.3, class template subtract_with_carry_engine
template<class UIntType, size_t w, size_t s, size_t r>
class subtract_with_carry_engine;
// 26.5.4.2, class template discard_block_engine
template<class Engine, size_t p, size_t r>
class discard_block_engine;
// 26.5.4.3, class template independent_bits_engine
template<class Engine, size_t w, class UIntType>
class independent_bits_engine;
// 26.5.4.4, class template shuffle_order_engine
template<class Engine, size_t k>
class shuffle_order_engine;
// 26.5.5, engines and engine adaptors with predefined parameters
typedef see below minstd_rand0;
typedef see below minstd_rand;
typedef see below mt19937;
typedef see below mt19937_64;
typedef see below ranlux24_base;
typedef see below ranlux48_base;
typedef see below ranlux24;
typedef see below ranlux48;
typedef see below knuth_b;
typedef see below default_random_engine;
// 26.5.6, class random_device
class random_device;
§ 26.5.2 933
c
ISO/IEC N????
// 26.5.7.1, class seed_seq
class seed_seq;
// 26.5.7.2, function template generate_canonical
template<class RealType, size_t bits, class URNG>
RealType generate_canonical(URNG& g);
// 26.5.8.2.1, class template uniform_int_distribution
template<class IntType = int>
class uniform_int_distribution;
// 26.5.8.2.2, class template uniform_real_distribution
template<class RealType = double>
class uniform_real_distribution;
// 26.5.8.3.1, class bernoulli_distribution
class bernoulli_distribution;
// 26.5.8.3.2, class template binomial_distribution
template<class IntType = int>
class binomial_distribution;
// 26.5.8.3.3, class template geometric_distribution
template<class IntType = int>
class geometric_distribution;
// 26.5.8.3.4, class template negative_binomial_distribution
template<class IntType = int>
class negative_binomial_distribution;
// 26.5.8.4.1, class template poisson_distribution
template<class IntType = int>
class poisson_distribution;
// 26.5.8.4.2, class template exponential_distribution
template<class RealType = double>
class exponential_distribution;
// 26.5.8.4.3, class template gamma_distribution
template<class RealType = double>
class gamma_distribution;
// 26.5.8.4.4, class template weibull_distribution
template<class RealType = double>
class weibull_distribution;
// 26.5.8.4.5, class template extreme_value_distribution
template<class RealType = double>
class extreme_value_distribution;
// 26.5.8.5.1, class template normal_distribution
template<class RealType = double>
class normal_distribution;
// 26.5.8.5.2, class template lognormal_distribution
§ 26.5.2 934
c
ISO/IEC N????
template<class RealType = double>
class lognormal_distribution;
// 26.5.8.5.3, class template chi_squared_distribution
template<class RealType = double>
class chi_squared_distribution;
// 26.5.8.5.4, class template cauchy_distribution
template<class RealType = double>
class cauchy_distribution;
// 26.5.8.5.5, class template fisher_f_distribution
template<class RealType = double>
class fisher_f_distribution;
// 26.5.8.5.6, class template student_t_distribution
template<class RealType = double>
class student_t_distribution;
// 26.5.8.6.1, class template discrete_distribution
template<class IntType = int>
class discrete_distribution;
// 26.5.8.6.2, class template piecewise_constant_distribution
template<class RealType = double>
class piecewise_constant_distribution;
// 26.5.8.6.3, class template piecewise_linear_distribution
template<class RealType = double>
class piecewise_linear_distribution;
}// namespace std
26.5.3 Random number engine class templates [rand.eng]
1Each type instantiated from a class template specified in this section 26.5.3 satisfies the requirements of a
random number engine (26.5.1.4) type.
2Except where specified otherwise, the complexity of each function specified in this section 26.5.3 is constant.
3Except where specified otherwise, no function described in this section 26.5.3 throws an exception.
4Descriptions are provided in this section 26.5.3 only for engine operations that are not described in 26.5.1.4
or for operations where there is additional semantic information. In particular, declarations for copy con-
structors, for copy assignment operators, for streaming operators, and for equality and inequality operators
are not shown in the synopses.
5Each template specified in this section 26.5.3 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.
6For every random number engine and for every random number engine adaptor Xdefined in this sub-
clause (26.5.3) and in sub-clause 26.5.4:
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
§ 26.5.3 935
c
ISO/IEC N????
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.
26.5.3.1 Class template linear_congruential_engine [rand.eng.lcong]
1Alinear_congruential_engine random number engine produces unsigned integer random numbers. The
state xiof a linear_congruential_engine object xis of size 1and consists of a single integer. The
transition algorithm is a modular linear function of the form TA(xi)=(a·xi+c) mod m; the generation
algorithm is GA(xi) = xi+1.
template<class UIntType, UIntType a, UIntType c, UIntType m>
class linear_congruential_engine
{
public:
// types
typedef UIntType result_type;
// 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);
};
2If the template parameter mis 0, the modulus mused throughout this section 26.5.3.1 is numeric_-
limits<result_type>::max() plus 1. [ Note: mneed not be representable as a value of type result_type.
— end note ]
3If the template parameter mis not 0, the following relations shall hold: a<mand c<m.
4The textual representation consists of the value of xi.
explicit linear_congruential_engine(result_type s = default_seed);
5Effects: Constructs a linear_congruential_engine object. If cmod mis 0and smod mis 0, sets
the engine’s state to 1, otherwise sets the engine’s state to smod m.
template<class Sseq> explicit linear_congruential_engine(Sseq& q);
§ 26.5.3.1 936
c
ISO/IEC N????
6Effects: Constructs a linear_congruential_engine object. With k=llog2m
32 mand aan array
(or equivalent) of length k+ 3, invokes q.generate(a+ 0,a+k+ 3)and then computes S=
Pk1
j=0 aj+3 ·232jmod m. If cmod mis 0and Sis 0, sets the engine’s state to 1, else sets the
engine’s state to S.
26.5.3.2 Class template mersenne_twister_engine [rand.eng.mers]
1Amersenne_twister_engine random number engine278 produces unsigned integer random numbers in the
closed interval [0,2w1]. The state xiof a mersenne_twister_engine object xis of size nand consists of
a sequence Xof nvalues of the type delivered by x; all subscripts applied to Xare to be taken modulo n.
2The transition algorithm employs a twisted generalized feedback shift register defined by shift values nand
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 u, d, s, b, t, c, and `.
The state transition is performed as follows:
a) Concatenate the upper wrbits of Xinwith the lower rbits of Xi+1nto obtain an unsigned integer
value Y.
b) With α=a·(Ybitand 1), set Xito Xi+mnxor (Yrshift 1) xor α.
The sequence Xis initialized with the help of an initialization multiplier f.
3The generation algorithm determines the unsigned integer values z1, z2, z3, z4as follows, then delivers z4as
its result:
a) Let z1=Xixor (Xirshift u)bitand d.
b) Let z2=z1xor (z1lshiftws)bitand b.
c) Let z3=z2xor (z2lshiftwt)bitand c.
d) Let z4=z3xor (z3rshift `).
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
typedef UIntType result_type;
// 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;
278) 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.
§ 26.5.3.2 937
c
ISO/IEC N????
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 2w1; }
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);
};
4The 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.
5The textual representation of xiconsists of the values of Xin, . . . , Xi1, in that order.
explicit mersenne_twister_engine(result_type value = default_seed);
6Effects: Constructs a mersenne_twister_engine object. Sets Xnto value mod 2w. Then, itera-
tively for i= 1n, . . . , 1, sets Xito
f·Xi1xor Xi1rshift (w2)+imod nmod 2w.
7Complexity: O(n).
template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
8Effects: Constructs a mersenne_twister_engine object. With k=dw/32eand aan array (or equiv-
alent) of length n·k, invokes q.generate(a+ 0,a+n·k)and then, iteratively for i=n, . . . , 1,
sets Xito Pk1
j=0 ak(i+n)+j·232jmod 2w. Finally, if the most significant wrbits of Xnare zero,
and if each of the other resulting Xiis 0, changes Xnto 2w1.
26.5.3.3 Class template subtract_with_carry_engine [rand.eng.sub]
1Asubtract_with_carry_engine random number engine produces unsigned integer random numbers.
2The state xiof a subtract_with_carry_engine object xis of size O(r), and consists of a sequence Xof
rinteger values 0Xi< m = 2w; all subscripts applied to Xare to be taken modulo r. The state xi
additionally consists of an integer c(known as the carry) whose value is either 0or 1.
3The state transition is performed as follows:
a) Let Y=XisXirc.
b) Set Xito y=Ymod m. Set cto 1 if Y < 0, otherwise set cto 0.
[Note: This algorithm corresponds to a modular linear function of the form TA(xi)=(a·xi) mod b, where
bis of the form mrms+ 1 and a=b(b1)/m.— end note ]
4The generation algorithm is given by GA(xi) = y, where yis the value produced as a result of advancing the
engine’s state as described above.
§ 26.5.3.3 938
c
ISO/IEC N????
template<class UIntType, size_t w, size_t s, size_t r>
class subtract_with_carry_engine
{
public:
// types
typedef UIntType result_type;
// 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 m1; }
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);
};
5The following relations shall hold: 0u < s,s<r,0<w, and w <= numeric_limits<UIntType>::digits.
6The textual representation consists of the values of Xir, . . . , Xi1, in that order, followed by c.
explicit subtract_with_carry_engine(result_type value = default_seed);
7Effects: Constructs a subtract_with_carry_engine object. Sets the values of Xr, . . . , X1, in that
order, as specified below. If X1is then 0, sets cto 1; otherwise sets cto 0.
To set the values Xk, 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 Xk, obtain new values z0, . . . , zn1from n=dw/32esuccessive invocations of e
taken modulo 232. Set Xkto Pn1
j=0 zj·232jmod m.
8Complexity: Exactly n·rinvocations of e.
template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
9Effects: Constructs a subtract_with_carry_engine object. With k=dw/32eand aan array (or
equivalent) of length r·k, invokes q.generate(a+0,a+r·k)and then, iteratively for i=r, . . . , 1,
sets Xito Pk1
j=0 ak(i+r)+j·232jmod m. If X1is then 0, sets cto 1; otherwise sets cto 0.
26.5.4 Random number engine adaptor class templates [rand.adapt]
26.5.4.1 In general [rand.adapt.general]
1Each type instantiated from a class template specified in this section 26.5.3 satisfies the requirements of a
random number engine adaptor (26.5.1.5) type.
§ 26.5.4.1 939
c
ISO/IEC N????
2Except where specified otherwise, the complexity of each function specified in this section 26.5.4 is constant.
3Except where specified otherwise, no function described in this section 26.5.4 throws an exception.
4Descriptions are provided in this section 26.5.4 only for adaptor operations that are not described in sec-
tion 26.5.1.5 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.
5Each template specified in this section 26.5.4 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.
26.5.4.2 Class template discard_block_engine [rand.adapt.disc]
1Adiscard_block_engine random number engine adaptor produces random numbers selected from those
produced by some base engine e. The state xiof a discard_block_engine engine adaptor object xconsists
of the state eiof its base engine eand an additional integer n. The size of the state is the size of e’s state
plus 1.
2The transition algorithm discards all but r > 0values from each block of prvalues delivered by e. The
state transition is performed as follows: If nr, advance the state of efrom eito ei+prand set nto 0.
In any case, then increment nand advance e’s then-current state ejto ej+1.
3The 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
typedef typename Engine::result_type 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
};
§ 26.5.4.2 940
c
ISO/IEC N????
4The following relations shall hold: 0<rand r <= p.
5The textual representation consists of the textual representation of efollowed by the value of n.
6In addition to its behavior pursuant to section 26.5.1.5, each constructor that is not a copy constructor sets
nto 0.
26.5.4.3 Class template independent_bits_engine [rand.adapt.ibits]
1An 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 xiof
an independent_bits_engine engine adaptor object xconsists of the state eiof its base engine e; the size
of the state is the size of e’s state.
2The transition and generation algorithms are described in terms of the following integral constants:
a) Let R=e.max() - e.min() + 1 and m=blog2Rc.
b) With nas determined below, let w0=bw/nc,n0=nwmod n,y0= 2w0bR/2w0c, and y1=
2w0+1 R/2w0+1.
c) Let n=dw/meif and only if the relation Ry0≤ by0/ncholds as a result. Otherwise let n=
1 + dw/me.
[Note: The relation w=n0w0+ (nn0)(w0+ 1) always holds. — end note ]
3The transition algorithm is carried out by invoking e() as often as needed to obtain n0values less than y0
+e.min() and nn0values less than y1+e.min().
4The generation algorithm uses the values produced while advancing the state as described above to yield a
quantity Sobtained as if by the following algorithm:
S= 0;
for (k=0;k6=n0;k+= 1) {
do u= e() - e.min(); while (uy0);
S=2w0·S+umod 2w0;
}
for (k=n0;k6=n;k+= 1) {
do u= e() - e.min(); while (uy1);
S=2w0+1 ·S+umod 2w0+1;
}
template<class Engine, size_t w, class UIntType>
class independent_bits_engine
{
public:
// types
typedef UIntType result_type;
// engine characteristics
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 2w1; }
// 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);
§ 26.5.4.3 941
c
ISO/IEC N????
// 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
};
5The following relations shall hold: 0<wand w <= numeric_limits<result_type>::digits.
6The textual representation consists of the textual representation of e.
26.5.4.4 Class template shuffle_order_engine [rand.adapt.shuf]
1Ashuffle_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 xiof a shuffle_-
order_engine engine adaptor object xconsists of the state eiof its base engine e, an additional value Yof
the type delivered by e, and an additional sequence Vof kvalues also of the type delivered by e. The size
of the state is the size of e’s state plus k+ 1.
2The transition algorithm permutes the values produced by e. The state transition is performed as follows:
a) Calculate an integer j=jk·(Yemin )
emax emin +1 k.
b) Set Yto Vjand then set Vjto e().
3The generation algorithm yields the last value of Yproduced while advancing e’s state as described above.
template<class Engine, size_t k>
class shuffle_order_engine
{
public:
// types
typedef typename Engine::result_type 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; };
§ 26.5.4.4 942
c
ISO/IEC N????
private:
Engine e; // exposition only
result_type Y; // exposition only
result_type V[k]; // exposition only
};
4The following relation shall hold: 0<k.
5The textual representation consists of the textual representation of e, followed by the kvalues of V, followed
by the value of Y.
6In addition to its behavior pursuant to section 26.5.1.5, each constructor that is not a copy constructor
initializes V[0],...,V[k-1] and Y, in that order, with values returned by successive invocations of e().
26.5.5 Engines and engine adaptors with predefined parameters [rand.predef]
typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
minstd_rand0;
1Required behavior: The 10000 th consecutive invocation of a default-constructed object of type minstd_-
rand0 shall produce the value 1043618065.
typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>
minstd_rand;
2Required behavior: The 10000 th consecutive invocation of a default-constructed object of type minstd_-
rand shall produce the value 399268537.
typedef mersenne_twister_engine<uint_fast32_t,
32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>
mt19937;
3Required behavior: The 10000 th consecutive invocation of a default-constructed object of type mt19937
shall produce the value 4123659995.
typedef mersenne_twister_engine<uint_fast64_t,
64,312,156,31,0xb5026f5aa96619e9,29,
0x5555555555555555,17,
0x71d67fffeda60000,37,
0xfff7eee000000000,43,
6364136223846793005>
mt19937_64;
4Required behavior: The 10000 th consecutive invocation of a default-constructed object of type mt19937_-
64 shall produce the value 9981545732273789042.
typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
ranlux24_base;
5Required behavior: The 10000 th consecutive invocation of a default-constructed object of type ranlux24_-
base shall produce the value 7937952.
typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
ranlux48_base;
§ 26.5.5 943
c
ISO/IEC N????
6Required behavior: The 10000 th consecutive invocation of a default-constructed object of type ranlux48_-
base shall produce the value 61839128582725.
typedef discard_block_engine<ranlux24_base, 223, 23>
ranlux24;
7Required behavior: The 10000 th consecutive invocation of a default-constructed object of type ranlux24
shall produce the value 9901578.
typedef discard_block_engine<ranlux48_base, 389, 11>
ranlux48;
8Required behavior: The 10000 th consecutive invocation of a default-constructed object of type ranlux48
shall produce the value 249142670248501.
typedef shuffle_order_engine<minstd_rand0,256>
knuth_b;
9Required behavior: The 10000 th consecutive invocation of a default-constructed object of type knuth_b
shall produce the value 1112339016.
typedef implementation-defined
default_random_engine;
10 Remark: 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 ]
26.5.6 Class random_device [rand.device]
1Arandom_device uniform random number generator produces non-deterministic random numbers.
2If implementation limitations prevent generating non-deterministic random numbers, the implementation
may employ a random number engine.
class random_device
{
public:
// types
typedef unsigned int result_type;
// 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()();
§ 26.5.6 944
c
ISO/IEC N????
// 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 );
3Effects: Constructs a random_device non-deterministic uniform random number generator object.
The semantics and default value of the token parameter are implementation-defined.279
4Throws: A value of an implementation-defined type derived from exception if the random_device
could not be initialized.
double entropy() const noexcept;
5Returns: If the implementation employs a random number engine, returns 0.0. Otherwise, returns
an entropy estimate280 for the random numbers returned by operator(), in the range min() to
log2(max() + 1).
result_type operator()();
6Returns: A non-deterministic random value, uniformly distributed between min() and max(), inclusive.
It is implementation-defined how these values are generated.
7Throws: A value of an implementation-defined type derived from exception if a random number could
not be obtained.
26.5.7 Utilities [rand.util]
26.5.7.1 Class seed_seq [rand.util.seedseq]
1No function described in this section 26.5.7.1 throws an exception.
class seed_seq
{
public:
// types
typedef uint_least32_t result_type;
// 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);
279) The parameter is intended to allow an implementation to differentiate between different sources of randomness.
280) If a device has nstates whose respective probabilities are P0,...,Pn1, the device entropy Sis defined as
S=Pn1
i=0 Pi·log Pi.
§ 26.5.7.1 945
c
ISO/IEC N????
// property functions
size_t size() const;
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();
2Effects: Constructs a seed_seq object as if by default-constructing its member v.
template<class T>
seed_seq(initializer_list<T> il);
3Requires: Tshall be an integer type.
4Effects: Same as seed_seq(il.begin(), il.end()).
template<class InputIterator>
seed_seq(InputIterator begin, InputIterator end);
5Requires: InputIterator shall satisfy the requirements of an input iterator (Table 107) type. More-
over, iterator_traits<InputIterator>::value_type shall denote an integer type.
6Effects: Constructs a seed_seq object by the following algorithm:
for( InputIterator s = begin; s != end; ++s)
v.push_back((*s)mod232);
template<class RandomAccessIterator>
void generate(RandomAccessIterator begin, RandomAccessIterator end);
7Requires: RandomAccessIterator shall meet the requirements of a mutable random access iterator
(Table 111) type. Moreover, iterator_traits<RandomAccessIterator>::value_type shall denote
an unsigned integer type capable of accommodating 32-bit quantities.
8Effects: Does nothing if begin == end. Otherwise, with s=v.size() and n=end begin, fills
the supplied range [begin,end)according to the following algorithm in which each operation is to be
carried out modulo 232, each indexing operator applied to begin is to be taken modulo n, and T(x)is
defined as xxor (xrshift 27):
a) By way of initialization, set each element of the range to the value 0x8b8b8b8b. Additionally, for
use in subsequent steps, let p= (nt)/2and let q=p+t, where
t= (n623) ?11 :(n68) ?7:(n39) ?5:(n7) ?3:(n1)/2;
§ 26.5.7.1 946
c
ISO/IEC N????
b) With mas the larger of s+ 1 and n, transform the elements of the range: iteratively for k=
0, . . . , m 1, calculate values
r1= 1664525 ·T(begin[k]xor begin[k+p]xor begin[k1])
r2=r1+
s,k= 0
kmod n+v[k1],0< k s
kmod n,s<k
and, in order, increment begin[k+p]by r1, increment begin[k+q]by r2, and set begin[k]
to r2.
c) Transform the elements of the range again, beginning where the previous step ended: iteratively
for k=m, . . . , m+n1, calculate values
r3= 1566083941 ·T(begin[k]+begin[k+p]+begin[k1])
r4=r3(kmod n)
and, in order, update begin[k+p]by xoring it with r3, update begin[k+q]by xoring it with
r4, and set begin[k]to r4.
size_t size() const;
9Returns: The number of 32-bit units that would be returned by a call to param().
10 Complexity: constant time.
template<class OutputIterator>
void param(OutputIterator dest) const;
11 Requires: OutputIterator shall satisfy the requirements of an output iterator (Table 108) type. More-
over, the expression *dest = rt shall be valid for a value rt of type result_type.
12 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);
26.5.7.2 Function template generate_canonical [rand.util.canonical]
1Each function instantiated from the template described in this section 26.5.7.2 maps the result of one or
more invocations of a supplied uniform random number generator gto one member of the specified RealType
such that, if the values giproduced by gare uniformly distributed, the instantiation’s results tj,0tj<1,
are distributed as uniformly as possible as specified below.
2[Note: Obtaining a value in this way can be a useful step in the process of transforming a value generated
by a uniform random number generator into a value that can be delivered by a random number distribution.
— end note ]
template<class RealType, size_t bits, class URNG>
RealType generate_canonical(URNG& g);
3Complexity: Exactly k= max(1,db/ log2Re)invocations of g, where b281 is the lesser of numeric_-
limits<RealType>::digits and bits, and Ris the value of g.max() g.min() + 1.
281) bis introduced to avoid any attempt to produce more bits of randomness than can be held in RealType.
§ 26.5.7.2 947
c
ISO/IEC N????
4Effects: Invokes g() ktimes to obtain values g0, . . . , gk1, respectively. Calculates a quantity
S=
k1
X
i=0
(gig.min())·Ri
using arithmetic of type RealType.
5Returns: S/Rk.
6Throws: What and when gthrows.
26.5.8 Random number distribution class templates [rand.dist]
26.5.8.1 In general [rand.dist.general]
1Each type instantiated from a class template specified in this section 26.5.8 satisfies the requirements of a
random number distribution (26.5.1.6) type.
2Descriptions are provided in this section 26.5.8 only for distribution operations that are not described in
26.5.1.6 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.
3The algorithms for producing each of the specified distributions are implementation-defined.
4The value of each probability density function p(z)and of each discrete probability function P(zi)specified
in this section is 0everywhere outside its stated domain.
26.5.8.2 Uniform distributions [rand.dist.uni]
26.5.8.2.1 Class template uniform_int_distribution [rand.dist.uni.int]
1Auniform_int_distribution random number distribution produces random integers i,aib, dis-
tributed according to the constant discrete probability function
P(i|a, b)=1/(ba+ 1) .
template<class IntType = int>
class uniform_int_distribution
{
public:
// types
typedef IntType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& g, const param_type& parm);
// property functions
result_type a() const;
result_type b() const;
param_type param() const;
§ 26.5.8.2.1 948
c
ISO/IEC N????
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());
2Requires: ab.
3Effects: Constructs a uniform_int_distribution object; aand bcorrespond to the respective pa-
rameters of the distribution.
result_type a() const;
4Returns: The value of the aparameter with which the object was constructed.
result_type b() const;
5Returns: The value of the bparameter with which the object was constructed.
26.5.8.2.2 Class template uniform_real_distribution [rand.dist.uni.real]
1Auniform_real_distribution random number distribution produces random numbers x,ax < b,
distributed according to the constant probability density function
p(x|a, b)=1/(ba).
template<class RealType = double>
class uniform_real_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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;
};
§ 26.5.8.2.2 949
c
ISO/IEC N????
explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
2Requires: aband banumeric_limits<RealType>::max().
3Effects: Constructs a uniform_real_distribution object; aand bcorrespond to the respective
parameters of the distribution.
result_type a() const;
4Returns: The value of the aparameter with which the object was constructed.
result_type b() const;
5Returns: The value of the bparameter with which the object was constructed.
26.5.8.3 Bernoulli distributions [rand.dist.bern]
26.5.8.3.1 Class bernoulli_distribution [rand.dist.bern.bernoulli]
1Abernoulli_distribution random number distribution produces bool values bdistributed according to
the discrete probability function
P(b|p) = pif b=true
1pif b=false .
class bernoulli_distribution
{
public:
// types
typedef bool result_type;
typedef unspecified param_type;
// constructors and reset functions
explicit bernoulli_distribution(double p = 0.5);
explicit bernoulli_distribution(const param_type& parm);
void reset();
// generating functions
template<class URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0p1.
3Effects: Constructs a bernoulli_distribution object; pcorresponds to the parameter of the distri-
bution.
§ 26.5.8.3.1 950
c
ISO/IEC N????
double p() const;
4Returns: The value of the pparameter with which the object was constructed.
26.5.8.3.2 Class template binomial_distribution [rand.dist.bern.bin]
1Abinomial_distribution random number distribution produces integer values i0distributed according
to the discrete probability function
P(i|t, p) = t
i·pi·(1 p)ti.
template<class IntType = int>
class binomial_distribution
{
public:
// types
typedef IntType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0p1and 0t.
3Effects: Constructs a binomial_distribution object; tand pcorrespond to the respective parameters
of the distribution.
IntType t() const;
4Returns: The value of the tparameter with which the object was constructed.
double p() const;
5Returns: The value of the pparameter with which the object was constructed.
§ 26.5.8.3.2 951
c
ISO/IEC N????
26.5.8.3.3 Class template geometric_distribution [rand.dist.bern.geo]
1Ageometric_distribution random number distribution produces integer values i0distributed accord-
ing to the discrete probability function
P(i|p) = p·(1 p)i.
template<class IntType = int>
class geometric_distribution
{
public:
// types
typedef IntType result_type;
typedef unspecified param_type;
// constructors and reset functions
explicit geometric_distribution(double p = 0.5);
explicit geometric_distribution(const param_type& parm);
void reset();
// generating functions
template<class URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<p<1.
3Effects: Constructs a geometric_distribution object; pcorresponds to the parameter of the distri-
bution.
double p() const;
4Returns: The value of the pparameter with which the object was constructed.
26.5.8.3.4 Class template negative_binomial_distribution [rand.dist.bern.negbin]
1Anegative_binomial_distribution random number distribution produces random integers i0dis-
tributed according to the discrete probability function
P(i|k, p) = k+i1
i·pk·(1 p)i.
template<class IntType = int>
class negative_binomial_distribution
{
§ 26.5.8.3.4 952
c
ISO/IEC N????
public:
// types
typedef IntType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<p1and 0<k.
3Effects: Constructs a negative_binomial_distribution object; kand pcorrespond to the respective
parameters of the distribution.
IntType k() const;
4Returns: The value of the kparameter with which the object was constructed.
double p() const;
5Returns: The value of the pparameter with which the object was constructed.
26.5.8.4 Poisson distributions [rand.dist.pois]
26.5.8.4.1 Class template poisson_distribution [rand.dist.pois.poisson]
1Apoisson_distribution random number distribution produces integer values i0distributed according
to the discrete probability function
P(i|µ) = eµµi
i!.
The distribution parameter µis also known as this distribution’s mean .
template<class IntType = int>
class poisson_distribution
{
public:
// types
§ 26.5.8.4.1 953
c
ISO/IEC N????
typedef IntType result_type;
typedef unspecified param_type;
// constructors and reset functions
explicit poisson_distribution(double mean = 1.0);
explicit poisson_distribution(const param_type& parm);
void reset();
// generating functions
template<class URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<mean.
3Effects: Constructs a poisson_distribution object; mean corresponds to the parameter of the dis-
tribution.
double mean() const;
4Returns: The value of the mean parameter with which the object was constructed.
26.5.8.4.2 Class template exponential_distribution [rand.dist.pois.exp]
1An exponential_distribution random number distribution produces random numbers x > 0distributed
according to the probability density function
p(x|λ) = λeλx .
template<class RealType = double>
class exponential_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// constructors and reset functions
explicit exponential_distribution(RealType lambda = 1.0);
explicit exponential_distribution(const param_type& parm);
void reset();
// generating functions
template<class URNG>
result_type operator()(URNG& g);
§ 26.5.8.4.2 954
c
ISO/IEC N????
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<lambda.
3Effects: Constructs a exponential_distribution object; lambda corresponds to the parameter of the
distribution.
RealType lambda() const;
4Returns: The value of the lambda parameter with which the object was constructed.
26.5.8.4.3 Class template gamma_distribution [rand.dist.pois.gamma]
1Agamma_distribution random number distribution produces random numbers x > 0distributed according
to the probability density function
p(x|α, β) = ex/β
βα·Γ(α)·xα1.
template<class RealType = double>
class gamma_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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;
};
§ 26.5.8.4.3 955
c
ISO/IEC N????
explicit gamma_distribution(RealType alpha = 1.0, RealType beta = 1.0);
2Requires: 0<alpha and 0<beta.
3Effects: Constructs a gamma_distribution object; alpha and beta correspond to the parameters of
the distribution.
RealType alpha() const;
4Returns: The value of the alpha parameter with which the object was constructed.
RealType beta() const;
5Returns: The value of the beta parameter with which the object was constructed.
26.5.8.4.4 Class template weibull_distribution [rand.dist.pois.weibull]
1Aweibull_distribution random number distribution produces random numbers x0distributed ac-
cording to the probability density function
p(x|a, b) = a
b·x
ba1·exp x
ba.
template<class RealType = double>
class weibull_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<aand 0<b.
3Effects: Constructs a weibull_distribution object; aand bcorrespond to the respective parameters
of the distribution.
§ 26.5.8.4.4 956
c
ISO/IEC N????
RealType a() const;
4Returns: The value of the aparameter with which the object was constructed.
RealType b() const;
5Returns: The value of the bparameter with which the object was constructed.
26.5.8.4.5 Class template extreme_value_distribution [rand.dist.pois.extreme]
1An extreme_value_distribution random number distribution produces random numbers xdistributed
according to the probability density function282
p(x|a, b) = 1
b·exp ax
bexp ax
b .
template<class RealType = double>
class extreme_value_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<b.
3Effects: Constructs an extreme_value_distribution object; aand bcorrespond to the respective
parameters of the distribution.
RealType a() const;
282) 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.
§ 26.5.8.4.5 957
c
ISO/IEC N????
4Returns: The value of the aparameter with which the object was constructed.
RealType b() const;
5Returns: The value of the bparameter with which the object was constructed.
26.5.8.5 Normal distributions [rand.dist.norm]
26.5.8.5.1 Class template normal_distribution [rand.dist.norm.normal]
1Anormal_distribution random number distribution produces random numbers xdistributed according
to the probability density function
p(x|µ, σ) = 1
σ2π·exp (xµ)2
2σ2.
The distribution parameters µand σare also known as this distribution’s mean and standard deviation .
template<class RealType = double>
class normal_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<stddev.
3Effects: Constructs a normal_distribution object; mean and stddev correspond to the respective
parameters of the distribution.
RealType mean() const;
4Returns: The value of the mean parameter with which the object was constructed.
§ 26.5.8.5.1 958
c
ISO/IEC N????
RealType stddev() const;
5Returns: The value of the stddev parameter with which the object was constructed.
26.5.8.5.2 Class template lognormal_distribution [rand.dist.norm.lognormal]
1Alognormal_distribution random number distribution produces random numbers x > 0distributed
according to the probability density function
p(x|m, s) = 1
sx2π·exp (ln xm)2
2s2.
template<class RealType = double>
class lognormal_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<s.
3Effects: Constructs a lognormal_distribution object; mand scorrespond to the respective param-
eters of the distribution.
RealType m() const;
4Returns: The value of the mparameter with which the object was constructed.
RealType s() const;
5Returns: The value of the sparameter with which the object was constructed.
§ 26.5.8.5.2 959
c
ISO/IEC N????
26.5.8.5.3 Class template chi_squared_distribution [rand.dist.norm.chisq]
1Achi_squared_distribution random number distribution produces random numbers x > 0distributed
according to the probability density function
p(x|n) = x(n/2)1·ex/2
Γ(n/2) ·2n/2.
template<class RealType = double>
class chi_squared_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<n.
3Effects: Constructs a chi_squared_distribution object; ncorresponds to the parameter of the
distribution.
RealType n() const;
4Returns: The value of the nparameter with which the object was constructed.
26.5.8.5.4 Class template cauchy_distribution [rand.dist.norm.cauchy]
1Acauchy_distribution random number distribution produces random numbers xdistributed according
to the probability density function
p(x|a, b) = πb 1 + xa
b2!!1
.
§ 26.5.8.5.4 960
c
ISO/IEC N????
template<class RealType = double>
class cauchy_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<b.
3Effects: Constructs a cauchy_distribution object; aand bcorrespond to the respective parameters
of the distribution.
RealType a() const;
4Returns: The value of the aparameter with which the object was constructed.
RealType b() const;
5Returns: The value of the bparameter with which the object was constructed.
26.5.8.5.5 Class template fisher_f_distribution [rand.dist.norm.f]
1Afisher_f_distribution random number distribution produces random numbers x0distributed ac-
cording to the probability density function
p(x|m, n) = Γ(m+n)/2
Γ(m/2) Γ(n/2) ·m
nm/2·x(m/2)1·1 + mx
n(m+n)/2.
template<class RealType = double>
class fisher_f_distribution
{
public:
§ 26.5.8.5.5 961
c
ISO/IEC N????
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<mand 0<n.
3Effects: Constructs a fisher_f_distribution object; mand ncorrespond to the respective parameters
of the distribution.
RealType m() const;
4Returns: The value of the mparameter with which the object was constructed.
RealType n() const;
5Returns: The value of the nparameter with which the object was constructed.
26.5.8.5.6 Class template student_t_distribution [rand.dist.norm.t]
1Astudent_t_distribution random number distribution produces random numbers xdistributed according
to the probability density function
p(x|n) = 1
·Γ(n+ 1)/2
Γ(n/2) ·1 + x2
n(n+1)/2
.
template<class RealType = double>
class student_t_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
§ 26.5.8.5.6 962
c
ISO/IEC N????
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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);
2Requires: 0<n.
3Effects: Constructs a student_t_distribution object; ncorresponds to the parameter of the distri-
bution.
RealType n() const;
4Returns: The value of the nparameter with which the object was constructed.
26.5.8.6 Sampling distributions [rand.dist.samp]
26.5.8.6.1 Class template discrete_distribution [rand.dist.samp.discrete]
1Adiscrete_distribution random number distribution produces random integers i,0i<n, distributed
according to the discrete probability function
P(i|p0, . . . , pn1) = pi.
2Unless specified otherwise, the distribution parameters are calculated as: pk=wk/S for k= 0, . . . , n1,
in which the values wk, commonly known as the weights , shall be non-negative, non-NaN, and non-infinity.
Moreover, the following relation shall hold: 0< S =w0+··· +wn1.
template<class IntType = int>
class discrete_distribution
{
public:
// types
typedef IntType result_type;
typedef unspecified param_type;
// constructor and reset functions
discrete_distribution();
template<class InputIterator>
discrete_distribution(InputIterator firstW, InputIterator lastW);
discrete_distribution(initializer_list<double> wl);
§ 26.5.8.6.1 963
c
ISO/IEC N????
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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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();
3Effects: Constructs a discrete_distribution object with n= 1 and p0= 1. [ Note: Such an object
will always deliver the value 0.— end note ]
template<class InputIterator>
discrete_distribution(InputIterator firstW, InputIterator lastW);
4Requires: InputIterator shall satisfy the requirements of an input iterator (Table 107) type. More-
over, iterator_traits<InputIterator>::value_type shall denote a type that is convertible to
double. If firstW == lastW, let n= 1 and w0= 1. Otherwise, firstW,lastWshall form a se-
quence wof length n > 0.
5Effects: Constructs a discrete_distribution object with probabilities given by the formula above.
discrete_distribution(initializer_list<double> wl);
6Effects: Same as discrete_distribution(wl.begin(), wl.end()).
template<class UnaryOperation>
discrete_distribution(size_t nw, double xmin, double xmax, UnaryOperation fw);
7Requires: Each instance of type UnaryOperation shall be a function object (20.10) whose return type
shall be convertible to double. Moreover, double shall be convertible to the type of UnaryOperation’s
sole parameter. If nw = 0, let n= 1, otherwise let n=nw. The relation 0< δ = (xmax xmin)/n shall
hold.
8Effects: Constructs a discrete_distribution object with probabilities given by the formula above,
using the following values: If nw = 0, let w0= 1. Otherwise, let wk=fw(xmin +k·δ+δ/2) for
k= 0, . . . , n1.
9Complexity: The number of invocations of fw shall not exceed n.
vector<double> probabilities() const;
10 Returns: Avector<double> whose size member returns nand whose operator[] member returns
pkwhen invoked with argument kfor k= 0, . . . , n1.
§ 26.5.8.6.1 964
c
ISO/IEC N????
26.5.8.6.2 Class template piecewise_constant_distribution [rand.dist.samp.pconst]
1Apiecewise_constant_distribution random number distribution produces random numbers x,b0x <
bn, uniformly distributed over each subinterval [bi, bi+1)according to the probability density function
p(x|b0, . . . , bn, ρ0, . . . , ρn1) = ρi, for bix<bi+1 .
2The n+ 1 distribution parameters bi, also known as this distribution’s interval boundaries , shall satisfy the
relation bi< bi+1 for i= 0, . . . , n1. Unless specified otherwise, the remaining ndistribution parameters
are calculated as:
ρk=wk
S·(bk+1 bk)for k= 0, . . . , n1,
in which the values wk, commonly known as the weights , shall be non-negative, non-NaN, and non-infinity.
Moreover, the following relation shall hold: 0< S =w0+··· +wn1.
template<class RealType = double>
class piecewise_constant_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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();
3Effects: Constructs a piecewise_constant_distribution object with n= 1,ρ0= 1,b0= 0, and
b1= 1.
§ 26.5.8.6.2 965
c
ISO/IEC N????
template<class InputIteratorB, class InputIteratorW>
piecewise_constant_distribution(InputIteratorB firstB, InputIteratorB lastB,
InputIteratorW firstW);
4Requires: InputIteratorB and InputIteratorW shall each satisfy the requirements of an input itera-
tor (Table 107) 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 n= 1,w0= 1,b0= 0, and b1= 1. Otherwise,
firstB,lastBshall form a sequence bof length n+ 1, the length of the sequence wstarting from
firstW shall be at least n, and any wkfor knshall be ignored by the distribution.
5Effects: Constructs a piecewise_constant_distribution object with parameters as specified above.
template<class UnaryOperation>
piecewise_constant_distribution(initializer_list<RealType> bl, UnaryOperation fw);
6Requires: Each instance of type UnaryOperation shall be a function object (20.10) whose return type
shall be convertible to double. Moreover, double shall be convertible to the type of UnaryOperation’s
sole parameter.
7Effects: Constructs a piecewise_constant_distribution object with parameters taken or calculated
from the following values: If bl.size() <2, let n= 1,w0= 1,b0= 0, and b1= 1. Otherwise, let
bl.begin(),bl.end()form a sequence b0, . . . , bn, and let wk=fwbk+1 +bk/2for k= 0, . . . , n1.
8Complexity: 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);
9Requires: Each instance of type UnaryOperation shall be a function object (20.10) whose return type
shall be convertible to double. Moreover, double shall be convertible to the type of UnaryOperation’s
sole parameter. If nw = 0, let n= 1, otherwise let n=nw. The relation 0< δ = (xmax xmin)/n shall
hold.
10 Effects: Constructs a piecewise_constant_distribution object with parameters taken or calculated
from the following values: Let bk=xmin+k·δfor k= 0, . . . , n, and wk=fw(bk+δ/2) for k= 0, . . . , n1.
11 Complexity: The number of invocations of fw shall not exceed n.
vector<result_type> intervals() const;
12 Returns: Avector<result_type> whose size member returns n+ 1 and whose operator[] member
returns bkwhen invoked with argument kfor k= 0, . . . , n.
vector<result_type> densities() const;
13 Returns: Avector<result_type> whose size member returns nand whose operator[] member
returns ρkwhen invoked with argument kfor k= 0, . . . , n1.
§ 26.5.8.6.2 966
c
ISO/IEC N????
26.5.8.6.3 Class template piecewise_linear_distribution [rand.dist.samp.plinear]
1Apiecewise_linear_distribution random number distribution produces random numbers x,b0x<bn,
distributed over each subinterval [bi, bi+1)according to the probability density function
p(x|b0, . . . , bn, ρ0, . . . , ρn) = ρi·bi+1 x
bi+1 bi
+ρi+1 ·xbi
bi+1 bi
, for bix<bi+1 .
2The n+ 1 distribution parameters bi, also known as this distribution’s interval boundaries , shall satisfy the
relation bi< bi+1 for i= 0, . . . , n1. Unless specified otherwise, the remaining n+ 1 distribution parameters
are calculated as ρk=wk/S for k= 0, . . . , n, in which the values wk, commonly known as the weights at
boundaries , shall be non-negative, non-NaN, and non-infinity. Moreover, the following relation shall hold:
0< S =1
2·
n1
X
k=0
(wk+wk+1)·(bk+1 bk).
template<class RealType = double>
class piecewise_linear_distribution
{
public:
// types
typedef RealType result_type;
typedef unspecified param_type;
// 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 URNG>
result_type operator()(URNG& g);
template<class URNG>
result_type operator()(URNG& 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();
3Effects: Constructs a piecewise_linear_distribution object with n= 1,ρ0=ρ1= 1,b0= 0, and
b1= 1.
§ 26.5.8.6.3 967
c
ISO/IEC N????
template<class InputIteratorB, class InputIteratorW>
piecewise_linear_distribution(InputIteratorB firstB, InputIteratorB lastB,
InputIteratorW firstW);
4Requires: InputIteratorB and InputIteratorW shall each satisfy the requirements of an input itera-
tor (Table 107) 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 n= 1,ρ0=ρ1= 1,b0= 0, and b1= 1. Otherwise,
firstB,lastBshall form a sequence bof length n+ 1, the length of the sequence wstarting from
firstW shall be at least n+ 1, and any wkfor kn+ 1 shall be ignored by the distribution.
5Effects: Constructs a piecewise_linear_distribution object with parameters as specified above.
template<class UnaryOperation>
piecewise_linear_distribution(initializer_list<RealType> bl, UnaryOperation fw);
6Requires: Each instance of type UnaryOperation shall be a function object (20.10) whose return type
shall be convertible to double. Moreover, double shall be convertible to the type of UnaryOperation’s
sole parameter.
7Effects: Constructs a piecewise_linear_distribution object with parameters taken or calculated
from the following values: If bl.size() <2, let n= 1,ρ0=ρ1= 1,b0= 0, and b1= 1. Otherwise,
let bl.begin(),bl.end()form a sequence b0, . . . , bn, and let wk=fw(bk)for k= 0, . . . , n.
8Complexity: The number of invocations of fw shall not exceed n+ 1.
template<class UnaryOperation>
piecewise_linear_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw);
9Requires: Each instance of type UnaryOperation shall be a function object (20.10) whose return type
shall be convertible to double. Moreover, double shall be convertible to the type of UnaryOperation’s
sole parameter. If nw = 0, let n= 1, otherwise let n=nw. The relation 0< δ = (xmax xmin)/n shall
hold.
10 Effects: Constructs a piecewise_linear_distribution object with parameters taken or calculated
from the following values: Let bk=xmin +k·δfor k= 0, . . . , n, and wk=fw(bk)for k= 0, . . . , n.
11 Complexity: The number of invocations of fw shall not exceed n+ 1.
vector<result_type> intervals() const;
12 Returns: Avector<result_type> whose size member returns n+ 1 and whose operator[] member
returns bkwhen invoked with argument kfor k= 0, . . . , n.
vector<result_type> densities() const;
13 Returns: Avector<result_type> whose size member returns nand whose operator[] member
returns ρkwhen invoked with argument kfor k= 0, . . . , n.
§ 26.5.8.6.3 968
c
ISO/IEC N????
26.6 Numeric arrays [numarray]
26.6.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&);
§ 26.6.1 969
c
ISO/IEC N????
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>&);
§ 26.6.1 970
c
ISO/IEC N????
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> unspecified 1 begin(valarray<T>& v);
template <class T> unspecified 2 begin(const valarray<T>& v);
template <class T> unspecified 1 end(valarray<T>& v);
template <class T> unspecified 2 end(const valarray<T>& v);
}
1The 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 rep-
resenting and manipulating arrays of values.
2The valarray array classes are defined to be free of certain forms of aliasing, thus allowing operations on
these classes to be optimized.
3Any 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.283
4Implementations 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 (26.6.10), identical func-
tions taking the replacement types shall be added;
for every function taking two const valarray<T>& arguments, identical functions taking every com-
bination of const valarray<T>& and replacement types shall be added.
5In particular, an implementation shall allow a valarray<T> to be constructed from such replacement types
and shall allow assignments and computed assignments of such types to valarray<T>,slice_array<T>,
gslice_array<T>,mask_array<T> and indirect_array<T> objects.
6These library functions are permitted to throw a bad_alloc (18.6.2.1) exception if there are not sufficient
resources available to carry out the operation. Note that the exception is not mandated.
26.6.2 Class template valarray [template.valarray]
26.6.2.1 Class template valarray overview [template.valarray.overview]
namespace std {
template<class T> class valarray {
public:
typedef T value_type;
// 26.6.2.2 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>&);
283) Clause 18.3.2 recommends a minimum number of recursively nested template instantiations. This requirement thus
indirectly suggests a minimum allowable complexity for valarray expressions.
§ 26.6.2.1 971
c
ISO/IEC N????
valarray(const indirect_array<T>&);
valarray(initializer_list<T>);
~valarray();
// 26.6.2.3 assignment:
valarray<T>& operator=(const valarray<T>&);
valarray<T>& operator=(valarray<T>&&) noexcept;
valarray& operator=(initializer_list<T>);
valarray<T>& operator=(const T&);
valarray<T>& operator=(const slice_array<T>&);
valarray<T>& operator=(const gslice_array<T>&);
valarray<T>& operator=(const mask_array<T>&);
valarray<T>& operator=(const indirect_array<T>&);
// 26.6.2.4 element access:
const T& operator[](size_t) const;
T& operator[](size_t);
// 26.6.2.5 subset operations:
valarray<T> operator[](slice) const;
slice_array<T> operator[](slice);
valarray<T> operator[](const gslice&) const;
gslice_array<T> operator[](const gslice&);
valarray<T> operator[](const valarray<bool>&) const;
mask_array<T> operator[](const valarray<bool>&);
valarray<T> operator[](const valarray<size_t>&) const;
indirect_array<T> operator[](const valarray<size_t>&);
// 26.6.2.6 unary operators:
valarray<T> operator+() const;
valarray<T> operator-() const;
valarray<T> operator~() const;
valarray<bool> operator!() const;
// 26.6.2.7 computed assignment:
valarray<T>& operator*= (const T&);
valarray<T>& operator/= (const T&);
valarray<T>& operator%= (const T&);
valarray<T>& operator+= (const T&);
valarray<T>& operator-= (const T&);
valarray<T>& operator^= (const T&);
valarray<T>& operator&= (const T&);
valarray<T>& operator|= (const T&);
valarray<T>& operator<<=(const T&);
valarray<T>& operator>>=(const T&);
valarray<T>& operator*= (const valarray<T>&);
valarray<T>& operator/= (const valarray<T>&);
valarray<T>& operator%= (const valarray<T>&);
valarray<T>& operator+= (const valarray<T>&);
valarray<T>& operator-= (const valarray<T>&);
valarray<T>& operator^= (const valarray<T>&);
valarray<T>& operator|= (const valarray<T>&);
valarray<T>& operator&= (const valarray<T>&);
valarray<T>& operator<<=(const valarray<T>&);
§ 26.6.2.1 972
c
ISO/IEC N????
valarray<T>& operator>>=(const valarray<T>&);
// 26.6.2.8 member functions:
void swap(valarray&) noexcept;
size_t size() const;
T sum() const;
T min() const;
T max() const;
valarray<T> shift (int) const;
valarray<T> cshift(int) const;
valarray<T> apply(T func(T)) const;
valarray<T> apply(T func(const T&)) const;
void resize(size_t sz, T c = T());
};
}
1The 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. 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.284
2An implementation is permitted to qualify any of the functions declared in <valarray> as inline.
26.6.2.2 valarray constructors [valarray.cons]
valarray();
1Effects: Constructs an object of class valarray<T>285 which has zero length.286
explicit valarray(size_t);
2The array created by this constructor has a length equal to the value of the argument. The elements
of the array are value-initialized (8.5).
valarray(const T&, size_t);
3The array created by this constructor has a length equal to the second argument. The elements of the
array are initialized with the value of the first argument.
valarray(const T*, size_t);
4The array created by this constructor has a length equal to the second argument n. The values of the
elements of the array are initialized with the first nvalues pointed to by the first argument.287 If the
value of the second argument is greater than the number of values pointed to by the first argument,
the behavior is undefined.
284) 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.
285) For convenience, such objects are referred to as “arrays” throughout the remainder of 26.6.
286) 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.
287) This constructor is the preferred method for converting a C array to a valarray object.
§ 26.6.2.2 973
c
ISO/IEC N????
valarray(const valarray<T>&);
5The array created by this constructor has the same length as the argument array. The elements are
initialized with the values of the corresponding elements of the argument array.288
valarray(valarray<T>&& v) noexcept;
6The array created by this constructor has the same length as the argument array. The elements are
initialized with the values of the corresponding elements of the argument array.
7Complexity: Constant.
valarray(initializer_list<T> il);
8Effects: Same as 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>&);
9These conversion constructors convert one of the four reference templates to a valarray.
~valarray();
10 The destructor is applied to every element of *this; an implementation may return all allocated
memory.
26.6.2.3 valarray assignment [valarray.assign]
valarray<T>& operator=(const valarray<T>& v);
1Each element of the *this array is assigned the value of the corresponding element of the argument
array. If the length of vis 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.
2Postcondition: size() == v.size().
valarray<T>& operator=(valarray<T>&& v) noexcept;
3Effects: *this obtains the value of v. The value of vafter the assignment is not specified.
4Complexity: Linear.
valarray& operator=(initializer_list<T> il);
5Effects: *this = valarray(il).
6Returns: *this.
288) 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.
§ 26.6.2.3 974
c
ISO/IEC N????
valarray<T>& operator=(const T&);
7The scalar assignment operator causes each element of the *this array to be assigned the value of the
argument.
valarray<T>& operator=(const slice_array<T>&);
valarray<T>& operator=(const gslice_array<T>&);
valarray<T>& operator=(const mask_array<T>&);
valarray<T>& operator=(const indirect_array<T>&);
8Requires: The length of the array to which the argument refers equals size().
9These operators allow the results of a generalized subscripting operation to be assigned directly to a
valarray.
10 If the value of an element in the left-hand side of a valarray assignment operator depends on the value
of another element in that left-hand side, the resulting behavior is undefined.
26.6.2.4 valarray element access [valarray.access]
const T& operator[](size_t) const;
T& operator[](size_t);
1The subscript operator returns a reference to the corresponding element of the array.
2Thus, the expression (a[i] = q, a[i]) == q evaluates as true for any non-constant valarray<T> a,
any T q, and for any size_t i such that the value of iis less than the length of a.
3The expression &a[i+j] == &a[i] + j evaluates as true for all size_t i and size_t j such that
i+j is less than the length of the array a.
4Likewise, the expression &a[i] != &b[j] evaluates as true for any two arrays aand band for any
size_t i and size_t j such that iis less than the length of aand jis less than the length of b. This
property indicates an absence of aliasing and may be used to advantage by optimizing compilers.289
5The reference returned by the subscript operator for an array shall be valid until the member function
resize(size_t, T) (26.6.2.8) is called for that array or until the lifetime of that array ends, whichever
happens first.
6If the subscript operator is invoked with a size_t argument whose value is not less than the length of
the array, the behavior is undefined.
26.6.2.5 valarray subset operations [valarray.sub]
1The 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<T> operator[](slice slicearr) const;
2Returns: An object of class valarray<T> containing those elements of the controlled sequence desig-
nated by slicearr. [ Example:
const valarray<char> v0("abcdefghijklmnop", 16);
// v0[slice(2, 5, 3)] returns valarray<char>("cfilo", 5)
289) Compilers may take advantage of inlining, constant propagation, loop fusion, tracking of pointers obtained from operator
new, and other techniques to generate efficient valarrays.
§ 26.6.2.5 975
c
ISO/IEC N????
— end example ]
slice_array<T> operator[](slice slicearr);
3Returns: 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<T> operator[](const gslice& gslicearr) const;
4Returns: An object of class valarray<T> containing those elements of the controlled sequence desig-
nated 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);
5Returns: An object that holds references to elements of the controlled sequence selected by gslicearr.
[Example:
valarray<char> v0("abcdefghijklmnop", 16);
valarray<char> v1("ABCDE", 5);
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<T> operator[](const valarray<bool>& boolarr) const;
6Returns: An object of class valarray<T> containing those elements of the controlled sequence desig-
nated 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 ]
§ 26.6.2.5 976
c
ISO/IEC N????
mask_array<T> operator[](const valarray<bool>& boolarr);
7Returns: 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<T> operator[](const valarray<size_t>& indarr) const;
8Returns: An object of class valarray<T> containing those elements of the controlled sequence desig-
nated 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);
9Returns: 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 ]
26.6.2.6 valarray unary operators [valarray.unary]
valarray<T> operator+() const;
valarray<T> operator-() const;
valarray<T> operator~() const;
valarray<bool> operator!() const;
1Each of these operators may only be instantiated for a type Tto 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!).
2Each of these operators returns an array whose length is equal to the length of the array. Each
element of the returned array is initialized with the result of applying the indicated operator to the
corresponding element of the array.
§ 26.6.2.6 977
c
ISO/IEC N????
26.6.2.7 valarray computed assignment [valarray.cassign]
valarray<T>& operator*= (const valarray<T>&);
valarray<T>& operator/= (const valarray<T>&);
valarray<T>& operator%= (const valarray<T>&);
valarray<T>& operator+= (const valarray<T>&);
valarray<T>& operator-= (const valarray<T>&);
valarray<T>& operator^= (const valarray<T>&);
valarray<T>& operator&= (const valarray<T>&);
valarray<T>& operator|= (const valarray<T>&);
valarray<T>& operator<<=(const valarray<T>&);
valarray<T>& operator>>=(const valarray<T>&);
1Each of these operators may only be instantiated for a type Tto which the indicated operator can
be applied. Each of these operators performs the indicated operation on each of its elements and the
corresponding element of the argument array.
2The array is then returned by reference.
3If the array and the argument array do not have the same length, the behavior is undefined. The
appearance of an array on the left-hand side of a computed assignment does not invalidate references
or pointers.
4If the value of an element in the left-hand side of a valarray computed assignment operator depends
on the value of another element in that left hand side, the resulting behavior is undefined.
valarray<T>& operator*= (const T&);
valarray<T>& operator/= (const T&);
valarray<T>& operator%= (const T&);
valarray<T>& operator+= (const T&);
valarray<T>& operator-= (const T&);
valarray<T>& operator^= (const T&);
valarray<T>& operator&= (const T&);
valarray<T>& operator|= (const T&);
valarray<T>& operator<<=(const T&);
valarray<T>& operator>>=(const T&);
5Each of these operators may only be instantiated for a type Tto which the indicated operator can be
applied.
6Each of these operators applies the indicated operation to each element of the array and the non-array
argument.
7The array is then returned by reference.
8The appearance of an array on the left-hand side of a computed assignment does not invalidate refer-
ences or pointers to the elements of the array.
26.6.2.8 valarray member functions [valarray.members]
void swap(valarray& v) noexcept;
1Effects: *this obtains the value of v.vobtains the value of *this.
2Complexity: Constant.
size_t size() const;
§ 26.6.2.8 978
c
ISO/IEC N????
3Returns: The number of elements in the array.
4Complexity: constant time.
T sum() const;
This function may only be instantiated for a type Tto which operator+= can be applied. This function
returns the sum of all the elements of the array.
5If the array has length 0, the behavior is undefined. If the array has length 1, sum() 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;
6This function returns the minimum value contained in *this. The value returned for an array of
length 0 is undefined. 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;
7This function returns the maximum value contained in *this. The value returned for an array of
length 0 is undefined. 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<T> shift(int n) const;
8This function returns an object of class valarray<T> of length size(), each of whose elements Iis
(*this)[I + n] if I+nis non-negative and less than size(), otherwise T(). Thus if element zero
is taken as the leftmost element, a positive value of nshifts the elements left nplaces, with zero fill.
9[Example: If the argument has the value -2, the first two elements of the result will be value-
initialized (8.5); the third element of the result will be assigned the value of the first element of
the argument; etc. — end example ]
valarray<T> cshift(int n) const;
10 This function returns an object of class valarray<T> of length size() that is a circular shift of *this.
If element zero is taken as the leftmost element, a non-negative value of nshifts the elements circularly
left nplaces and a negative value of nshifts the elements circularly right -n places.
valarray<T> apply(T func(T)) const;
valarray<T> apply(T func(const T&)) const;
11 These functions return an array whose length is equal to the array. Each element of the returned array
is assigned the value returned by applying the argument function to the corresponding element of the
array.
void resize(size_t sz, T c = T());
12 This member function 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.
§ 26.6.2.8 979
c
ISO/IEC N????
26.6.3 valarray non-member operations [valarray.nonmembers]
26.6.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>&);
1Each of these operators may only be instantiated for a type Tto which the indicated operator can
be applied and for which the indicated operator returns a value which is of type Tor which can be
unambiguously implicitly converted to type T.
2Each of these operators returns an array 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.
3If the argument arrays do not have the same length, the behavior is undefined.
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>&);
§ 26.6.3.1 980
c
ISO/IEC N????
4Each of these operators may only be instantiated for a type Tto which the indicated operator can
be applied and for which the indicated operator returns a value which is of type Tor which can be
unambiguously implicitly converted to type T.
5Each of these operators returns an array 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.
26.6.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>&);
1Each of these operators may only be instantiated for a type Tto 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.
2Each of these operators returns a bool array 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.
3If the two array arguments do not have the same length, the behavior is undefined.
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>&);
4Each of these operators may only be instantiated for a type Tto 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.
§ 26.6.3.2 981
c
ISO/IEC N????
5Each of these operators returns a bool array 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.
26.6.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>&);
1Each of these functions may only be instantiated for a type Tto which a unique function with the
indicated name can be applied (unqualified). This function shall return a value which is of type Tor
which can be unambiguously implicitly converted to type T.
26.6.3.4 valarray specialized algorithms [valarray.special]
template <class T> void swap(valarray<T>& x, valarray<T>& y) noexcept;
1Effects: x.swap(y).
26.6.4 Class slice [class.slice]
26.6.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;
};
}
§ 26.6.4.1 982
c
ISO/IEC N????
1The slice class represents a BLAS-like slice from an array. Such a slice is specified by a starting index, a
length, and a stride.290
26.6.4.2 slice constructors [cons.slice]
slice();
slice(size_t start, size_t length, size_t stride);
slice(const slice&);
1The 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.
2[Example: slice(3, 8, 2) constructs a slice which selects elements 3, 5, 7, ... 17 from an array.
— end example ]
26.6.4.3 slice access functions [slice.access]
size_t start() const;
size_t size() const;
size_t stride() const;
1Returns: The start, length, or stride specified by a slice object.
2Complexity: constant time.
26.6.5 Class template slice_array [template.slice.array]
26.6.5.1 Class template slice_array overview [template.slice.array.overview]
namespace std {
template <class T> class slice_array {
public:
typedef T value_type;
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
};
}
290) 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.
§ 26.6.5.1 983
c
ISO/IEC N????
1The 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.
2[Example: The expression a[slice(1, 5, 3)] = b; has the effect of assigning the elements of bto a slice
of the elements in a. For the slice shown, the elements selected from aare 1, 4, ..., 13. — end example ]
26.6.5.2 slice_array assignment [slice.arr.assign]
void operator=(const valarray<T>&) const;
const slice_array& operator=(const slice_array&) const;
1These 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.
26.6.5.3 slice_array computed 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;
1These computed 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.
26.6.5.4 slice_array fill function [slice.arr.fill]
void operator=(const T&) const;
1This 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.
26.6.6 The gslice class [class.gslice]
26.6.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;
};
}
1This class represents a generalized slice out of an array. A gslice is defined by a starting offset (s), a set
of lengths (lj), and a set of strides (dj). The number of lengths shall equal the number of strides.
§ 26.6.6.1 984
c
ISO/IEC N????
2Agslice represents a mapping from a set of indices (ij), 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
k=s+X
j
ijdj
where the multidimensional indices ijrange in value from 0 to lij 1.
3[Example: The gslice specification
start = 3
length = {2, 4, 3}
stride = {19, 4, 1}
yields the sequence of one-dimensional indices
k= 3 + (0,1) ×19 + (0,1,2,3) ×4 + (0,1,2) ×1
which are ordered as shown in the following table:
(i0, i1, i2, k) =
(0,0,0,3),
(0,0,1,4),
(0,0,2,5),
(0,1,0,7),
(0,1,1,8),
(0,1,2,9),
(0,2,0,11),
(0,2,1,12),
(0,2,2,13),
(0,3,0,15),
(0,3,1,16),
(0,3,2,17),
(1,0,0,22),
(1,0,1,23),
. . .
(1,3,2,36)
That is, the highest-ordered index turns fastest. — end example ]
4It is possible to have degenerate generalized slices in which an address is repeated.
5[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
(0,0,0,3),
(0,0,1,4),
(0,0,2,5),
(0,1,0,4),
(0,1,1,5),
(0,1,2,6),
. . .
— end example ]
6If a degenerate slice is used as the argument to the non-const version of operator[](const gslice&), the
resulting behavior is undefined.
§ 26.6.6.1 985
c
ISO/IEC N????
26.6.6.2 gslice constructors [gslice.cons]
gslice();
gslice(size_t start, const valarray<size_t>& lengths,
const valarray<size_t>& strides);
gslice(const gslice&);
1The 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.
26.6.6.3 gslice access functions [gslice.access]
size_t start() const;
valarray<size_t> size() const;
valarray<size_t> stride() const;
1Returns: The representation of the start, lengths, or strides specified for the gslice.
2Complexity: start() is constant time. size() and stride() are linear in the number of strides.
26.6.7 Class template gslice_array [template.gslice.array]
26.6.7.1 Class template gslice_array overview [template.gslice.array.overview]
namespace std {
template <class T> class gslice_array {
public:
typedef T value_type;
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
};
}
1This template is a helper template used by the slice subscript operator
gslice_array<T> valarray<T>::operator[](const gslice&);
2It has reference semantics to a subset of an array specified by a gslice object.
3Thus, the expression a[gslice(1, length, stride)] = b has the effect of assigning the elements of
bto a generalized slice of the elements in a.
§ 26.6.7.1 986
c
ISO/IEC N????
26.6.7.2 gslice_array assignment [gslice.array.assign]
void operator=(const valarray<T>&) const;
const gslice_array& operator=(const gslice_array&) const;
1These 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.
26.6.7.3 gslice_array [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;
1These computed 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.
26.6.7.4 gslice_array fill function [gslice.array.fill]
void operator=(const T&) const;
1This 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.
26.6.8 Class template mask_array [template.mask.array]
26.6.8.1 Class template mask_array overview [template.mask.array.overview]
namespace std {
template <class T> class mask_array {
public:
typedef T value_type;
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;
§ 26.6.8.1 987
c
ISO/IEC N????
mask_array() = delete; // as implied by declaring copy constructor above
};
}
1This template is a helper template used by the mask subscript operator:
mask_array<T> valarray<T>::operator[](const valarray<bool>&).
2It 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 bto the masked elements in a(those for
which the corresponding element in mask is true.)
26.6.8.2 mask_array assignment [mask.array.assign]
void operator=(const valarray<T>&) const;
const mask_array& operator=(const mask_array&) const;
1These 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.
26.6.8.3 mask_array computed 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;
1These computed 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.
26.6.8.4 mask_array fill function [mask.array.fill]
void operator=(const T&) const;
1This 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.
26.6.9 Class template indirect_array [template.indirect.array]
26.6.9.1 Class template indirect_array overview [template.indirect.array.overview]
namespace std {
template <class T> class indirect_array {
public:
typedef T value_type;
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;
§ 26.6.9.1 988
c
ISO/IEC N????
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
};
}
1This template is a helper template used by the indirect subscript operator
indirect_array<T> valarray<T>::operator[](const valarray<size_t>&).
2It 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 bto the elements in awhose indices
appear in indirect.
26.6.9.2 indirect_array assignment [indirect.array.assign]
void operator=(const valarray<T>&) const;
const indirect_array& operator=(const indirect_array&) const;
1These 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.
2If the indirect_array specifies an element in the valarray<T> object to which it refers more than
once, the behavior is undefined.
3[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 ]
26.6.9.3 indirect_array computed 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;
1These computed 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.
2If the indirect_array specifies an element in the valarray<T> object to which it refers more than
once, the behavior is undefined.
§ 26.6.9.3 989
c
ISO/IEC N????
26.6.9.4 indirect_array fill function [indirect.array.fill]
void operator=(const T&) const;
1This 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.
26.6.10 valarray range access [valarray.range]
1In the begin and end function templates that follow, unspecified 1 is a type that meets the requirements
of a mutable random access iterator (24.2.7) whose value_type is the template parameter Tand whose
reference type is T&.unspecified 2 is a type that meets the requirements of a constant random access
iterator (24.2.7) whose value_type is the template parameter Tand whose reference type is const T&.
2The iterators returned by begin and end for an array are guaranteed to be valid until the member function
resize(size_t, T) (26.6.2.8) is called for that array or until the lifetime of that array ends, whichever
happens first.
template <class T> unspecified 1 begin(valarray<T>& v);
template <class T> unspecified 2 begin(const valarray<T>& v);
3Returns: An iterator referencing the first value in the numeric array.
template <class T> unspecified 1 end(valarray<T>& v);
template <class T> unspecified 2 end(const valarray<T>& v);
4Returns: An iterator referencing one past the last value in the numeric array.
26.7 Generalized numeric operations [numeric.ops]
26.7.1 Header <numeric> synopsis [numeric.ops.overview]
namespace std {
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);
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);
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,
§ 26.7.1 990
c
ISO/IEC N????
BinaryOperation binary_op);
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 ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value);
}
1The requirements on the types of algorithms’ arguments that are described in the introduction to Clause 25
also apply to the following algorithms.
26.7.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);
1Effects: 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 iin the range
[first,last) in order.291
2Requires: Tshall meet the requirements of CopyConstructible (Table 21) and CopyAssignable (Ta-
ble 23) types. In the range [first,last],binary_op shall neither modify elements nor invalidate
iterators or subranges.292
26.7.3 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);
1Effects: 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.
291) 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.
292) The use of fully closed ranges is intentional
§ 26.7.3 991
c
ISO/IEC N????
2Requires: Tshall meet the requirements of CopyConstructible (Table 21) and CopyAssignable (Ta-
ble 23) 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.293
26.7.4 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);
1Effects: 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 iin [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)).
2Returns: result + (last - first).
3Complexity: Exactly (last - first) - 1 applications of the binary operation.
4Requires: 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 to the result output iterator. In the ranges [first,last] and
[result,result + (last - first)] binary_op shall neither modify elements nor invalidate itera-
tors or subranges.294
5Remarks: result may be equal to first.
26.7.5 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);
1Effects: 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 iin [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.
2Requires: InputIterator’s value type shall be MoveAssignable (Table 22) and shall be constructible
from the type of *first.acc shall be writable 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. In
293) The use of fully closed ranges is intentional
294) The use of fully closed ranges is intentional.
§ 26.7.5 992
c
ISO/IEC N????
the ranges [first,last] and [result,result + (last - first)],binary_op shall neither modify
elements nor invalidate iterators or subranges.295
3Remarks: result may be equal to first.
4Returns: result + (last - first).
5Complexity: Exactly (last - first) - 1 applications of the binary operation.
26.7.6 Iota [numeric.iota]
template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value);
1Requires: Tshall be convertible to ForwardIterator’s value type. The expression ++val, where val
has type T, shall be well formed.
2Effects: For each element referred to by the iterator iin the range [first,last), assigns *i = value
and increments value as if by ++value.
3Complexity: Exactly last - first increments and assignments.
26.8 C library [c.math]
1The header <ctgmath> simply includes the headers <ccomplex> and <cmath>.
2[Note: The overloads provided in C by type-generic macros are already provided in <ccomplex> and <cmath>
by “sufficient” additional overloads. — end note ]
3Tables 119 and 120 describe headers <cmath> and <cstdlib>, respectively.
4The contents of these headers are the same as the Standard C library headers <math.h> and <stdlib.h>
respectively, with the following changes:
5The rand function has the semantics specified in the C standard, except that the implementation may specify
that particular library functions may call rand. It is implementation-defined whether the rand function may
introduce data races (17.6.5.9). [ Note: The random number generation (26.5) facilities in this standard are
often preferable to rand.— end note ]
6In addition to the int versions of certain math functions in <cstdlib>, C++ adds long and long long
overloaded versions of these functions, with the same semantics.
7The added signatures are:
long abs(long); // labs()
long long abs(long long); // llabs()
ldiv_t div(long, long); // ldiv()
lldiv_t div(long long, long long); // lldiv()
8In addition to the double versions of the math functions in <cmath>, C++ adds float and long double
overloaded versions of these functions, with the same semantics.
9The added signatures are:
float abs(float);
float acos(float);
float acosh(float);
float asin(float);
float asinh(float);
float atan(float);
float atan2(float, float);
float atanh(float);
float cbrt(float);
float ceil(float);
295) The use of fully closed ranges is intentional.
§ 26.8 993
c
ISO/IEC N????
Table 119 — Header <cmath> synopsis
Type Name(s)
Macros:
FP_FAST_FMA FP_ILOGBNAN FP_SUBNORMAL HUGE_VALL MATH_ERRNO
FP_FAST_FMAF FP_INFINITE FP_ZERO INFINITY MATH_ERREXCEPT
FP_FAST_FMAL FP_NAN HUGE_VAL NAN math_errhandling
FP_ILOGB0 FP_NORMAL HUGE_VALF
Types:double_t float_t
Math Functions:
abs cosh fmod logb remquo
acos erf frexp lrint rint
acosh erfc hypot lround round
asin exp2 ilogb modf scalbln
asinh exp ldexp nan scalbn
atan expm1 lgamma nanf sin
atan2 fabs llrint nanl sinh
atanh fdim llround nearbyint sqrt
cbrt floor log nextafter tan
ceil fma log10 nexttoward tanh
copysign fmax log1p pow tgamma
cos fmin log2 remainder trunc
Classification/comparison Functions:
fpclassify isgreaterequal islessequal isnan isunordered
isfinite isinf islessgreater isnormal signbit
isgreater isless
Table 120 — Header <cstdlib> synopsis
Type Name(s)
Macro:RAND_MAX
Types:
div_t ldiv_t lldiv_t
Functions:
abs ldiv rand
div llabs srand
labs lldiv
§ 26.8 994
c
ISO/IEC N????
float copysign(float, float);
float cos(float);
float cosh(float);
float erf(float);
float erfc(float);
float exp(float);
float exp2(float);
float expm1(float);
float fabs(float);
float fdim(float, float);
float floor(float);
float fma(float, float, float);
float fmax(float, float);
float fmin(float, float);
float fmod(float, float);
float frexp(float, int*);
float hypot(float, float);
int ilogb(float);
float ldexp(float, int);
float lgamma(float);
long long llrint(float);
long long llround(float);
float log(float);
float log10(float);
float log1p(float);
float log2(float);
float logb(float);
long lrint(float);
long lround(float);
float modf(float, float*);
float nearbyint(float);
float nextafter(float, float);
float nexttoward(float, long double);
float pow(float, float);
float remainder(float, float);
float remquo(float, float, int *);
float rint(float);
float round(float);
float scalbln(float, long);
float scalbn(float, int);
float sin(float);
float sinh(float);
float sqrt(float);
float tan(float);
float tanh(float);
float tgamma(float);
float trunc(float);
double abs(double); // fabs()
long double abs(long double);
long double acos(long double);
long double acosh(long double);
long double asin(long double);
long double asinh(long double);
§ 26.8 995
c
ISO/IEC N????
long double atan(long double);
long double atan2(long double, long double);
long double atanh(long double);
long double cbrt(long double);
long double ceil(long double);
long double copysign(long double, long double);
long double cos(long double);
long double cosh(long double);
long double erf(long double);
long double erfc(long double);
long double exp(long double);
long double exp2(long double);
long double expm1(long double);
long double fabs(long double);
long double fdim(long double, long double);
long double floor(long double);
long double fma(long double, long double, long double);
long double fmax(long double, long double);
long double fmin(long double, long double);
long double fmod(long double, long double);
long double frexp(long double, int*);
long double hypot(long double, long double);
int ilogb(long double);
long double ldexp(long double, int);
long double lgamma(long double);
long long llrint(long double);
long long llround(long double);
long double log(long double);
long double log10(long double);
long double log1p(long double);
long double log2(long double);
long double logb(long double);
long lrint(long double);
long lround(long double);
long double modf(long double, long double*);
long double nearbyint(long double);
long double nextafter(long double, long double);
long double nexttoward(long double, long double);
long double pow(long double, long double);
long double remainder(long double, long double);
long double remquo(long double, long double, int *);
long double rint(long double);
long double round(long double);
long double scalbln(long double, long);
long double scalbn(long double, int);
long double sin(long double);
long double sinh(long double);
long double sqrt(long double);
long double tan(long double);
long double tanh(long double);
long double tgamma(long double);
long double trunc(long double);
10 The classification/comparison functions behave the same as the C macros with the corresponding names
defined in 7.12.3, Classification macros, and 7.12.14, Comparison macros in the C Standard. Each function
§ 26.8 996
c
ISO/IEC N????
is overloaded for the three floating-point types, as follows:
int fpclassify(float x);
bool isfinite(float x);
bool isinf(float x);
bool isnan(float x);
bool isnormal(float x);
bool signbit(float x);
bool isgreater(float x, float y);
bool isgreaterequal(float x, float y);
bool isless(float x, float y);
bool islessequal(float x, float y);
bool islessgreater(float x, float y);
bool isunordered(float x, float y);
int fpclassify(double x);
bool isfinite(double x);
bool isinf(double x);
bool isnan(double x);
bool isnormal(double x);
bool signbit(double x);
bool isgreater(double x, double y);
bool isgreaterequal(double x, double y);
bool isless(double x, double y);
bool islessequal(double x, double y);
bool islessgreater(double x, double y);
bool isunordered(double x, double y);
int fpclassify(long double x);
bool isfinite(long double x);
bool isinf(long double x);
bool isnan(long double x);
bool isnormal(long double x);
bool signbit(long double x);
bool isgreater(long double x, long double y);
bool isgreaterequal(long double x, long double y);
bool isless(long double x, long double y);
bool islessequal(long double x, long double y);
bool islessgreater(long double x, long double y);
bool isunordered(long double x, long double y);
11 Moreover, there shall be additional overloads sufficient to ensure:
1. If any arithmetic argument corresponding to a double parameter has type long double, then all
arithmetic arguments corresponding to double parameters are effectively cast to long double.
2. Otherwise, if any arithmetic argument corresponding to a double parameter has type double or an
integer type, then all arithmetic arguments corresponding to double parameters are effectively cast to
double.
3. Otherwise, all arithmetic arguments corresponding to double parameters have type float.
See also: ISO C 7.5, 7.10.2, 7.10.6.
§ 26.8 997
c
ISO/IEC N????
27 Input/output library [input.output]
27.1 General [input.output.general]
1This Clause describes components that C++ programs may use to perform input/output operations.
2The following subclauses describe requirements for stream parameters, and components for forward declara-
tions of iostreams, predefined iostreams objects, base iostreams classes, stream buffering, stream formatting
and manipulators, string streams, and file streams, as summarized in Table 121.
Table 121 — Input/output library summary
Subclause Header(s)
27.2 Requirements
27.3 Forward declarations <iosfwd>
27.4 Standard iostream objects <iostream>
27.5 Iostreams base classes <ios>
27.6 Stream buffers <streambuf>
27.7 Formatting and manipulators <istream>
<ostream>
<iomanip>
27.8 String streams <sstream>
27.9 File streams <fstream>
<cstdio>
<cinttypes>
3Figure 7illustrates relationships among various types described in this clause. A line from Ato Bindicates
that Ais an alias (e.g. a typedef) for Bor that Ais defined in terms of B.
char_traits<char>
::pos_type
streampos
iostreams.limits.pos
char_traits<wchar_t>
::pos_type
wstreampos
iostreams.limits.pos
fpos<mbstate_t>
iostream.forward iostream.forward
char_traits<char>
::off_type
streamoff
iostreams.limits.pos
char_traits<wchar_t>
::off_type
iostreams.limits.pos
signed integer type
sufficient for
O/S maximum file size
stream.types
streamsize
signed integer type
represents characters xfered
or buffer sizes
stream.types
Figure 7 — Stream position, offset, and size types [non-normative]
27.2 Iostreams requirements [iostreams.requirements]
27.2.1 Imbue limitations [iostream.limits.imbue]
1No function described in Clause 27 except for ios_base::imbue and basic_filebuf::pubimbue causes any
§ 27.2.1 998
c
ISO/IEC N????
instance of basic_ios::imbue or basic_streambuf::imbue to be called. If any user function called from
a function declared in Clause 27 or as an overriding virtual function of any class declared in Clause 27 calls
imbue, the behavior is undefined.
27.2.2 Positioning type limitations [iostreams.limits.pos]
1The classes of Clause 27 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.
2In the classes of Clause 27, a template formal 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.
27.2.3 Thread safety [iostreams.threadsafety]
1Concurrent access to a stream object (27.8,27.9), stream buffer object (27.6), or C Library stream (27.9.2)
by multiple threads may result in a data race (1.10) unless otherwise specified (27.4). [ Note: Data races
result in undefined behavior (1.10). — end note ]
2If one thread makes a library call athat writes a value to a stream and, as a result, another thread reads
this value from the stream through a library call bsuch that this does not result in a data race, then a’s
write synchronizes with b’s read.
27.3 Forward declarations [iostream.forward]
Header <iosfwd> synopsis
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;
§ 27.3 999
c
ISO/IEC N????
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;
typedef basic_ios<char> ios;
typedef basic_ios<wchar_t> wios;
typedef basic_streambuf<char> streambuf;
typedef basic_istream<char> istream;
typedef basic_ostream<char> ostream;
typedef basic_iostream<char> iostream;
typedef basic_stringbuf<char> stringbuf;
typedef basic_istringstream<char> istringstream;
typedef basic_ostringstream<char> ostringstream;
typedef basic_stringstream<char> stringstream;
typedef basic_filebuf<char> filebuf;
typedef basic_ifstream<char> ifstream;
typedef basic_ofstream<char> ofstream;
typedef basic_fstream<char> fstream;
typedef basic_streambuf<wchar_t> wstreambuf;
typedef basic_istream<wchar_t> wistream;
typedef basic_ostream<wchar_t> wostream;
typedef basic_iostream<wchar_t> wiostream;
typedef basic_stringbuf<wchar_t> wstringbuf;
typedef basic_istringstream<wchar_t> wistringstream;
typedef basic_ostringstream<wchar_t> wostringstream;
typedef basic_stringstream<wchar_t> wstringstream;
typedef basic_filebuf<wchar_t> wfilebuf;
typedef basic_ifstream<wchar_t> wifstream;
typedef basic_ofstream<wchar_t> wofstream;
typedef basic_fstream<wchar_t> wfstream;
template <class state> class fpos;
typedef fpos<char_traits<char>::state_type> streampos;
typedef fpos<char_traits<wchar_t>::state_type> wstreampos;
}
1Default 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.296
296) It is the implementation’s responsibility to implement headers so that including <iosfwd> and other headers does not
§ 27.3 1000
c
ISO/IEC N????
2[Note: 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>.
3The class template specialization basic_streambuf<charT,traits> serves as a base class for class templates
basic_stringbuf and basic_filebuf.
4The class template specialization basic_istream<charT,traits> serves as a base class for class templates
basic_istringstream and basic_ifstream.
5The class template specialization basic_ostream<charT,traits> serves as a base class for class templates
basic_ostringstream and basic_ofstream.
6The class template specialization basic_iostream<charT,traits> serves as a base class for class templates
basic_stringstream and basic_fstream.
7Other typedefs define instances of class templates specialized for char or wchar_t types.
8Specializations of the class template fpos are used for specifying file position information.
9The types streampos and wstreampos are used for positioning streams specialized on char and wchar_t
respectively.
10 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
typedef ... _STATE; // implementation private declaration of stateT
typedef fpos<_STATE> streampos;
template<> struct char_traits<char> {
typedef streampos
pos_type;
}
— end note ]
27.4 Standard iostream objects [iostream.objects]
27.4.1 Overview [iostream.objects.overview]
Header <iostream> synopsis
#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>
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;
}
1The header <iostream> declares objects that associate objects with the standard C streams provided for by
the functions declared in <cstdio> (27.9.2), and includes all the headers necessary to use these objects.
violate the rules about multiple occurrences of default arguments.
§ 27.4.1 1001
c
ISO/IEC N????
2The 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 begins exe-
cution.297 The objects are not destroyed during program execution.298 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. Similarly, the entire program shall behave as if there were at least one instance of ios_base::Init
with static storage duration.
3Mixing operations on corresponding wide- and narrow-character streams follows the same semantics as
mixing such operations on FILEs, as specified in Amendment 1 of the ISO C standard.
4Concurrent access to a synchronized (27.5.3.4) standard iostream object’s formatted and unformatted in-
put (27.7.2.1) and output (27.7.3.1) functions or a standard C stream by multiple threads shall not result
in a data race (1.10). [ Note: Users must still synchronize concurrent use of these objects and streams by
multiple threads if they wish to avoid interleaved characters. — end note ]
27.4.2 Narrow stream objects [narrow.stream.objects]
istream cin;
1The object cin controls input from a stream buffer associated with the object stdin, declared in
<cstdio>.
2After the object cin is initialized, cin.tie() returns &cout. Its state is otherwise the same as required
for basic_ios<char>::init (27.5.5.2).
ostream cout;
3The object cout controls output to a stream buffer associated with the object stdout, declared in
<cstdio> (27.9.2).
ostream cerr;
4The object cerr controls output to a stream buffer associated with the object stderr, declared in
<cstdio> (27.9.2).
5After 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 (27.5.5.2).
ostream clog;
6The object clog controls output to a stream buffer associated with the object stderr, declared in
<cstdio> (27.9.2).
27.4.3 Wide stream objects [wide.stream.objects]
wistream wcin;
1The object wcin controls input from a stream buffer associated with the object stdin, declared in
<cstdio>.
2After the object wcin is initialized, wcin.tie() returns &wcout. Its state is otherwise the same as
required for basic_ios<wchar_t>::init (27.5.5.2).
297) If it is possible for them to do so, implementations are encouraged to initialize the objects earlier than required.
298) Constructors and destructors for static objects can access these objects to read input from stdin or write output to stdout
or stderr.
§ 27.4.3 1002
c
ISO/IEC N????
wostream wcout;
3The object wcout controls output to a stream buffer associated with the object stdout, declared in
<cstdio> (27.9.2).
wostream wcerr;
4The object wcerr controls output to a stream buffer associated with the object stderr, declared in
<cstdio> (27.9.2).
5After 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 (27.5.5.2).
wostream wclog;
6The object wclog controls output to a stream buffer associated with the object stderr, declared in
<cstdio> (27.9.2).
27.5 Iostreams base classes [iostreams.base]
27.5.1 Overview [iostreams.base.overview]
Header <ios> synopsis
#include <iosfwd>
namespace std {
typedef implementation-defined streamoff;
typedef implementation-defined streamsize;
template <class stateT> class fpos;
class ios_base;
template <class charT, class traits = char_traits<charT> >
class basic_ios;
// 27.5.6, 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);
§ 27.5.1 1003
c
ISO/IEC N????
ios_base& nounitbuf (ios_base& str);
// 27.5.6.2 adjustfield:
ios_base& internal (ios_base& str);
ios_base& left (ios_base& str);
ios_base& right (ios_base& str);
// 27.5.6.3 basefield:
ios_base& dec (ios_base& str);
ios_base& hex (ios_base& str);
ios_base& oct (ios_base& str);
// 27.5.6.4 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);
// 27.5.6.5 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);
error_condition make_error_condition(io_errc e);
const error_category& iostream_category();
}
27.5.2 Types [stream.types]
typedef implementation-defined streamoff;
1The 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.299
typedef implementation-defined streamsize;
2The 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.300
27.5.3 Class ios_base [ios.base]
namespace std {
class ios_base {
public:
class failure;
// 27.5.3.1.2 fmtflags
typedef T1 fmtflags;
static constexpr fmtflags boolalpha = unspecified ;
299) Typically long long.
300) 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).
§ 27.5.3 1004
c
ISO/IEC N????
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 ;
// 27.5.3.1.3 iostate
typedef T2 iostate;
static constexpr iostate badbit = unspecified ;
static constexpr iostate eofbit = unspecified ;
static constexpr iostate failbit = unspecified ;
static constexpr iostate goodbit = see below ;
// 27.5.3.1.4 openmode
typedef T3 openmode;
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 ;
// 27.5.3.1.5 seekdir
typedef T4 seekdir;
static constexpr seekdir beg = unspecified ;
static constexpr seekdir cur = unspecified ;
static constexpr seekdir end = unspecified ;
class Init;
// 27.5.3.2 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);
// 27.5.3.3 locales:
§ 27.5.3 1005
c
ISO/IEC N????
locale imbue(const locale& loc);
locale getloc() const;
// 27.5.3.5 storage:
static int xalloc();
long& iword(int index);
void*& pword(int index);
// destructor
virtual ~ios_base();
// 27.5.3.6 callbacks;
enum event { erase_event, imbue_event, copyfmt_event };
typedef void (*event_callback)(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
};
}
1ios_base defines several member types:
a class failure derived from system_error;
a class Init;
three bitmask types, fmtflags,iostate, and openmode;
an enumerated type, seekdir.
2It 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.
3[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 main-
tained 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 ]
§ 27.5.3 1006
c
ISO/IEC N????
27.5.3.1 Types [ios.types]
27.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);
};
}
1The 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.
2When 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);
3Effects: 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);
4Effects: Constructs an object of class failure by constructing the base class with msg and ec.
27.5.3.1.2 Type ios_base::fmtflags [ios::fmtflags]
typedef T1 fmtflags;
1The type fmtflags is a bitmask type (17.5.2.1.3). Setting its elements has the effects indicated in
Table 122.
2Type fmtflags also defines the constants indicated in Table 123.
27.5.3.1.3 Type ios_base::iostate [ios::iostate]
typedef T2 iostate;
1The type iostate is a bitmask type (17.5.2.1.3) that contains the elements indicated in Table 124.
2Type iostate also defines the constant:
goodbit, the value zero.
27.5.3.1.4 Type ios_base::openmode [ios::openmode]
typedef T3 openmode;
1The type openmode is a bitmask type (17.5.2.1.3). It contains the elements indicated in Table 125.
27.5.3.1.5 Type ios_base::seekdir [ios::seekdir]
typedef T4 seekdir;
1The type seekdir is an enumerated type (17.5.2.1.2) that contains the elements indicated in Table 126.
§ 27.5.3.1.5 1007
c
ISO/IEC N????
Table 122 — fmtflags 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 out-
put, 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 gen-
erated output
Table 123 — fmtflags constants
Constant Allowable values
adjustfield left | right | internal
basefield dec | oct | hex
floatfield scientific | fixed
Table 124 — iostate 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.
Table 125 — openmode 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
§ 27.5.3.1.5 1008
c
ISO/IEC N????
Table 126 — seekdir 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
27.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
};
}
1The class Init describes an object whose construction ensures the construction of the eight objects declared
in <iostream> (27.4) that associate file stream buffers with the standard C streams provided for by the
functions declared in <cstdio> (27.9.2).
2For 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();
3Effects: 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();
4Effects: 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().
27.5.3.2 ios_base state functions [fmtflags.state]
fmtflags flags() const;
1Returns: The format control information for both input and output.
fmtflags flags(fmtflags fmtfl);
2Postcondition: fmtfl == flags().
3Returns: The previous value of flags().
fmtflags setf(fmtflags fmtfl);
§ 27.5.3.2 1009
c
ISO/IEC N????
4Effects: Sets fmtfl in flags().
5Returns: The previous value of flags().
fmtflags setf(fmtflags fmtfl, fmtflags mask);
6Effects: Clears mask in flags(), sets fmtfl & mask in flags().
7Returns: The previous value of flags().
void unsetf(fmtflags mask);
8Effects: Clears mask in flags().
streamsize precision() const;
9Returns: The precision to generate on certain output conversions.
streamsize precision(streamsize prec);
10 Postcondition: prec == precision().
11 Returns: The previous value of precision().
streamsize width() const;
12 Returns: The minimum field width (number of characters) to generate on certain output conversions.
streamsize width(streamsize wide);
13 Postcondition: wide == width().
14 Returns: The previous value of width().
27.5.3.3 ios_base functions [ios.base.locales]
locale imbue(const locale& loc);
1Effects: Calls each registered callback pair (fn,index) (27.5.3.6) 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.
2Returns: The previous value of getloc().
3Postcondition: loc == getloc().
locale getloc() const;
4Returns: 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.
§ 27.5.3.3 1010
c
ISO/IEC N????
27.5.3.4 ios_base static members [ios.members.static]
bool sync_with_stdio(bool sync = true);
1Returns: true if the previous state of the standard iostream objects (27.4) was synchronized and
otherwise returns false. The first time it is called, the function returns true.
2Effects: 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.
3When a standard iostream object str is synchronized with a standard stdio stream f, the effect of
inserting a character cby
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 cby
c = fgetc(f);
is the same as the effect of
c = str.rdbuf()->sbumpc(c);
for any sequences of characters; and the effect of pushing back a character cby
ungetc(c, f);
is the same as the effect of
str.rdbuf()->sputbackc(c);
for any sequence of characters.301
27.5.3.5 ios_base storage functions [ios.base.storage]
static int xalloc();
1Returns: index ++.
long& iword(int idx);
2Effects: 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.302 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 fails303 and *this is a base 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).
3Returns: On success iarray[idx]. On failure, a valid long& initialized to 0.
301) 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.
302) 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.
303) for example, because it cannot allocate space.
§ 27.5.3.5 1011
c
ISO/IEC N????
void*& pword(int idx);
4Effects: 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 fails304
and *this is a base 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).
5Returns: On success parray[idx]. On failure a valid void*& initialized to 0.
6Remarks: After a subsequent call to pword(int) for the same object, the earlier return value may no
longer be valid.
27.5.3.6 ios_base callbacks [ios.base.callback]
void register_callback(event_callback fn, int index);
1Effects: Registers the pair (fn,index) such that during calls to imbue() (27.5.3.3), copyfmt(), or
˜ios_base() (27.5.3.7), 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.
2Requires: The function fn shall not throw exceptions.
Remarks: Identical pairs are not merged. A function registered twice will be called twice.
27.5.3.7 ios_base constructors/destructor [ios.base.cons]
ios_base();
1Effects: 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()
2Effects: Destroys an object of class ios_base. Calls each registered callback pair (fn, index) (27.5.3.6)
as (*fn)(erase_event, *this, index) at such time that any ios_base member function called from
within fn has well defined results.
27.5.4 Class template fpos [fpos]
namespace std {
template <class stateT> class fpos {
public:
// 27.5.4.1 Members
stateT state() const;
void state(stateT);
private;
stateT st; // exposition only
};
}
304) for example, because it cannot allocate space.
§ 27.5.4 1012
c
ISO/IEC N????
27.5.4.1 fpos members [fpos.members]
void state(stateT s);
1Effects: Assign sto st.
stateT state() const;
2Returns: Current value of st.
27.5.4.2 fpos requirements [fpos.operations]
1Operations specified in Table 127 are permitted. In that table,
Prefers to an instance of fpos,
pand qrefer to values of type P,
Orefers to type streamoff,
orefers to a value of type streamoff,
sz refers to a value of type streamsize and
irefers to a value of type int.
Table 127 — 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);
Pp=i;
post: 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
2[Note: Every implementation is required to supply overloaded operators on fpos objects to satisfy the
requirements of 27.5.4.2. It is unspecified whether these operators are members of fpos, global operators,
or provided in some other way. — end note ]
3Stream 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.
§ 27.5.4.2 1013
c
ISO/IEC N????
27.5.5 Class template basic_ios [ios]
27.5.5.1 Overview [ios.overview]
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_ios : public ios_base {
public:
// types:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
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);
// 27.5.5.2 Constructor/destructor:
explicit basic_ios(basic_streambuf<charT,traits>* sb);
virtual ~basic_ios();
// 27.5.5.3 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);
§ 27.5.5.1 1014
c
ISO/IEC N????
void move(basic_ios& rhs);
void move(basic_ios&& rhs);
void swap(basic_ios& rhs) noexcept;
void set_rdbuf(basic_streambuf<charT, traits>* sb);
};
}
27.5.5.2 basic_ios constructors [basic.ios.cons]
explicit basic_ios(basic_streambuf<charT,traits>* sb);
1Effects: Constructs an object of class basic_ios, assigning initial values to its member objects by
calling init(sb).
basic_ios();
2Effects: Constructs an object of class basic_ios (27.5.3.7) 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();
3Remarks: The destructor does not destroy rdbuf().
void init(basic_streambuf<charT,traits>* sb);
Postconditions: The postconditions of this function are indicated in Table 128.
Table 128 — basic_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
27.5.5.3 Member functions [basic.ios.members]
basic_ostream<charT,traits>* tie() const;
1Returns: An output sequence that is tied to (synchronized with) the sequence controlled by the stream
buffer.
§ 27.5.5.3 1015
c
ISO/IEC N????
basic_ostream<charT,traits>* tie(basic_ostream<charT,traits>* tiestr);
2Requires: If tiestr is not null, tiestr must not be reachable by traversing the linked list of tied
stream objects starting from tiestr->tie().
3Postcondition: tiestr == tie().
4Returns: The previous value of tie().
basic_streambuf<charT,traits>* rdbuf() const;
5Returns: A pointer to the streambuf associated with the stream.
basic_streambuf<charT,traits>* rdbuf(basic_streambuf<charT,traits>* sb);
6Postcondition: sb == rdbuf().
7Effects: Calls clear().
8Returns: The previous value of rdbuf().
locale imbue(const locale& loc);
9Effects: Calls ios_base::imbue(loc) (27.5.3.3) and if rdbuf()!=0 then rdbuf()->pubimbue(loc)
(27.6.3.2.1).
10 Returns: The prior value of ios_base::imbue().
char narrow(char_type c, char dfault) const;
11 Returns: use_facet< ctype<char_type> >(getloc()).narrow(c,dfault)
char_type widen(char c) const;
12 Returns: use_facet< ctype<char_type> >(getloc()).widen(c)
char_type fill() const;
13 Returns: The character used to pad (fill) an output conversion to the specified field width.
char_type fill(char_type fillch);
14 Postcondition: traits::eq(fillch, fill())
15 Returns: The previous value of fill().
basic_ios& copyfmt(const basic_ios& rhs);
16 Effects: If (this == &rhs) does nothing. Otherwise assigns to the member objects of *this the
corresponding member objects of rhs as follows:
1. calls each registered callback pair (fn, index) as (*fn)(erase_event, *this, index);
2. assigns to the member objects of *this the corresponding member objects of rhs, except that
§ 27.5.5.3 1016
c
ISO/IEC N????
rdstate(),rdbuf(), and exceptions() are left unchanged;
the contents of arrays pointed at by pword and iword are copied, not the pointers them-
selves;305 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. calls each callback pair that was copied from rhs as (*fn)(copyfmt_event, *this, index);
4. calls exceptions(rhs.except()).
17 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.
18 Postconditions: The postconditions of this function are indicated in Table 129.
Table 129 — basic_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()
19 Returns: *this.
void move(basic_ios& rhs);
void move(basic_ios&& rhs);
20 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;
21 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);
305) This suggests an infinite amount of copying, but the implementation can keep track of the maximum element of the arrays
that is non-zero.
§ 27.5.5.3 1017
c
ISO/IEC N????
22 Requires: sb != nullptr.
23 Effects: Associates the basic_streambuf object pointed to by sb with this stream without calling
clear().
24 Postconditions: rdbuf() == sb.
25 Throws: Nothing.
27.5.5.4 basic_ios flags functions [iostate.flags]
explicit operator bool() const;
1Returns: !fail().
bool operator!() const;
2Returns: fail().
iostate rdstate() const;
3Returns: The error state of the stream buffer.
void clear(iostate state = goodbit);
4Postcondition: If rdbuf()!=0 then state == rdstate(); otherwise rdstate()==(state | ios_base
::badbit).
5Effects: If ((state | (rdbuf() ? goodbit : badbit)) & exceptions()) == 0, returns. Oth-
erwise, the function throws an object fail of class basic_ios::failure (27.5.3.1.1), constructed with
implementation-defined argument values.
void setstate(iostate state);
6Effects: Calls clear(rdstate() | state) (which may throw basic_ios::failure (27.5.3.1.1)).
bool good() const;
7Returns: rdstate() == 0
bool eof() const;
8Returns: true if eofbit is set in rdstate().
bool fail() const;
9Returns: true if failbit or badbit is set in rdstate().306
bool bad() const;
10 Returns: true if badbit is set in rdstate().
306) Checking badbit also for fail() is historical practice.
§ 27.5.5.4 1018
c
ISO/IEC N????
iostate exceptions() const;
11 Returns: A mask that determines what elements set in rdstate() cause exceptions to be thrown.
void exceptions(iostate except);
12 Postcondition: except == exceptions().
13 Effects: Calls clear(rdstate()).
27.5.6 ios_base manipulators [std.ios.manip]
27.5.6.1 fmtflags manipulators [fmtflags.manip]
ios_base& boolalpha(ios_base& str);
1Effects: Calls str.setf(ios_base::boolalpha).
2Returns: str.
ios_base& noboolalpha(ios_base& str);
3Effects: Calls str.unsetf(ios_base::boolalpha).
4Returns: str.
ios_base& showbase(ios_base& str);
5Effects: Calls str.setf(ios_base::showbase).
6Returns: str.
ios_base& noshowbase(ios_base& str);
7Effects: Calls str.unsetf(ios_base::showbase).
8Returns: str.
ios_base& showpoint(ios_base& str);
9Effects: Calls str.setf(ios_base::showpoint).
10 Returns: str.
ios_base& noshowpoint(ios_base& str);
11 Effects: Calls str.unsetf(ios_base::showpoint).
12 Returns: str.
ios_base& showpos(ios_base& str);
13 Effects: Calls str.setf(ios_base::showpos).
14 Returns: str.
§ 27.5.6.1 1019
c
ISO/IEC N????
ios_base& noshowpos(ios_base& str);
15 Effects: Calls str.unsetf(ios_base::showpos).
16 Returns: str.
ios_base& skipws(ios_base& str);
17 Effects: Calls str.setf(ios_base::skipws).
18 Returns: str.
ios_base& noskipws(ios_base& str);
19 Effects: Calls str.unsetf(ios_base::skipws).
20 Returns: str.
ios_base& uppercase(ios_base& str);
21 Effects: Calls str.setf(ios_base::uppercase).
22 Returns: str.
ios_base& nouppercase(ios_base& str);
23 Effects: Calls str.unsetf(ios_base::uppercase).
24 Returns: str.
ios_base& unitbuf(ios_base& str);
25 Effects: Calls str.setf(ios_base::unitbuf).
26 Returns: str.
ios_base& nounitbuf(ios_base& str);
27 Effects: Calls str.unsetf(ios_base::unitbuf).
28 Returns: str.
27.5.6.2 adjustfield manipulators [adjustfield.manip]
ios_base& internal(ios_base& str);
1Effects: Calls str.setf(ios_base::internal, ios_base::adjustfield).
2Returns: str.
ios_base& left(ios_base& str);
3Effects: Calls str.setf(ios_base::left, ios_base::adjustfield).
4Returns: str.
ios_base& right(ios_base& str);
5Effects: Calls str.setf(ios_base::right, ios_base::adjustfield).
6Returns: str.
§ 27.5.6.2 1020
c
ISO/IEC N????
27.5.6.3 basefield manipulators [basefield.manip]
ios_base& dec(ios_base& str);
1Effects: Calls str.setf(ios_base::dec, ios_base::basefield).
2Returns: str307.
ios_base& hex(ios_base& str);
3Effects: Calls str.setf(ios_base::hex, ios_base::basefield).
4Returns: str.
ios_base& oct(ios_base& str);
5Effects: Calls str.setf(ios_base::oct, ios_base::basefield).
6Returns: str.
27.5.6.4 floatfield manipulators [floatfield.manip]
ios_base& fixed(ios_base& str);
1Effects: Calls str.setf(ios_base::fixed, ios_base::floatfield).
2Returns: str.
ios_base& scientific(ios_base& str);
3Effects: Calls str.setf(ios_base::scientific, ios_base::floatfield).
4Returns: str.
ios_base& hexfloat(ios_base& str);
5Effects: Calls str.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield).
6Returns: str.
7[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);
8Effects: Calls str.unsetf(ios_base::floatfield).
9Returns: str.
307) 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.
§ 27.5.6.4 1021
c
ISO/IEC N????
27.5.6.5 Error reporting [error.reporting]
error_code make_error_code(io_errc e);
1Returns: error_code(static_cast<int>(e), iostream_category()).
error_condition make_error_condition(io_errc e);
2Returns: error_condition(static_cast<int>(e), iostream_category()).
const error_category& iostream_category();
3Returns: A reference to an object of a type derived from class error_category.
4The 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".
27.6 Stream buffers [stream.buffers]
27.6.1 Overview [stream.buffers.overview]
Header <streambuf> synopsis
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_streambuf;
typedef basic_streambuf<char> streambuf;
typedef basic_streambuf<wchar_t> wstreambuf;
}
1The header <streambuf> defines types that control input from and output to character sequences.
27.6.2 Stream buffer requirements [streambuf.reqts]
1Stream 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.
2Each 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);
§ 27.6.2 1022
c
ISO/IEC N????
the end pointer, or first element address beyond the end of the array (called xend here).
3The 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).
27.6.3 Class template basic_streambuf<charT,traits> [streambuf]
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_streambuf {
public:
// types:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
virtual ~basic_streambuf();
// 27.6.3.2.1 locales:
locale pubimbue(const locale& loc);
locale getloc() const;
// 27.6.3.2.2 buffer and positioning:
basic_streambuf<char_type,traits>*
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:
// 27.6.3.2.3 Get area:
streamsize in_avail();
int_type snextc();
int_type sbumpc();
§ 27.6.3 1023
c
ISO/IEC N????
int_type sgetc();
streamsize sgetn(char_type* s, streamsize n);
// 27.6.3.2.4 Putback:
int_type sputbackc(char_type c);
int_type sungetc();
// 27.6.3.2.5 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);
// 27.6.3.3.2 Get area:
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);
// 27.6.3.3.3 Put area:
char_type* pbase() const;
char_type* pptr() const;
char_type* epptr() const;
void pbump(int n);
void setp(char_type* pbeg, char_type* pend);
// 27.6.3.4 virtual functions:
// 27.6.3.4.1 Locales:
virtual void imbue(const locale& loc);
// 27.6.3.4.2 Buffer management and positioning:
virtual basic_streambuf<char_type,traits>*
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();
// 27.6.3.4.3 Get area:
virtual streamsize showmanyc();
virtual streamsize xsgetn(char_type* s, streamsize n);
virtual int_type underflow();
virtual int_type uflow();
// 27.6.3.4.4 Putback:
virtual int_type pbackfail(int_type c = traits::eof());
// 27.6.3.4.5 Put area:
§ 27.6.3 1024
c
ISO/IEC N????
virtual streamsize xsputn(const char_type* s, streamsize n);
virtual int_type overflow (int_type c = traits::eof());
};
}
1The class template basic_streambuf<charT,traits> serves as an abstract base class for deriving various
stream buffers whose objects each control two character sequences:
a character input sequence;
a character output sequence.
27.6.3.1 basic_streambuf constructors [streambuf.cons]
basic_streambuf();
1Effects: Constructs an object of class basic_streambuf<charT,traits> and initializes:308
all its pointer member objects to null pointers,
the getloc() member to a copy the global locale, locale(), at the time of construction.
2Remarks: 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);
3Effects: Constructs a copy of rhs.
4Postconditions:
eback() == rhs.eback()
gptr() == rhs.gptr()
egptr() == rhs.egptr()
pbase() == rhs.pbase()
pptr() == rhs.pptr()
epptr() == rhs.epptr()
getloc() == rhs.getloc()
~basic_streambuf();
5Effects: None.
27.6.3.2 basic_streambuf public member functions [streambuf.members]
27.6.3.2.1 Locales [streambuf.locales]
locale pubimbue(const locale& loc);
1Postcondition: loc == getloc().
2Effects: Calls imbue(loc).
3Returns: Previous value of getloc().
308) The default constructor is protected for class basic_streambuf to assure that only objects for classes derived from this
class may be constructed.
§ 27.6.3.2.1 1025
c
ISO/IEC N????
locale getloc() const;
4Returns: 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.
27.6.3.2.2 Buffer management and positioning [streambuf.buffer]
basic_streambuf<char_type,traits>* pubsetbuf(char_type* s, streamsize n);
1Returns: setbuf(s, n).
pos_type pubseekoff(off_type off, ios_base::seekdir way,
ios_base::openmode which = ios_base::in | ios_base::out);
2Returns: seekoff(off, way, which).
pos_type pubseekpos(pos_type sp,
ios_base::openmode which = ios_base::in | ios_base::out);
3Returns: seekpos(sp, which).
int pubsync();
4Returns: sync().
27.6.3.2.3 Get area [streambuf.pub.get]
streamsize in_avail();
1Returns: If a read position is available, returns egptr() - gptr(). Otherwise returns showmanyc()
(27.6.3.4.3).
int_type snextc();
2Effects: Calls sbumpc().
3Returns: If that function returns traits::eof(), returns traits::eof(). Otherwise, returns sgetc().
int_type sbumpc();
4Returns: 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();
5Returns: 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);
6Returns: xsgetn(s, n).
§ 27.6.3.2.3 1026
c
ISO/IEC N????
27.6.3.2.4 Putback [streambuf.pub.pback]
int_type sputbackc(char_type c);
1Returns: 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();
2Returns: 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()).
27.6.3.2.5 Put area [streambuf.pub.put]
int_type sputc(char_type c);
1Returns: If the output sequence write position is not available, returns overflow(traits::to_int_-
type(c)). Otherwise, stores cat 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);
2Returns: xsputn(s,n).
27.6.3.3 basic_streambuf protected member functions [streambuf.protected]
27.6.3.3.1 Assignment [streambuf.assign]
basic_streambuf& operator=(const basic_streambuf& rhs);
1Effects: Assigns the data members of rhs to *this.
2Postconditions:
eback() == rhs.eback()
gptr() == rhs.gptr()
egptr() == rhs.egptr()
pbase() == rhs.pbase()
pptr() == rhs.pptr()
epptr() == rhs.epptr()
getloc() == rhs.getloc()
3Returns: *this.
void swap(basic_streambuf& rhs);
4Effects: Swaps the data members of rhs and *this.
§ 27.6.3.3.1 1027
c
ISO/IEC N????
27.6.3.3.2 Get area access [streambuf.get.area]
char_type* eback() const;
1Returns: The beginning pointer for the input sequence.
char_type* gptr() const;
2Returns: The next pointer for the input sequence.
char_type* egptr() const;
3Returns: The end pointer for the input sequence.
void gbump(int n);
4Effects: Adds nto the next pointer for the input sequence.
void setg(char_type* gbeg, char_type* gnext, char_type* gend);
5Postconditions: gbeg == eback(),gnext == gptr(), and gend == egptr().
27.6.3.3.3 Put area access [streambuf.put.area]
char_type* pbase() const;
1Returns: The beginning pointer for the output sequence.
char_type* pptr() const;
2Returns: The next pointer for the output sequence.
char_type* epptr() const;
3Returns: The end pointer for the output sequence.
void pbump(int n);
4Effects: Adds nto the next pointer for the output sequence.
void setp(char_type* pbeg, char_type* pend);
5Postconditions: pbeg == pbase(),pbeg == pptr(), and pend == epptr().
27.6.3.4 basic_streambuf virtual functions [streambuf.virtuals]
27.6.3.4.1 Locales [streambuf.virt.locales]
void imbue(const locale&)
1Effects: Change any translations based on locale.
2Remarks: 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.
3Default behavior: Does nothing.
§ 27.6.3.4.1 1028
c
ISO/IEC N????
27.6.3.4.2 Buffer management and positioning [streambuf.virt.buffer]
basic_streambuf* setbuf(char_type* s, streamsize n);
1Effects: Influences stream buffering in a way that is defined separately for each class derived from
basic_streambuf in this Clause (27.8.2.4,27.9.1.5).
2Default 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);
3Effects: 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 (27.8.2.4,27.9.1.5).
4Default behavior: Returns pos_type(off_type(-1)).
pos_type seekpos(pos_type sp,
ios_base::openmode which
= ios_base::in | ios_base::out);
5Effects: 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 (27.8.2,27.9.1.1).
6Default behavior: Returns pos_type(off_type(-1)).
int sync();
7Effects: 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.
8Returns:-1 on failure. What constitutes failure is determined by each derived class (27.9.1.5).
9Default behavior: Returns zero.
27.6.3.4.3 Get area [streambuf.virt.get]
streamsize showmanyc();309
1Returns: 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.310
2Default behavior: Returns zero.
3Remarks: Uses traits::eof().
streamsize xsgetn(char_type* s, streamsize n);
309) The morphemes of showmanyc are “es-how-many-see”, not “show-manic”.
310) 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.
§ 27.6.3.4.3 1029
c
ISO/IEC N????
4Effects: Assigns up to ncharacters 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 ncharacters have been assigned or a call to sbumpc() would return
traits::eof().
5Returns: The number of characters assigned.311
6Remarks: Uses traits::eof().
int_type underflow();
7Remarks: The public members of basic_streambuf call this virtual function only if gptr() is null or
gptr() >= egptr()
8Returns: traits::to_int_type(c), where cis 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.
9The pending sequence of characters is defined as the concatenation of:
a) If gptr() is non-null, then the egptr() - gptr() characters starting at gptr(), otherwise the
empty sequence.
b) Some sequence (possibly empty) of characters read from the input sequence.
10 The result character is
a) If the pending sequence is non-empty, the first character of the sequence.
b) If the pending sequence is empty then the next character that would be read from the input
sequence.
11 The backup sequence is defined as the concatenation of:
a) If eback() is null then empty,
b) Otherwise the gptr() - eback() characters beginning at eback().
12 Effects: The function sets up the gptr() and egptr() satisfying one of:
a) If the pending sequence is non-empty, egptr() is non-null and egptr() - gptr() characters
starting at gptr() are the characters in the pending sequence
b) If the pending sequence is empty, either gptr() is null or gptr() and egptr() are set to the
same non-null pointer value.
13 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:
a) If the backup sequence contains at least gptr() - eback() characters, then the gptr() - eback()
characters starting at eback() agree with the last gptr() - eback() characters of the backup
sequence.
b) Or the ncharacters starting at gptr() - n agree with the backup sequence (where nis the length
of the backup sequence)
14 Default behavior: Returns traits::eof().
311) Classes derived from basic_streambuf can provide more efficient ways to implement xsgetn() and xsputn() by overriding
these definitions from the base class.
§ 27.6.3.4.3 1030
c
ISO/IEC N????
int_type uflow();
15 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.
16 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.
17 Returns: traits::eof() to indicate failure.
27.6.3.4.4 Putback [streambuf.virt.pback]
int_type pbackfail(int_type c = traits::eof());
1Remarks: 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 cis prepended. Whether the
input sequence is backed up or modified in any other way is unspecified.
2Postcondition: On return, the constraints of gptr(),eback(), and pptr() are the same as for
underflow().
3Returns: 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.
4Returns some value other than traits::eof() to indicate success.
5Default behavior: Returns traits::eof().
27.6.3.4.5 Put area [streambuf.virt.put]
streamsize xsputn(const char_type* s, streamsize n);
1Effects: Writes up to ncharacters 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 ncharacters have been written or a call to sputc(c) would return
traits::eof(). Is is unspecified whether the function calls overflow() when pptr() == epptr()
becomes true or whether it achieves the same effects by other means.
2Returns: The number of characters written.
int_type overflow(int_type c = traits::eof());
3Effects: Consumes some initial subsequence of the characters of the pending sequence. The pending
sequence is defined as the concatenation of
a) if pbase() is null then the empty sequence otherwise, pptr() - pbase() characters beginning
at pbase().
b) if traits::eq_int_type(c,traits::eof()) returns true, then the empty sequence otherwise,
the sequence consisting of c.
§ 27.6.3.4.5 1031
c
ISO/IEC N????
4Remarks: 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.
5Requires: Every overriding definition of this virtual function shall obey the following constraints:
1) The effect of consuming a character on the associated output sequence is specified312
2) Let rbe the number of characters in the pending sequence not consumed. If ris non-zero then
pbase() and pptr() shall be set so that: pptr() - pbase() == r and the rcharacters starting
at pbase() are the associated output stream. In case ris 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) 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.
6Returns: traits::eof() or throws an exception if the function fails.
Otherwise, returns some value other than traits::eof() to indicate success.313
7Default behavior: Returns traits::eof().
27.7 Formatting and manipulators [iostream.format]
27.7.1 Overview [iostream.format.overview]
Header <istream> synopsis
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_istream;
typedef basic_istream<char> istream;
typedef basic_istream<wchar_t> wistream;
template <class charT, class traits = char_traits<charT> >
class basic_iostream;
typedef basic_iostream<char> iostream;
typedef basic_iostream<wchar_t> wiostream;
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);
}
Header <ostream> synopsis
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_ostream;
typedef basic_ostream<char> ostream;
typedef basic_ostream<wchar_t> wostream;
template <class charT, class traits>
312) That is, for each class derived from an instance of basic_streambuf in this Clause (27.8.2,27.9.1.1), a specification of how
consuming a character effects the associated output sequence is given. There is no requirement on a program-defined class.
313) Typically, overflow returns cto indicate success, except when traits::eq_int_type(c,traits::eof()) returns true, in
which case it returns traits::not_eof(c).
§ 27.7.1 1032
c
ISO/IEC N????
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);
}
Header <iomanip> synopsis
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(’\\’));
}
27.7.2 Input streams [input.streams]
1The 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.
27.7.2.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 (27.5.5)):
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
// 27.7.2.1.1 Constructor/destructor:
explicit basic_istream(basic_streambuf<charT,traits>* sb);
§ 27.7.2.1 1033
c
ISO/IEC N????
virtual ~basic_istream();
// 27.7.2.1.3 Prefix/suffix:
class sentry;
// 27.7.2.2 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);
// 27.7.2.3 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();
§ 27.7.2.1 1034
c
ISO/IEC N????
pos_type tellg();
basic_istream<charT,traits>& seekg(pos_type);
basic_istream<charT,traits>& seekg(off_type, ios_base::seekdir);
protected:
basic_istream(const basic_istream& rhs) = delete;
basic_istream(basic_istream&& rhs);
// 27.7.2.1.2 Assign/swap:
basic_istream& operator=(const basic_istream& rhs) = delete;
basic_istream& operator=(basic_istream&& rhs);
void swap(basic_istream& rhs);
};
// 27.7.2.2.3 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*);
}
1The class basic_istream defines a number of member function signatures that assist in reading and inter-
preting input from sequences controlled by a stream buffer.
2Two 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.
3If 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 (27.5.5.4), before returning.
4If 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.
27.7.2.1.1 basic_istream constructors [istream.cons]
explicit basic_istream(basic_streambuf<charT,traits>* sb);
1Effects: Constructs an object of class basic_istream, assigning initial values to the base class by
calling basic_ios::init(sb) (27.5.5.2).
§ 27.7.2.1.1 1035
c
ISO/IEC N????
2Postcondition: gcount() == 0
basic_istream(basic_istream&& rhs);
3Effects: 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();
4Effects: Destroys an object of class basic_istream.
5Remarks: Does not perform any operations of rdbuf().
27.7.2.1.2 Class basic_istream assign and swap [istream.assign]
basic_istream& operator=(basic_istream&& rhs);
1Effects: swap(rhs);.
2Returns: *this.
void swap(basic_istream& rhs);
3Effects: Calls basic_ios<charT, traits>::swap(rhs). Exchanges the values returned by gcount()
and rhs.gcount().
27.7.2.1.3 Class basic_istream::sentry [istream::sentry]
namespace std {
template <class charT,class traits = char_traits<charT> >
class basic_istream<charT,traits>::sentry {
typedef traits traits_type;
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;
};
}
1The 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);
2Effects: 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
§ 27.7.2.1.3 1036
c
ISO/IEC N????
sentry object is destroyed, the call to flush may be eliminated entirely.314 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 cis 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).
3Remarks: 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.
4To decide if the character cis 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)
// cis a whitespace character.
5If, 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 (27.5.5.4))315
~sentry();
6Effects: None.
explicit operator bool() const;
7Effects: Returns ok_.
27.7.2.2 Formatted input functions [istream.formatted]
27.7.2.2.1 Common requirements [istream.formatted.reqmts]
1Each 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 on316 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.
27.7.2.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);
314) 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.
315) The sentry constructor and destructor can also perform additional implementation-dependent operations.
316) This is done without causing an ios::failure to be thrown.
§ 27.7.2.2.2 1037
c
ISO/IEC N????
1As in the case of the inserters, these extractors depend on the locale’s num_get<> (22.4.2.1) object
to perform parsing the input stream data. These extractors behave as formatted input functions (as
described in 27.7.2.2.1). After a sentry object is constructed, the conversion occurs as if performed by
the following code fragment:
typedef num_get< charT,istreambuf_iterator<charT,traits> > numget;
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);
2The conversion occurs as if performed by the following code fragment (using the same notation as for
the preceding code fragment):
typedef num_get<charT,istreambuf_iterator<charT,traits> > numget;
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);
3The conversion occurs as if performed by the following code fragment (using the same notation as for
the preceding code fragment):
typedef num_get<charT,istreambuf_iterator<charT,traits> > numget;
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);
§ 27.7.2.2.2 1038
c
ISO/IEC N????
27.7.2.2.3 basic_istream::operator>> [istream::extractors]
basic_istream<charT,traits>& operator>>
(basic_istream<charT,traits>& (*pf)(basic_istream<charT,traits>&))
1Effects: None. This extractor does not behave as a formatted input function (as described in 27.7.2.2.1.)
2Returns: pf(*this).317
basic_istream<charT,traits>& operator>>
(basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&));
3Effects: Calls pf(*this). This extractor does not behave as a formatted input function (as described
in 27.7.2.2.1).
4Returns: *this.
basic_istream<charT,traits>& operator>>
(ios_base& (*pf)(ios_base&));
5Effects: Calls pf(*this).318 This extractor does not behave as a formatted input function (as de-
scribed in 27.7.2.2.1).
6Returns: *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);
7Effects: Behaves like a formatted input member (as described in 27.7.2.2.1) 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, nis width(). Otherwise
nis the number of elements of the largest array of char_type that can store a terminating charT().
nis the maximum number of characters stored.
8Characters are extracted and stored until any of the following occurs:
n-1 characters are stored;
end of file occurs on the input sequence;
ct.is(ct.space,c) is true for the next available input character c, where ct is use_facet<ctype<
charT> >(in.getloc()).
9operator>> 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).
10 If the function extracted no characters, it calls setstate(failbit), which may throw ios_base::
failure (27.5.5.4).
11 Returns: in.
317) See, for example, the function signature ws(basic_istream&) (27.7.2.4).
318) See, for example, the function signature dec(ios_base&) (27.5.6.3).
§ 27.7.2.2.3 1039
c
ISO/IEC N????
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);
12 Effects: Behaves like a formatted input member (as described in 27.7.2.2.1) 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).
13 Returns: in.
basic_istream<charT,traits>& operator>>
(basic_streambuf<charT,traits>* sb);
14 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). If sb is null,
calls setstate(failbit), which may throw ios_base::failure (27.5.5.4). 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).
15 If the function inserts no characters, it calls setstate(failbit), which may throw ios_base::
failure (27.5.5.4). If it inserted no characters because it caught an exception thrown while extracting
characters from *this and failbit is on in exceptions() (27.5.5.4), then the caught exception is
rethrown.
16 Returns: *this.
27.7.2.3 Unformatted input functions [istream.unformatted]
1Each 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 non-zero 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 on319 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;
319) This is done without causing an ios::failure to be thrown.
§ 27.7.2.3 1040
c
ISO/IEC N????
2Effects: None. This member function does not behave as an unformatted input function (as described
in 27.7.2.3, paragraph 1).
3Returns: The number of characters extracted by the last unformatted input member function called
for the object.
int_type get();
4Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). 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 (27.5.5.4),
5Returns: cif available, otherwise traits::eof().
basic_istream<charT,traits>& get(char_type& c);
6Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). After
constructing a sentry object, extracts a character, if one is available, and assigns it to c.320 Otherwise,
the function calls setstate(failbit) (which may throw ios_base::failure (27.5.5.4)).
7Returns: *this.
basic_istream<charT,traits>& get(char_type* s, streamsize n,
char_type delim );
8Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). After
constructing a sentry object, extracts characters and stores them into successive locations of an array
whose first element is designated by s.321 Characters are extracted and stored until any of the following
occurs:
nis less than one or n-1characters 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 cis not extracted).
9If the function stores no characters, it calls setstate(failbit) (which may throw ios_base::
failure (27.5.5.4)). In any case, if nis greater than zero it then stores a null character into the
next successive location of the array.
10 Returns: *this.
basic_istream<charT,traits>& get(char_type* s, streamsize n)
11 Effects: Calls get(s,n,widen(’\n’))
12 Returns: Value returned by the call.
basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& sb,
char_type delim );
320) Note that this function is not overloaded on types signed char and unsigned char.
321) Note that this function is not overloaded on types signed char and unsigned char.
§ 27.7.2.3 1041
c
ISO/IEC N????
13 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). 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 cis not extracted);
an exception occurs (in which case, the exception is caught but not rethrown).
14 If the function inserts no characters, it calls setstate(failbit), which may throw ios_base::
failure (27.5.5.4).
15 Returns: *this.
basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& sb);
16 Effects: Calls get(sb, widen(’\n’))
17 Returns: Value returned by the call.
basic_istream<charT,traits>& getline(char_type* s, streamsize n,
char_type delim);
18 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). After
constructing a sentry object, extracts characters and stores them into successive locations of an array
whose first element is designated by s.322 Characters are extracted and stored until one of the following
occurs:
1. end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit));
2. traits::eq(c, delim) for the next available input character c(in which case the input character
is extracted but not stored);323
3. nis less than one or n-1characters are stored (in which case the function calls setstate(
failbit)).
19 These conditions are tested in the order shown.324
20 If the function extracts no characters, it calls setstate(failbit) (which may throw ios_base::
failure (27.5.5.4)).325
21 In any case, if nis greater than zero, it then stores a null character (using charT()) into the next
successive location of the array.
22 Returns: *this.
23 [Example:
322) Note that this function is not overloaded on types signed char and unsigned char.
323) Since the final input character is “extracted,” it is counted in the gcount(), even though it is not stored.
324) This allows an input line which exactly fills the buffer, without setting failbit. This is different behavior than the
historical AT&T implementation.
325) This implies an empty input line will not cause failbit to be set.
§ 27.7.2.3 1042
c
ISO/IEC N????
#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);
24 Returns: getline(s,n,widen(’\n’))
basic_istream<charT,traits>&
ignore(streamsize n = 1, int_type delim = traits::eof());
25 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). After
constructing a sentry object, extracts characters and discards them. Characters are extracted until
any of the following occurs:
if n != numeric_limits<streamsize>::max() (18.3.2), ncharacters are extracted
end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit),
which may throw ios_base::failure (27.5.5.4));
traits::eq_int_type(traits::to_int_type(c), delim) for the next available input charac-
ter c(in which case cis extracted).
26 Remarks: The last condition will never occur if traits::eq_int_type(delim, traits::eof()).
27 Returns: *this.
int_type peek();
28 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). After
constructing a sentry object, reads but does not extract the current input character.
29 Returns: traits::eof() if good() is false. Otherwise, returns rdbuf()->sgetc().
§ 27.7.2.3 1043
c
ISO/IEC N????
basic_istream<charT,traits>& read(char_type* s, streamsize n);
30 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). 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.326 Characters are extracted and stored until either of the following occurs:
ncharacters 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 (27.5.5.4)).
31 Returns: *this.
streamsize readsome(char_type* s, streamsize n);
32 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1). 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 (27.5.5.4)), and extracts no characters;
If rdbuf()->in_avail() == 0, extracts no characters
If rdbuf()->in_avail() > 0, extracts min(rdbuf()->in_avail(),n)).
33 Returns: The number of characters extracted.
basic_istream<charT,traits>& putback(char_type c);
34 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), 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 (27.5.5.4)). [ Note: This function extracts no characters, so the value returned by
the next call to gcount() is 0. — end note ]
35 Returns: *this.
basic_istream<charT,traits>& unget();
36 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), 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 (27.5.5.4)). [ Note: This function extracts no characters, so the value returned by
the next call to gcount() is 0. — end note ]
37 Returns: *this.
int sync();
326) Note that this function is not overloaded on types signed char and unsigned char.
§ 27.7.2.3 1044
c
ISO/IEC N????
38 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), 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 (27.5.5.4), and returns -1. Otherwise, returns zero.
pos_type tellg();
39 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), except
that it does not count the number of characters extracted and does not affect the value returned by
subsequent calls to gcount().
40 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);
41 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), 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).
42 Returns: *this.
basic_istream<charT,traits>& seekg(off_type off, ios_base::seekdir dir);
43 Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), 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 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).
44 Returns: *this.
27.7.2.4 Standard basic_istream manipulators [istream.manip]
namespace std {
template <class charT, class traits>
basic_istream<charT,traits>& ws(basic_istream<charT,traits>& is);
}
1Effects: Behaves as an unformatted input function (as described in 27.7.2.3, paragraph 1), 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 cis whitespace or until there are no more characters in the sequence. Whitespace
characters are distinguished with the same criterion as used by sentry::sentry (27.7.2.1.3). If ws
stops extracting characters because there are no more available it sets eofbit, but not failbit.
2Returns: is.
§ 27.7.2.4 1045
c
ISO/IEC N????
27.7.2.5 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:
// types:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
// constructor/destructor
explicit basic_iostream(basic_streambuf<charT,traits>* sb);
virtual ~basic_iostream();
protected:
basic_iostream(const basic_iostream& rhs) = delete;
basic_iostream(basic_iostream&& rhs);
// assign/swap
basic_iostream& operator=(const basic_iostream& rhs) = delete;
basic_iostream& operator=(basic_iostream&& rhs);
void swap(basic_iostream& rhs);
};
}
1The class basic_iostream inherits a number of functions that allow reading input and writing output to
sequences controlled by a stream buffer.
27.7.2.5.1 basic_iostream constructors [iostream.cons]
explicit basic_iostream(basic_streambuf<charT,traits>* sb);
1Effects: Constructs an object of class basic_iostream, assigning initial values to the base classes
by calling basic_istream<charT,traits>(sb) (27.7.2.1) and basic_ostream<charT,traits>(sb)
(27.7.3.1)
2Postcondition: rdbuf()==sb and gcount()==0.
basic_iostream(basic_iostream&& rhs);
3Effects: Move constructs from the rvalue rhs by constructing the basic_istream base class with
move(rhs).
27.7.2.5.2 basic_iostream destructor [iostream.dest]
virtual ~basic_iostream();
1Effects: Destroys an object of class basic_iostream.
2Remarks: Does not perform any operations on rdbuf().
27.7.2.5.3 basic_iostream assign and swap [iostream.assign]
basic_iostream& operator=(basic_iostream&& rhs);
§ 27.7.2.5.3 1046
c
ISO/IEC N????
1Effects: swap(rhs).
void swap(basic_iostream& rhs);
2Effects: Calls basic_istream<charT, traits>::swap(rhs).
27.7.2.6 Rvalue stream extraction [istream.rvalue]
template <class charT, class traits, class T>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>&& is, T& x);
1Effects: is >>x
2Returns: is
27.7.3 Output streams [output.streams]
1The 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.
27.7.3.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 (27.5.5)):
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
// 27.7.3.2 Constructor/destructor:
explicit basic_ostream(basic_streambuf<char_type,traits>* sb);
virtual ~basic_ostream();
// 27.7.3.4 Prefix/suffix:
class sentry;
// 27.7.3.6 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);
§ 27.7.3.1 1047
c
ISO/IEC 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<<(
basic_streambuf<char_type,traits>* sb);
// 27.7.3.7 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();
// 27.7.3.5 seeks:
pos_type tellp();
basic_ostream<charT,traits>& seekp(pos_type);
basic_ostream<charT,traits>& seekp(off_type, ios_base::seekdir);
protected:
basic_ostream(const basic_ostream& rhs) = delete;
basic_ostream(basic_ostream&& rhs);
// 27.7.3.3 Assign/swap
basic_ostream& operator=(const basic_ostream& rhs) = delete;
basic_ostream& operator=(basic_ostream&& rhs);
void swap(basic_ostream& rhs);
};
// 27.7.3.6.4 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);
// signed and unsigned
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>
§ 27.7.3.1 1048
c
ISO/IEC N????
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&,
const char*);
// signed and unsigned
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*);
}
1The class basic_ostream defines a number of member function signatures that assist in formatting and
writing output to output sequences controlled by a stream buffer.
2Two 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().
3If 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.
27.7.3.2 basic_ostream constructors [ostream.cons]
explicit basic_ostream(basic_streambuf<charT,traits>* sb);
1Effects: Constructs an object of class basic_ostream, assigning initial values to the base class by
calling basic_ios<charT,traits>::init(sb) (27.5.5.2).
2Postcondition: rdbuf() == sb.
virtual ~basic_ostream();
3Effects: Destroys an object of class basic_ostream.
4Remarks: Does not perform any operations on rdbuf().
basic_ostream(basic_ostream&& rhs);
5Effects: 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.
27.7.3.3 Class basic_ostream assign and swap [ostream.assign]
basic_ostream& operator=(basic_ostream&& rhs);
1Effects: swap(rhs).
2Returns: *this.
void swap(basic_ostream& rhs);
3Effects: Calls basic_ios<charT, traits>::swap(rhs).
§ 27.7.3.3 1049
c
ISO/IEC N????
27.7.3.4 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;
};
}
1The class sentry defines a class that is responsible for doing exception safe prefix and suffix operations.
explicit sentry(basic_ostream<charT,traits>& os);
2If os.good() is nonzero, prepares for formatted or unformatted output. If os.tie() is not a null
pointer, calls os.tie()->flush().327
3If, 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 (27.5.5.4))328
~sentry();
4If ((os.flags() & ios_base::unitbuf) && !uncaught_exception() && os.good()) is true, calls
os.rdbuf()->pubsync(). If that function returns -1, sets badbit in os.rdstate() without propa-
gating an exception.
explicit operator bool() const;
5Effects: Returns ok_.
27.7.3.5 basic_ostream seek members [ostream.seeks]
1Each seek member function begins execution by constructing an object of class sentry. It returns by
destroying the sentry object.
pos_type tellp();
2Returns: 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);
3Effects: If fail() != true, executes rdbuf()->pubseekpos(pos, ios_base::out). In case of fail-
ure, the function calls setstate(failbit) (which may throw ios_base::failure).
4Returns: *this.
basic_ostream<charT,traits>& seekp(off_type off, ios_base::seekdir dir);
327) The call os.tie()->flush() does not necessarily occur if the function can determine that no synchronization is necessary.
328) The sentry constructor and destructor can also perform additional implementation-dependent operations.
§ 27.7.3.5 1050
c
ISO/IEC N????
5Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir, ios_base::out).
6Returns: *this.
27.7.3.6 Formatted output functions [ostream.formatted]
27.7.3.6.1 Common requirements [ostream.formatted.reqmts]
1Each 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 on329
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.
2The descriptions of the individual formatted output functions describe how they perform output and do not
mention the sentry object.
3If 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.
27.7.3.6.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);
1Effects: The classes num_get<> and num_put<> handle locale-dependent numeric formatting and pars-
ing. 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
329) without causing an ios::failure to be thrown.
§ 27.7.3.6.2 1051
c
ISO/IEC N????
? 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 frag-
ment:
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();
2The 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 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.
3Returns: *this.
27.7.3.6.3 basic_ostream::operator<< [ostream.inserters]
basic_ostream<charT,traits>& operator<<
(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&))
1Effects: None. Does not behave as a formatted output function (as described in 27.7.3.6.1).
2Returns: pf(*this).330
basic_ostream<charT,traits>& operator<<
(basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&))
3Effects: Calls pf(*this). This inserter does not behave as a formatted output function (as described
in 27.7.3.6.1).
4Returns: *this.331
330) See, for example, the function signature endl(basic_ostream&) (27.7.3.8).
331) See, for example, the function signature dec(ios_base&) (27.5.6.3).
§ 27.7.3.6.3 1052
c
ISO/IEC N????
basic_ostream<charT,traits>& operator<<
(ios_base& (*pf)(ios_base&))
5Effects: Calls pf(*this). This inserter does not behave as a formatted output function (as described
in 27.7.3.6.1).
6Returns: *this.
basic_ostream<charT,traits>& operator<<
(basic_streambuf<charT,traits>* sb);
7Effects: Behaves as an unformatted output function (as described in 27.7.3.7, paragraph 1). Af-
ter the sentry object is constructed, if sb is null calls setstate(badbit) (which may throw ios_-
base::failure).
8Gets 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.
9If the function inserts no characters, it calls setstate(failbit) (which may throw ios_base::
failure (27.5.5.4)). 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.
10 Returns: *this.
27.7.3.6.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);
1Effects: Behaves as a formatted output function ( 27.7.3.6.1) of out. Constructs a character sequence
seq. If chas 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 27.7.3.6.1.
Inserts seq into out. Calls os.width(0).
2Returns: out.
§ 27.7.3.6.4 1053
c
ISO/IEC N????
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);
3Requires: sshall not be a null pointer.
4Effects: Behaves like a formatted inserter (as described in 27.7.3.6.1) of out. Creates a character
sequence seq of ncharacters starting at s, each widened using out.widen() (27.5.5.3), where nis 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*,
std::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 27.7.3.6.1. Inserts seq into out. Calls width(0).
5Returns: out.
27.7.3.7 Unformatted output functions [ostream.unformatted]
1Each 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 on332 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);
2Effects: Behaves as an unformatted output function (as described in 27.7.3.7, paragraph 1). After
constructing a sentry object, inserts the character c, if possible.333
3Otherwise, calls setstate(badbit) (which may throw ios_base::failure (27.5.5.4)).
4Returns: *this.
basic_ostream& write(const char_type* s, streamsize n);
5Effects: Behaves as an unformatted output function (as described in 27.7.3.7, paragraph 1). After
constructing a sentry object, obtains characters to insert from successive locations of an array whose
first element is designated by s.334 Characters are inserted until either of the following occurs:
332) without causing an ios::failure to be thrown.
333) Note that this function is not overloaded on types signed char and unsigned char.
334) Note that this function is not overloaded on types signed char and unsigned char.
§ 27.7.3.7 1054
c
ISO/IEC N????
ncharacters are inserted;
inserting in the output sequence fails (in which case the function calls setstate(badbit), which
may throw ios_base::failure (27.5.5.4)).
6Returns: *this.
basic_ostream& flush();
7Effects: Behaves as an unformatted output function (as described in 27.7.3.6.1, paragraph 1). 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 (27.5.5.4)). Otherwise, if the sentry object
returns false, does nothing.
8Returns: *this.
27.7.3.8 Standard basic_ostream manipulators [ostream.manip]
namespace std {
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
}
1Effects: Calls os.put(os.widen(’\n’)), then os.flush().
2Returns: os.
namespace std {
template <class charT, class traits>
basic_ostream<charT,traits>& ends(basic_ostream<charT,traits>& os);
}
3Effects: Inserts a null character into the output sequence: calls os.put(charT()).
4Returns: os.
namespace std {
template <class charT, class traits>
basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os);
}
5Effects: Calls os.flush().
6Returns: os.
27.7.3.9 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);
1Effects: os << x
2Returns: os
§ 27.7.3.9 1055
c
ISO/IEC N????
27.7.4 Standard manipulators [std.manip]
1The 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);
2Returns: 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 fis defined as:335
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);
3Returns: 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 fis 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);
4Returns: 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 fis 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);
}
335) 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).
§ 27.7.4 1056
c
ISO/IEC N????
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);
5Returns: An object of unspecified type such that if out is an object of type basic_ostream<charT,
traits> and chas type charT then the expression out << setfill(c) behaves as if it called f(out,
c), where the function fis 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);
6Returns: 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 fis 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);
7Returns: 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 fis 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.
§ 27.7.4 1057
c
ISO/IEC N????
27.7.5 Extended manipulators [ext.manip]
1The 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);
2Requires: The type moneyT shall be either long double or a specialization of the basic_string
template (Clause 21).
3Effects: The expression in >>get_money(mon, intl) described below behaves as a formatted input
function (27.7.2.2.1).
4Returns: 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 fis defined as:
template <class charT, class traits, class moneyT>
void f(basic_ios<charT, traits>& str, moneyT& mon, bool intl) {
typedef istreambuf_iterator<charT, traits> Iter;
typedef money_get<charT, Iter> MoneyGet;
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);
5Requires: The type moneyT shall be either long double or a specialization of the basic_string
template (Clause 21).
6Returns: 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 input function
that calls f(out, mon, intl), where the function fis defined as:
template <class charT, class traits, class moneyT>
void f(basic_ios<charT, traits>& str, const moneyT& mon, bool intl) {
typedef ostreambuf_iterator<charT, traits> Iter;
typedef money_put<charT, Iter> MoneyPut;
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.
§ 27.7.5 1058
c
ISO/IEC N????
template <class charT> unspecified get_time(struct tm* tmb, const charT* fmt);
7Requires: 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.
8Returns: 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 fis defined as:
template <class charT, class traits>
void f(basic_ios<charT, traits>& str, struct tm* tmb, const charT* fmt) {
typedef istreambuf_iterator<charT, traits> Iter;
typedef time_get<charT, Iter> TimeGet;
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);
9Requires: 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.
10 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 fis defined as:
template <class charT, class traits>
void f(basic_ios<charT, traits>& str, const struct tm* tmb, const charT* fmt) {
typedef ostreambuf_iterator<charT, traits> Iter;
typedef time_put<charT, Iter> TimePut;
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.
§ 27.7.5 1059
c
ISO/IEC N????
27.7.6 Quoted manipulators [quoted.manip]
1[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(’\\’));
2Returns: An object of unspecified type such that if out is an instance of basic_ostream with member
type char_type the same as charT, then the expression out << quoted(s, delim, escape) behaves
as if it inserts the following characters into out using character inserter function templates (27.7.3.6.4),
which may throw ios_base::failure (27.5.3.1.1):
delim.
Each character in s. If the character to be output is equal to escape or delim, as determined by
operator==, first output escape.
delim.
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(’\\’));
3Returns: An object of unspecified type such that:
If in is an instance of basic_istream with member type char_type the same as charT, then the
expression in >> quoted(s, delim, escape) behaves as if it extracts the following characters
from in using basic_istream::operator>> (27.7.2.2.3) which may throw ios_base::failure
(27.5.3.1.1):
If the first character extracted is equal to delim, as determined by operator==, 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 type char_type the same as charT, 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.
§ 27.7.6 1060
c
ISO/IEC N????
27.8 String-based streams [string.streams]
27.8.1 Overview [string.streams.overview]
1The header <sstream> defines four class templates and eight types that associate stream buffers with objects
of class basic_string, as described in 21.3.
Header <sstream> synopsis
namespace std {
template <class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> >
class basic_stringbuf;
typedef basic_stringbuf<char> stringbuf;
typedef basic_stringbuf<wchar_t> wstringbuf;
template <class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> >
class basic_istringstream;
typedef basic_istringstream<char> istringstream;
typedef basic_istringstream<wchar_t> wistringstream;
template <class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> >
class basic_ostringstream;
typedef basic_ostringstream<char> ostringstream;
typedef basic_ostringstream<wchar_t> wostringstream;
template <class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> >
class basic_stringstream;
typedef basic_stringstream<char> stringstream;
typedef basic_stringstream<wchar_t> wstringstream;
}
27.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:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
typedef Allocator allocator_type;
// 27.8.2.1 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;
§ 27.8.2 1061
c
ISO/IEC N????
basic_stringbuf(basic_stringbuf&& rhs);
// 27.8.2.2 Assign and swap:
basic_stringbuf& operator=(const basic_stringbuf& rhs) = delete;
basic_stringbuf& operator=(basic_stringbuf&& rhs);
void swap(basic_stringbuf& rhs);
// 27.8.2.3 Get and set:
basic_string<charT,traits,Allocator> str() const;
void str(const basic_string<charT,traits,Allocator>& s);
protected:
// 27.8.2.4 Overridden virtual functions:
virtual int_type underflow();
virtual int_type pbackfail(int_type c = traits::eof());
virtual int_type overflow (int_type c = traits::eof());
virtual basic_streambuf<charT,traits>* setbuf(charT*, streamsize);
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);
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);
}
1The 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.
2For 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.
27.8.2.1 basic_stringbuf constructors [stringbuf.cons]
explicit basic_stringbuf(ios_base::openmode which =
ios_base::in | ios_base::out);
1Effects: Constructs an object of class basic_stringbuf, initializing the base class with basic_-
streambuf() (27.6.3.1), and initializing mode with which.
2Postcondition: str() == "".
explicit basic_stringbuf(const basic_string<charT,traits,Allocator>& s,
ios_base::openmode which = ios_base::in | ios_base::out);
3Effects: Constructs an object of class basic_stringbuf, initializing the base class with basic_-
streambuf() (27.6.3.1), and initializing mode with which. Then calls str(s).
§ 27.8.2.1 1062
c
ISO/IEC N????
basic_stringbuf(basic_stringbuf&& rhs);
4Effects: 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.
5Postconditions: 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()
27.8.2.2 Assign and swap [stringbuf.assign]
basic_stringbuf& operator=(basic_stringbuf&& rhs);
1Effects: After the move assignment *this has the observable state it would have had if it had been
move constructed from rhs (see 27.8.2.1).
2Returns: *this.
void swap(basic_stringbuf& rhs);
3Effects: 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);
4Effects: x.swap(y).
27.8.2.3 Member functions [stringbuf.members]
basic_string<charT,traits,Allocator> str() const;
1Returns: Abasic_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 true 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,
§ 27.8.2.3 1063
c
ISO/IEC N????
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);
2Effects: Copies the content of sinto the basic_stringbuf underlying character sequence and initializes
the input and output sequences according to mode.
3Postconditions: If mode & ios_base::out is true, pbase() points to the first underlying character
and epptr() >= pbase() + s.size() holds; in addition, if mode & ios_base::ate is true, pptr()
== pbase() + s.size() holds, otherwise pptr() == pbase() is true. If mode & ios_base::in is
true, eback() points to the first underlying character, and both gptr() == eback() and egptr() ==
eback() + s.size() hold.
27.8.2.4 Overridden virtual functions [stringbuf.virtuals]
int_type underflow();
1Returns: 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());
2Effects: Puts back the character designated by cto 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 put-
back 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 put-
back position available, and if mode & ios_base::out is nonzero, assigns cto *--gptr().
Returns: c.
If traits::eq_int_type(c,traits::eof()) returns true and if the input sequence has a put-
back position available, assigns gptr() - 1 to gptr().
Returns: traits::not_eof(c).
3Returns: traits::eof() to indicate failure.
4Remarks: 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());
5Effects: Appends the character designated by cto 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.
§ 27.8.2.4 1064
c
ISO/IEC N????
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().
6Remarks: The function can alter the number of write positions available as a result of any call.
7Returns: traits::eof() to indicate failure.
8The 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);
9Effects: Alters the stream position within one of the controlled sequences, if possible, as indicated in
Table 130.
Table 130 — seekoff 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.
10 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 131.
Table 131 — newoff values
Condition newoff Value
way == ios_base::beg 0
way == ios_base::cur the next pointer minus the begin-
ning pointer (xnext - xbeg).
way == ios_base::end the high mark pointer minus the
beginning pointer (high_mark -
xbeg).
§ 27.8.2.4 1065
c
ISO/IEC N????
11 If (newoff + off) < 0, or if newoff + off refers to an uninitialized character (as defined in 27.8.2.3
paragraph 1), the positioning operation fails. Otherwise, the function assigns xbeg + newoff + off
to the next pointer xnext.
12 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);
13 Effects: Equivalent to seekoff(off_type(sp), ios_base::beg, which).
14 Returns: sp to indicate success, or pos_type(off_type(-1)) to indicate failure.
basic_streambuf<charT,traits>* setbuf(charT* s, streamsize n);
15 Effects: implementation-defined, except that setbuf(0,0) has no effect.
16 Returns: this.
27.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:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
typedef Allocator allocator_type;
// 27.8.3.1 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);
// 27.8.3.2 Assign and swap:
basic_istringstream& operator=(const basic_istringstream& rhs) = delete;
basic_istringstream& operator=(basic_istringstream&& rhs);
void swap(basic_istringstream& rhs);
// 27.8.3.3 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
§ 27.8.3 1066
c
ISO/IEC N????
};
template <class charT, class traits, class Allocator>
void swap(basic_istringstream<charT, traits, Allocator>& x,
basic_istringstream<charT, traits, Allocator>& y);
}
1The 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.
27.8.3.1 basic_istringstream constructors [istringstream.cons]
explicit basic_istringstream(ios_base::openmode which = ios_base::in);
1Effects: 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, Alloca-
tor>(which | ios_base::in)) (27.8.2.1).
explicit basic_istringstream(
const basic_string<charT, traits, Allocator>& str,
ios_base::openmode which = ios_base::in);
2Effects: 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, Alloca-
tor>(str, which | ios_base::in)) (27.8.2.1).
basic_istringstream(basic_istringstream&& rhs);
3Effects: 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.
27.8.3.2 Assign and swap [istringstream.assign]
basic_istringstream& operator=(basic_istringstream&& rhs);
1Effects: Move assigns the base and members of *this from the base and corresponding members of
rhs.
2Returns: *this.
void swap(basic_istringstream& rhs);
3Effects: 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);
4Effects: x.swap(y).
§ 27.8.3.2 1067
c
ISO/IEC N????
27.8.3.3 Member functions [istringstream.members]
basic_stringbuf<charT,traits,Allocator>* rdbuf() const;
1Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).
basic_string<charT,traits,Allocator> str() const;
2Returns: rdbuf()->str().
void str(const basic_string<charT,traits,Allocator>& s);
3Effects: Calls rdbuf()->str(s).
27.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:
// types:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
typedef Allocator allocator_type;
// 27.8.4.1 Constructors/destructor:
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);
// 27.8.4.2 Assign/swap:
basic_ostringstream& operator=(const basic_ostringstream& rhs) = delete;
basic_ostringstream& operator=(basic_ostringstream&& rhs);
void swap(basic_ostringstream& rhs);
// 27.8.4.3 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);
}
§ 27.8.4 1068
c
ISO/IEC N????
1The 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.
27.8.4.1 basic_ostringstream constructors [ostringstream.cons]
explicit basic_ostringstream(ios_base::openmode which = ios_base::out);
1Effects: 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)) (27.8.2.1).
explicit basic_ostringstream(
const basic_string<charT,traits,Allocator>& str,
ios_base::openmode which = ios_base::out);
2Effects: 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, Alloca-
tor>(str, which | ios_base::out)) (27.8.2.1).
basic_ostringstream(basic_ostringstream&& rhs);
3Effects: 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.
27.8.4.2 Assign and swap [ostringstream.assign]
basic_ostringstream& operator=(basic_ostringstream&& rhs);
1Effects: Move assigns the base and members of *this from the base and corresponding members of
rhs.
2Returns: *this.
void swap(basic_ostringstream& rhs);
3Effects: 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);
4Effects: x.swap(y).
27.8.4.3 Member functions [ostringstream.members]
basic_stringbuf<charT,traits,Allocator>* rdbuf() const;
1Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).
basic_string<charT,traits,Allocator> str() const;
§ 27.8.4.3 1069
c
ISO/IEC N????
2Returns: rdbuf()->str().
void str(const basic_string<charT,traits,Allocator>& s);
3Effects: Calls rdbuf()->str(s).
27.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:
// types:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
typedef Allocator allocator_type;
// constructors/destructor
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);
// 27.8.6.1 Assign/swap:
basic_stringstream& operator=(const basic_stringstream& rhs) = delete;
basic_stringstream& operator=(basic_stringstream&& rhs);
void swap(basic_stringstream& rhs);
// 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);
}
1The 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, Alloca-
tor> object to control the associated sequence. For the sake of exposition, the maintained data is presented
here as
sb, the stringbuf object.
§ 27.8.5 1070
c
ISO/IEC N????
27.8.6 basic_stringstream constructors [stringstream.cons]
explicit basic_stringstream(
ios_base::openmode which = ios_base::out|ios_base::in);
1Effects: 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,Alloca-
tor>(which).
explicit basic_stringstream(
const basic_string<charT,traits,Allocator>& str,
ios_base::openmode which = ios_base::out|ios_base::in);
2Effects: 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, Alloca-
tor>(str, which).
basic_stringstream(basic_stringstream&& rhs);
3Effects: 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.
27.8.6.1 Assign and swap [stringstream.assign]
basic_stringstream& operator=(basic_stringstream&& rhs);
1Effects: Move assigns the base and members of *this from the base and corresponding members of
rhs.
2Returns: *this.
void swap(basic_stringstream& rhs);
3Effects: 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);
4Effects: x.swap(y).
27.8.7 Member functions [stringstream.members]
basic_stringbuf<charT,traits,Allocator>* rdbuf() const;
1Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb)
basic_string<charT,traits,Allocator> str() const;
2Returns: rdbuf()->str().
void str(const basic_string<charT,traits,Allocator>& str);
3Effects: Calls rdbuf()->str(str).
§ 27.8.7 1071
c
ISO/IEC N????
27.9 File-based streams [file.streams]
27.9.1 File streams [fstreams]
1The header <fstream> defines four class templates and eight types that associate stream buffers with files
and assist reading and writing files.
Header <fstream> synopsis
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_filebuf;
typedef basic_filebuf<char> filebuf;
typedef basic_filebuf<wchar_t> wfilebuf;
template <class charT, class traits = char_traits<charT> >
class basic_ifstream;
typedef basic_ifstream<char> ifstream;
typedef basic_ifstream<wchar_t> wifstream;
template <class charT, class traits = char_traits<charT> >
class basic_ofstream;
typedef basic_ofstream<char> ofstream;
typedef basic_ofstream<wchar_t> wofstream;
template <class charT, class traits = char_traits<charT> >
class basic_fstream;
typedef basic_fstream<char> fstream;
typedef basic_fstream<wchar_t> wfstream;
}
2In this subclause, the type name FILE refers to the type FILE declared in <cstdio> (27.9.2).
3[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 ]
27.9.1.1 Class template basic_filebuf [filebuf]
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_filebuf : public basic_streambuf<charT,traits> {
public:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
// 27.9.1.2 Constructors/destructor:
basic_filebuf();
basic_filebuf(const basic_filebuf& rhs) = delete;
basic_filebuf(basic_filebuf&& rhs);
virtual ~basic_filebuf();
// 27.9.1.3 Assign/swap:
basic_filebuf& operator=(const basic_filebuf& rhs) = delete;
basic_filebuf& operator=(basic_filebuf&& rhs);
void swap(basic_filebuf& rhs);
§ 27.9.1.1 1072
c
ISO/IEC N????
// 27.9.1.4 Members:
bool is_open() const;
basic_filebuf<charT,traits>* open(const char* s,
ios_base::openmode mode);
basic_filebuf<charT,traits>* open(const string& s,
ios_base::openmode mode);
basic_filebuf<charT,traits>* close();
protected:
// 27.9.1.5 Overridden virtual functions:
virtual streamsize showmanyc();
virtual int_type underflow();
virtual int_type uflow();
virtual int_type pbackfail(int_type c = traits::eof());
virtual int_type overflow (int_type c = traits::eof());
virtual basic_streambuf<charT,traits>*
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();
virtual void imbue(const locale& loc);
};
template <class charT, class traits>
void swap(basic_filebuf<charT, traits>& x,
basic_filebuf<charT, traits>& y);
}
1The class basic_filebuf<charT,traits> associates both the input sequence and the output sequence with
a file.
2The 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 Standard C library FILEs.
3In 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.
4An instance of basic_filebuf behaves as described in 27.9.1.1 provided traits::pos_type is fpos<traits
::state_type>. Otherwise the behavior is undefined.
5In 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());
27.9.1.2 basic_filebuf constructors [filebuf.cons]
basic_filebuf();
1Effects: Constructs an object of class basic_filebuf<charT,traits>, initializing the base class with
basic_streambuf<charT,traits>() (27.6.3.1).
2Postcondition: is_open() == false.
§ 27.9.1.2 1073
c
ISO/IEC N????
basic_filebuf(basic_filebuf&& rhs);
3Effects: 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.
4Postconditions: 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();
5Effects: 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 17.6.5.12).
27.9.1.3 Assign and swap [filebuf.assign]
basic_filebuf& operator=(basic_filebuf&& rhs);
1Effects: Calls this->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 27.9.1.2).
2Returns: *this.
void swap(basic_filebuf& rhs);
3Effects: Exchanges the state of *this and rhs.
template <class charT, class traits>
void swap(basic_filebuf<charT, traits>& x,
basic_filebuf<charT, traits>& y);
4Effects: x.swap(y).
§ 27.9.1.3 1074
c
ISO/IEC N????
27.9.1.4 Member functions [filebuf.members]
bool is_open() const;
1Returns: true if a previous call to open succeeded (returned a non-null value) and there has been no
intervening call to close.
basic_filebuf<charT,traits>* open(const char* s,
ios_base::openmode mode);
2Effects: 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 std::fopen(s,modstr)).
The ntbs modstr is determined from mode & ios_base::ate as indicated in Table 132. If mode is
not some combination of flags shown in the table then the open fails.
Table 132 — 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"
3If the open operation succeeds and (mode & ios_base::ate) != 0, positions the file to the end (as
if by calling std::fseek(file,0,SEEK_END)).336
4If the repositioning operation fails, calls close() and returns a null pointer to indicate failure.
5Returns: this if successful, a null pointer otherwise.
basic_filebuf<charT,traits>* open(const string& s,
ios_base::openmode mode);
Returns: open(s.c_str(), mode);
336) The macro SEEK_END is defined, and the function signatures fopen(const char*, const char*) and fseek(FILE*, long,
int) are declared, in <cstdio> (27.9.2).
§ 27.9.1.4 1075
c
ISO/IEC N????
basic_filebuf<charT,traits>* close();
6Effects: 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 std::fclose(file)).337 If any of the calls made by the
function, including std::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.
7Returns: this on success, a null pointer otherwise.
8Postcondition: is_open() == false.
27.9.1.5 Overridden virtual functions [filebuf.virtuals]
streamsize showmanyc();
1Effects: Behaves the same as basic_streambuf::showmanyc() (27.6.3.4).
2Remarks: 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();
3Effects: 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 rindicates that a_codecvt.in()
ran out of space in intern_buf, retry with a larger intern_buf.
int_type uflow();
4Effects: 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());
5Effects: Puts back the character designated by cto the input sequence, if possible, in one of three
ways:
337) The function signature fclose(FILE*) is declared in <cstdio> (27.9.2).
§ 27.9.1.5 1076
c
ISO/IEC N????
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 cthere.
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).
6Returns: traits::eof() to indicate failure.
7Remarks: If is_open() == false, the function always fails.
8The function does not put back a character directly to the input sequence.
9If 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());
10 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 bup 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.
11 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);
12 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.
§ 27.9.1.5 1077
c
ISO/IEC N????
pos_type seekoff(off_type off, ios_base::seekdir way,
ios_base::openmode which = ios_base::in | ios_base::out);
13 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 std::fseek(file, width * off, whence), otherwise
call std::fseek(file, 0, whence).
14 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 133.
Table 133 — seekoff effects
way Value stdio Equivalent
basic_ios::beg SEEK_SET
basic_ios::cur SEEK_CUR
basic_ios::end SEEK_END
15 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);
16 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. if (om & ios_base::out) != 0, then update the output sequence and write any unshift sequence;
2. set the file position to sp;
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.
17 If sp is an invalid stream position, or if the function positions neither sequence, the positioning opera-
tion 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.
18 Returns: sp on success. Otherwise returns pos_type(off_type(-1)).
int sync();
19 Effects: If a put area exists, calls filebuf::overflow to write the characters to the file. If a get area
exists, the effect is implementation-defined.
void imbue(const locale& loc);
§ 27.9.1.5 1078
c
ISO/IEC N????
20 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 (22.4.1.4.2) then that facet is the same as
the corresponding facet of loc.
21 Effects: Causes characters inserted or extracted after this call to be converted according to loc until
another call of imbue.
22 Remark: 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.
27.9.1.6 Class template basic_ifstream [ifstream]
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_ifstream : public basic_istream<charT,traits> {
public:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
// 27.9.1.7 Constructors:
basic_ifstream();
explicit basic_ifstream(const char* s,
ios_base::openmode mode = ios_base::in);
explicit basic_ifstream(const string& s,
ios_base::openmode mode = ios_base::in);
basic_ifstream(const basic_ifstream& rhs) = delete;
basic_ifstream(basic_ifstream&& rhs);
// 27.9.1.8 Assign/swap:
basic_ifstream& operator=(const basic_ifstream& rhs) = delete;
basic_ifstream& operator=(basic_ifstream&& rhs);
void swap(basic_ifstream& rhs);
// 27.9.1.9 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 string& 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);
}
1The 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:
sb, the filebuf object.
§ 27.9.1.6 1079
c
ISO/IEC N????
27.9.1.7 basic_ifstream constructors [ifstream.cons]
basic_ifstream();
1Effects: 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>()) (27.7.2.1.1,
27.9.1.2).
explicit basic_ifstream(const char* s,
ios_base::openmode mode = ios_base::in);
2Effects: Constructs an object of class basic_ifstream, initializing the base class with basic_-
istream(&sb) and initializing sb with basic_filebuf<charT, traits>()) (27.7.2.1.1,27.9.1.2),
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);
3Effects: the same as basic_ifstream(s.c_str(), mode).
basic_ifstream(basic_ifstream&& rhs);
4Effects: 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.
27.9.1.8 Assign and swap [ifstream.assign]
basic_ifstream& operator=(basic_ifstream&& rhs);
1Effects: Move assigns the base and members of *this from the base and corresponding members of
rhs.
2Returns: *this.
void swap(basic_ifstream& rhs);
3Effects: 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);
4Effects: x.swap(y).
§ 27.9.1.8 1080
c
ISO/IEC N????
27.9.1.9 Member functions [ifstream.members]
basic_filebuf<charT,traits>* rdbuf() const;
1Returns: const_cast<basic_filebuf<charT,traits>*>(&sb).
bool is_open() const;
2Returns: rdbuf()->is_open().
void open(const char* s, ios_base::openmode mode = ios_base::in);
3Effects: 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
(27.5.5.4)).
void open(const string& s, ios_base::openmode mode = ios_base::in);
4Effects: calls open(s.c_str(), mode).
void close();
5Effects: Calls rdbuf()->close() and, if that function returns a null pointer, calls setstate(failbit)
(which may throw ios_base::failure (27.5.5.4)).
27.9.1.10 Class template basic_ofstream [ofstream]
namespace std {
template <class charT, class traits = char_traits<charT> >
class basic_ofstream : public basic_ostream<charT,traits> {
public:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
// 27.9.1.11 Constructors:
basic_ofstream();
explicit basic_ofstream(const char* s,
ios_base::openmode mode = ios_base::out);
explicit basic_ofstream(const string& s,
ios_base::openmode mode = ios_base::out);
basic_ofstream(const basic_ofstream& rhs) = delete;
basic_ofstream(basic_ofstream&& rhs);
// 27.9.1.12 Assign/swap:
basic_ofstream& operator=(const basic_ofstream& rhs) = delete;
basic_ofstream& operator=(basic_ofstream&& rhs);
void swap(basic_ofstream& rhs);
// 27.9.1.13 Members:
basic_filebuf<charT,traits>* rdbuf() const;
§ 27.9.1.10 1081
c
ISO/IEC N????
bool is_open() const;
void open(const char* s, ios_base::openmode mode = ios_base::out);
void open(const string& 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);
}
1The 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:
sb, the filebuf object.
27.9.1.11 basic_ofstream constructors [ofstream.cons]
basic_ofstream();
1Effects: 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>()) (27.7.3.2,27.9.1.2).
explicit basic_ofstream(const char* s,
ios_base::openmode mode = ios_base::out);
2Effects: 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>()) (27.7.3.2,27.9.1.2),
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);
3Effects: the same as basic_ofstream(s.c_str(), mode);
basic_ofstream(basic_ofstream&& rhs);
4Effects: 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.
27.9.1.12 Assign and swap [ofstream.assign]
basic_ofstream& operator=(basic_ofstream&& rhs);
1Effects: Move assigns the base and members of *this from the base and corresponding members of
rhs.
2Returns: *this.
§ 27.9.1.12 1082
c
ISO/IEC N????
void swap(basic_ofstream& rhs);
3Effects: 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);
4Effects: x.swap(y).
27.9.1.13 Member functions [ofstream.members]
basic_filebuf<charT,traits>* rdbuf() const;
1Returns: const_cast<basic_filebuf<charT,traits>*>(&sb).
bool is_open() const;
2Returns: rdbuf()->is_open().
void open(const char* s, ios_base::openmode mode = ios_base::out);
3Effects: 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
(27.5.5.4)).
void close();
4Effects: Calls rdbuf()->close() and, if that function fails (returns a null pointer), calls setstate(
failbit) (which may throw ios_base::failure (27.5.5.4)).
void open(const string& s, ios_base::openmode mode = ios_base::out);
5Effects: calls open(s.c_str(), mode);
27.9.1.14 Class template basic_fstream [fstream]
namespace std {
template <class charT, class traits=char_traits<charT> >
class basic_fstream
: public basic_iostream<charT,traits> {
public:
typedef charT char_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef traits traits_type;
// constructors/destructor
basic_fstream();
§ 27.9.1.14 1083
c
ISO/IEC N????
explicit basic_fstream(const char* s,
ios_base::openmode mode = ios_base::in|ios_base::out);
explicit basic_fstream(const string& s,
ios_base::openmode mode = ios_base::in|ios_base::out);
basic_fstream(const basic_fstream& rhs) = delete;
basic_fstream(basic_fstream&& rhs);
// 27.9.1.16 Assign/swap:
basic_fstream& operator=(const basic_fstream& rhs) = delete;
basic_fstream& operator=(basic_fstream&& rhs);
void swap(basic_fstream& rhs);
// 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 string& 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);
}
1The class template basic_fstream<charT,traits> supports reading and writing from named files. It uses
abasic_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.
27.9.1.15 basic_fstream constructors [fstream.cons]
basic_fstream();
1Effects: 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);
2Effects: 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);
3Effects: the same as basic_fstream(s.c_str(), mode);
§ 27.9.1.15 1084
c
ISO/IEC N????
basic_fstream(basic_fstream&& rhs);
4Effects: 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.
27.9.1.16 Assign and swap [fstream.assign]
basic_fstream& operator=(basic_fstream&& rhs);
1Effects: Move assigns the base and members of *this from the base and corresponding members of
rhs.
2Returns: *this.
void swap(basic_fstream& rhs);
3Effects: 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);
4Effects: x.swap(y).
27.9.1.17 Member functions [fstream.members]
basic_filebuf<charT,traits>* rdbuf() const;
1Returns: const_cast<basic_filebuf<charT,traits>*>(&sb).
bool is_open() const;
2Returns: rdbuf()->is_open().
void open(const char* s,
ios_base::openmode mode = ios_base::in|ios_base::out);
3Effects: 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) (27.5.5.4).
void open(const string& s,
ios_base::openmode mode = ios_base::in|ios_base::out);
4Effects: calls open(s.c_str(), mode);
void close();
5Effects: Calls rdbuf()->close() and, if that function returns returns a null pointer, calls setstate(
failbit) (27.5.5.4) (which may throw ios_base::failure).
§ 27.9.1.17 1085
c
ISO/IEC N????
Table 134 — Header <cstdio> synopsis
Type Name(s)
Macros:
BUFSIZ FOPEN_MAX SEEK_CUR TMP_MAX _IONBF stdout
EOF L_tmpnam SEEK_END _IOFBF stderr
FILENAME_MAX NULL <cstdio> SEEK_SET _IOLBF stdin
Types:FILE fpos_t size_t <cstdio>
Functions:
clearerr fopen fsetpos putc setbuf vprintf
fclose fprintf ftell putchar setvbuf vscanf
feof fputc fwrite puts snprintf vsnprintf
ferror fputs getc rename sprintf vsprintf
fflush fread getchar remove tmpfile vsscanf
fgetc freopen gets rewind tmpnam
fgetpos fscanf perror scanf ungetc
fgets fseek printf sscanf vfprintf
27.9.2 C library files [c.files]
1Table 134 describes header <cstdio>.
2Calls to the function tmpnam with an argument of NULL may introduce a data race (17.6.5.9) with other calls
to tmpnam with an argument of NULL.
See also: ISO C 7.9, Amendment 1 4.6.2.
3Table 135 describes header <cinttypes>. [ Note: The macros defined by <cinttypes> are provided uncon-
ditionally. In particular, the symbol __STDC_FORMAT_MACROS, mentioned in footnote 182 of the C standard,
plays no role in C++.— end note ]
Table 135 — Header <cinttypes> synopsis
Type Name(s)
Macros:
PRI{d i o u x X}[FAST LEAST]{8 16 32 64}
PRI{d i o u x X}{MAX PTR}
SCN{d i o u x X}[FAST LEAST]{8 16 32 64}
SCN{d i o u x X}{MAX PTR}
Types:imaxdiv_t
Functions:
abs imaxabs strtoimax wcstoimax
div imaxdiv strtoumax wcstoumax
4The contents of header <cinttypes> are the same as the Standard C 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 (3.9.1), the following function
signatures are added:
§ 27.9.2 1086
c
ISO/IEC N????
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.
§ 27.9.2 1087
c
ISO/IEC N????
28 Regular expressions library [re]
28.1 General [re.general]
1This Clause describes components that C++ programs may use to perform operations involving regular
expression matching and searching.
2The following subclauses describe a basic regular expression class template and its traits that can handle
char-like 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 136.
Table 136 — Regular expressions library summary
Subclause Header(s)
28.2 Definitions
28.3 Requirements
28.5 Constants
28.6 Exception type
28.7 Traits
28.8 Regular expression template <regex>
28.9 Submatches
28.10 Match results
28.11 Algorithms
28.12 Iterators
28.13 Grammar
28.2 Definitions [re.def]
1The following definitions shall apply to this Clause:
28.2.1 [defns.regex.collating.element]
collating element
a sequence of one or more characters within the current locale that collate as if they were a single character.
28.2.2 [defns.regex.finite.state.machine]
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.
28.2.3 [defns.regex.format.specifier]
format specifier
a sequence of one or more characters that is to be replaced with some part of a regular expression match.
28.2.4 [defns.regex.matched]
matched
§ 28.2 1088
c
ISO/IEC N????
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.
28.2.5 [defns.regex.primary.equivalence.class]
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.
28.2.6 [defns.regex.regular.expression]
regular expression
a pattern that selects specific strings from a set of character strings.
28.2.7 [defns.regex.subexpression]
sub-expression
a subset of a regular expression that has been marked by parenthesis.
28.3 Requirements [re.req]
1This subclause defines requirements on classes representing regular expression traits. [ Note: The class
template regex_traits, defined in Clause 28.7, satisfies these requirements. — end note ]
2The class template basic_regex, defined in Clause 28.8, 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 typedefs
and functions in the template parameter traits used by the basic_regex class template. This subclause
defines the semantics of these members.
3To specialize class template basic_regex for a character container CharT and its related regular expression
traits class Traits, use basic_regex<CharT, Traits>.
4In Table 137 Xdenotes a traits class defining types and functions for the character container type charT;
uis an object of type X;vis an object of type const X;pis a value of type const charT*;I1 and I2
are input iterators (24.2.3); F1 and F2 are forward iterators (24.2.5); cis 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;bis a value of type
bool;Iis 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 137 — 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 std::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 (17.5.2.1.3).
A bitmask type representing a particular
character classification.
X::length(p) std::size_t Yields the smallest isuch that p[i] == 0.
Complexity is linear in i.
v.translate(c) X::char_type Returns a character such that for any
character dthat is to be considered equivalent
to cthen v.translate(c) ==
v.translate(d).
§ 28.3 1089
c
ISO/IEC N????
Table 137 — Regular expression traits class requirements
(continued)
Expression Return type Assertion/note pre-/post-condition
v.translate_nocase(c) X::char_type For all characters Cthat are to be considered
equivalent to cwhen 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 bis 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 cis 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 Iif the character cis a valid digit in
base I; otherwise returns -1. [ Note: The
value of Iwill only be 8, 10, or 16. — end
note ]
§ 28.3 1090
c
ISO/IEC N????
Table 137 — Regular expression traits class requirements
(continued)
Expression Return type Assertion/note pre-/post-condition
u.imbue(loc) X::locale_type Imbues uwith the locale loc and returns the
previous locale used by uif any.
v.getloc() X::locale_type Returns the current locale used by v, if any.
5[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 28.7.— end note ]
28.4 Header <regex> synopsis [re.syn]
#include <initializer_list>
namespace std {
// 28.5, regex constants:
namespace regex_constants {
enum error_type;
}// namespace regex_constants
// 28.6, class regex_error:
class regex_error;
// 28.7, class template regex_traits:
template <class charT> struct regex_traits;
// 28.8, class template basic_regex:
template <class charT, class traits = regex_traits<charT> > class basic_regex;
typedef basic_regex<char> regex;
typedef basic_regex<wchar_t> wregex;
// 28.8.6, basic_regex swap:
template <class charT, class traits>
void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2);
// 28.9, class template sub_match:
template <class BidirectionalIterator>
class sub_match;
typedef sub_match<const char*> csub_match;
typedef sub_match<const wchar_t*> wcsub_match;
typedef sub_match<string::const_iterator> ssub_match;
typedef sub_match<wstring::const_iterator> wssub_match;
// 28.9.2, 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>
§ 28.4 1091
c
ISO/IEC N????
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>(
§ 28.4 1092
c
ISO/IEC N????
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==(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator!=(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator<(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator>(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator>=(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator<=(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator==(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
template <class BiIter>
bool operator!=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
template <class BiIter>
bool operator<(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
template <class BiIter>
bool operator>(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
template <class BiIter>
bool operator>=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
template <class BiIter>
bool operator<=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
template <class BiIter>
bool operator==(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
§ 28.4 1093
c
ISO/IEC N????
template <class BiIter>
bool operator!=(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator<(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator>(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator>=(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator<=(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
template <class BiIter>
bool operator==(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
template <class BiIter>
bool operator!=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
template <class BiIter>
bool operator<(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
template <class BiIter>
bool operator>(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
template <class BiIter>
bool operator>=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
template <class BiIter>
bool operator<=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
template <class charT, class ST, class BiIter>
basic_ostream<charT, ST>&
operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);
// 28.10, class template match_results:
template <class BidirectionalIterator,
class Allocator = allocator<sub_match<BidirectionalIterator> > >
class match_results;
typedef match_results<const char*> cmatch;
typedef match_results<const wchar_t*> wcmatch;
typedef match_results<string::const_iterator> smatch;
typedef match_results<wstring::const_iterator> wsmatch;
// 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,
§ 28.4 1094
c
ISO/IEC N????
const match_results<BidirectionalIterator, Allocator>& m2);
// 28.10.7, match_results swap:
template <class BidirectionalIterator, class Allocator>
void swap(match_results<BidirectionalIterator, Allocator>& m1,
match_results<BidirectionalIterator, Allocator>& m2);
// 28.11.2, 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 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);
// 28.11.3, 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,
§ 28.4 1095
c
ISO/IEC N????
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);
// 28.11.4, 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>
§ 28.4 1096
c
ISO/IEC N????
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);
// 28.12.1, class template regex_iterator:
template <class BidirectionalIterator,
class charT = typename iterator_traits<
BidirectionalIterator>::value_type,
class traits = regex_traits<charT> >
class regex_iterator;
typedef regex_iterator<const char*> cregex_iterator;
typedef regex_iterator<const wchar_t*> wcregex_iterator;
typedef regex_iterator<string::const_iterator> sregex_iterator;
typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
// 28.12.2, 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;
typedef regex_token_iterator<const char*> cregex_token_iterator;
typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
typedef regex_token_iterator<string::const_iterator> sregex_token_iterator;
typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
}
28.5 Namespace std::regex_constants [re.const]
1The 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.
28.5.1 Bitmask type syntax_option_type [re.synopt]
namespace std {
namespace regex_constants {
typedef T1 syntax_option_type;
§ 28.5.1 1097
c
ISO/IEC N????
constexpr syntax_option_type icase = unspecified ;
constexpr syntax_option_type nosubs = unspecified ;
constexpr syntax_option_type optimize = unspecified ;
constexpr syntax_option_type collate = unspecified ;
constexpr syntax_option_type ECMAScript = unspecified ;
constexpr syntax_option_type basic = unspecified ;
constexpr syntax_option_type extended = unspecified ;
constexpr syntax_option_type awk = unspecified ;
constexpr syntax_option_type grep = unspecified ;
constexpr syntax_option_type egrep = unspecified ;
}
}
1The type syntax_option_type is an implementation-defined bitmask type (17.5.2.1.3). Setting its elements
has the effects listed in table 138. A valid value of type syntax_option_type shall have exactly one of the
elements ECMAScript,basic,extended,awk,grep,egrep, set.
Table 138 — syntax_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 when a regular expression is matched against a character con-
tainer 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 28.13.
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.
28.5.2 Bitmask type regex_constants::match_flag_type [re.matchflag]
namespace std {
namespace regex_constants{
§ 28.5.2 1098
c
ISO/IEC N????
typedef T2 match_flag_type;
constexpr match_flag_type match_default = {};
constexpr match_flag_type match_not_bol = unspecified ;
constexpr match_flag_type match_not_eol = unspecified ;
constexpr match_flag_type match_not_bow = unspecified ;
constexpr match_flag_type match_not_eow = unspecified ;
constexpr match_flag_type match_any = unspecified ;
constexpr match_flag_type match_not_null = unspecified ;
constexpr match_flag_type match_continuous = unspecified ;
constexpr match_flag_type match_prev_avail = unspecified ;
constexpr match_flag_type format_default = {};
constexpr match_flag_type format_sed = unspecified ;
constexpr match_flag_type format_no_copy = unspecified ;
constexpr match_flag_type format_first_only = unspecified ;
}
}
1The type regex_constants::match_flag_type is an implementation-defined bitmask type (17.5.2.1.3).
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 139 for any bitmask elements set.
Table 139 — regex_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 expres-
sion 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 28.11 and iterators 28.12.
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 occur-
rences 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.
§ 28.5.2 1099
c
ISO/IEC N????
Table 139 — regex_constants::match_flag_type effects when
obtaining a match against a character container sequence
[first,last). (continued)
Element Effect(s) if set
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 occur-
rence of the regular expression shall be replaced.
28.5.3 Implementation-defined error_type [re.err]
namespace std {
namespace regex_constants {
typedef T3 error_type;
constexpr error_type error_collate = unspecified ;
constexpr error_type error_ctype = unspecified ;
constexpr error_type error_escape = unspecified ;
constexpr error_type error_backref = unspecified ;
constexpr error_type error_brack = unspecified ;
constexpr error_type error_paren = unspecified ;
constexpr error_type error_brace = unspecified ;
constexpr error_type error_badbrace = unspecified ;
constexpr error_type error_range = unspecified ;
constexpr error_type error_space = unspecified ;
constexpr error_type error_badrepeat = unspecified ;
constexpr error_type error_complexity = unspecified ;
constexpr error_type error_stack = unspecified ;
}
}
1The type error_type is an implementation-defined enumerated type (17.5.2.1.2). Values of type error_type
represent the error conditions described in Table 140:
Table 140 — error_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 ex-
ceeded a pre-set level.
§ 28.5.3 1100
c
ISO/IEC N????
Table 140 — error_type values in the C locale (continued)
Value Error condition
error_stack There was insufficient memory to determine whether the regular expression
could match the specified character sequence.
28.6 Class regex_error [re.badexp]
class regex_error : public std::runtime_error {
public:
explicit regex_error(regex_constants::error_type ecode);
regex_constants::error_type code() const;
};
1The 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);
2Effects: Constructs an object of class regex_error.
3Postcondition::ecode == code()
regex_constants::error_type code() const;
4Returns: The error code that was passed to the constructor.
28.7 Class template regex_traits [re.traits]
namespace std {
template <class charT>
struct regex_traits {
public:
typedef charT char_type;
typedef std::basic_string<char_type> string_type;
typedef std::locale locale_type;
typedef bitmask_type char_class_type;
regex_traits();
static std::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);
§ 28.7 1101
c
ISO/IEC N????
locale_type getloc()const;
};
}
1The specializations regex_traits<char> and regex_traits<wchar_t> shall be valid and shall satisfy the
requirements for a regular expression traits class (28.3).
typedef bitmask_type char_class_type;
2The 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 std::size_t length(const char_type* p);
3Returns: char_traits<charT>::length(p);
charT translate(charT c) const;
4Returns: (c).
charT translate_nocase(charT c) const;
5Returns: use_facet<ctype<charT> >(getloc()).tolower(c).
template <class ForwardIterator>
string_type transform(ForwardIterator first, ForwardIterator last) const;
6Effects:
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;
7Effects: 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;
8Returns: 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;
§ 28.7 1102
c
ISO/IEC N????
9Returns: 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.338 The value returned shall
be independent of the case of the characters in the character sequence. If the name is not recognized
then returns a value that compares equal to 0.
10 Remarks: For regex_traits<char>, at least the names "d","w","s","alnum","alpha","blank",
"cntrl","digit","graph","lower","print","punct","space","upper" and "xdigit" shall be
recognized. For regex_traits<wchar_t>, at least the names L"d",L"w",L"s",L"alnum",L"alpha",
L"blank",L"cntrl",L"digit",L"graph",L"lower",L"print",L"punct",L"space",L"upper" and
L"xdigit" shall be recognized.
bool isctype(charT c, char_class_type f) const;
11 Effects: Determines if the character cis a member of the character classification represented by f.
12 Returns: Converts finto a value mof type std::ctype_base::mask in an unspecified manner, and
returns true if use_facet<ctype<charT> >(getloc()).is(m, c) is true. Otherwise returns true
if fbitwise or’ed with the result of calling lookup_classname with an iterator pair that designates
the character sequence "w" is not equal to 0 and c == ’_’, or if fbitwise or’ed with the result of
calling lookup_classname with an iterator pair that designates the character sequence "blank" is not
equal to 0 and cis one of an implementation-defined subset of the characters for which isspace(c,
getloc()) returns true, otherwise returns false.
int value(charT ch, int radix) const;
13 Requires: The value of radix shall be 8, 10, or 16.
14 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);
15 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 ]
16 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.
17 Postcondition: getloc() == loc.
locale_type getloc()const;
18 Returns: if no locale has been imbued then a copy of the global locale in effect at the time of construc-
tion of *this, otherwise a copy of the last argument passed to imbue.
338) For example, if the parameter icase is true then [[:lower:]] is the same as [[:alpha:]].
§ 28.7 1103
c
ISO/IEC N????
28.8 Class template basic_regex [re.regex]
1For 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 28.8,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.
2Objects 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 ]
3The 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:
typedef charT value_type;
typedef traits traits_type;
typedef typename traits::string_type string_type;
typedef regex_constants::syntax_option_type flag_type;
typedef typename traits::locale_type locale_type;
// 28.8.1, 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;
// 28.8.2, 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);
§ 28.8 1104
c
ISO/IEC N????
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);
// 28.8.3, 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);
// 28.8.4, const operations:
unsigned mark_count() const;
flag_type flags() const;
// 28.8.5, locale:
locale_type imbue(locale_type loc);
locale_type getloc() const;
// 28.8.6, swap:
void swap(basic_regex&);
};
}
28.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
§ 28.8.1 1105
c
ISO/IEC N????
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;
1The static constant members are provided as synonyms for the constants declared in namespace regex_-
constants.
28.8.2 basic_regex constructors [re.regex.construct]
basic_regex();
1Effects: 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);
2Requires: p shall not be a null pointer.
3Throws: regex_error if pis not a valid regular expression.
4Effects: Constructs an object of class basic_regex; the object’s internal finite state machine is con-
structed 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.
5Postconditions: 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);
6Requires: p shall not be a null pointer.
7Throws: regex_error if pis not a valid regular expression.
8Effects: Constructs an object of class basic_regex; the object’s internal finite state machine is con-
structed from the regular expression contained in the sequence of characters [p,p+len), and interpreted
according the flags specified in f.
9Postconditions: flags() returns f.mark_count() returns the number of marked sub-expressions
within the expression.
basic_regex(const basic_regex& e);
10 Effects: Constructs an object of class basic_regex as a copy of the object e.
11 Postconditions: flags() and mark_count() return e.flags() and e.mark_count(), respectively.
basic_regex(basic_regex&& e) noexcept;
12 Effects: Move constructs an object of class basic_regex from e.
13 Postconditions: flags() and mark_count() return the values that e.flags() and e.mark_count(),
respectively, had before construction. eis in a valid state with unspecified value.
§ 28.8.2 1106
c
ISO/IEC N????
template <class ST, class SA>
explicit basic_regex(const basic_string<charT, ST, SA>& s,
flag_type f = regex_constants::ECMAScript);
14 Throws: regex_error if sis not a valid regular expression.
15 Effects: Constructs an object of class basic_regex; the object’s internal finite state machine is con-
structed from the regular expression contained in the string s, and interpreted according to the flags
specified in f.
16 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);
17 Throws: regex_error if the sequence [first,last) is not a valid regular expression.
18 Effects: Constructs an object of class basic_regex; the object’s internal finite state machine is con-
structed from the regular expression contained in the sequence of characters [first,last), and in-
terpreted according to the flags specified in f.
19 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);
20 Effects: Same as basic_regex(il.begin(), il.end(), f).
28.8.3 basic_regex assign [re.regex.assign]
basic_regex& operator=(const basic_regex& e);
1Effects: returns assign(e).
basic_regex& operator=(basic_regex&& e) noexcept;
2Effects: returns assign(std::move(e)).
basic_regex& operator=(const charT* ptr);
3Requires: ptr shall not be a null pointer.
4Effects: returns assign(ptr).
basic_regex& operator=(initializer_list<charT> il);
5Effects: returns assign(il.begin(), il.end()).
template <class ST, class SA>
basic_regex& operator=(const basic_string<charT, ST, SA>& p);
§ 28.8.3 1107
c
ISO/IEC N????
6Effects: returns assign(p).
basic_regex& assign(const basic_regex& that);
7Effects: copies that into *this and returns *this.
8Postconditions: flags() and mark_count() return that.flags() and that.mark_count(), respec-
tively.
basic_regex& assign(basic_regex&& that) noexcept;
9Effects: move assigns from that into *this and returns *this.
10 Postconditions: flags() and mark_count() return the values that that.flags() and that.mark_-
count(), respectively, had before assignment. that is in a valid state with unspecified value.
basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript);
11 Returns: assign(string_type(ptr), f).
basic_regex& assign(const charT* ptr, size_t len,
flag_type f = regex_constants::ECMAScript);
12 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);
13 Throws: regex_error if sis not a valid regular expression.
14 Returns: *this.
15 Effects: Assigns the regular expression contained in the string s, interpreted according the flags spec-
ified in f. If an exception is thrown, *this is unchanged.
16 Postconditions: If no exception is thrown, flags() returns fand 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);
17 Requires: The type InputIterator shall satisfy the requirements for an Input Iterator (24.2.3).
18 Returns: assign(string_type(first, last), f).
basic_regex& assign(initializer_list<charT> il,
flag_type f = regex_constants::ECMAScript);
19 Effects: Same as assign(il.begin(), il.end(), f).
20 Returns: *this.
§ 28.8.3 1108
c
ISO/IEC N????
28.8.4 basic_regex constant operations [re.regex.operations]
unsigned mark_count() const;
1Effects: Returns the number of marked sub-expressions within the regular expression.
flag_type flags() const;
2Effects: Returns a copy of the regular expression syntax flags that were passed to the object’s con-
structor or to the last call to assign.
28.8.5 basic_regex locale [re.regex.locale]
locale_type imbue(locale_type loc);
1Effects: 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;
2Effects: Returns the result of traits_inst.getloc() where traits_inst is a (default initialized)
instance of the template parameter traits stored within the object.
28.8.6 basic_regex swap [re.regex.swap]
void swap(basic_regex& e);
1Effects: Swaps the contents of the two regular expressions.
2Postcondition: *this contains the regular expression that was in e,econtains the regular expression
that was in *this.
3Complexity: constant time.
28.8.7 basic_regex non-member functions [re.regex.nonmemb]
28.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);
1Effects: Calls lhs.swap(rhs).
28.9 Class template sub_match [re.submatch]
1Class template sub_match denotes the sequence of characters matched by a particular marked sub-expression.
namespace std {
template <class BidirectionalIterator>
class sub_match : public std::pair<BidirectionalIterator, BidirectionalIterator> {
public:
typedef typename iterator_traits<BidirectionalIterator>::
value_type value_type;
typedef typename iterator_traits<BidirectionalIterator>::
difference_type difference_type;
typedef BidirectionalIterator iterator;
typedef basic_string<value_type> string_type;
§ 28.9 1109
c
ISO/IEC N????
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;
};
}
28.9.1 sub_match members [re.submatch.members]
constexpr sub_match();
1Effects: Value-initializes the pair base class subobject and the member matched.
difference_type length() const;
2Returns: (matched ? distance(first, second) : 0).
operator string_type() const;
3Returns: matched ? string_type(first, second) : string_type().
string_type str() const;
4Returns: matched ? string_type(first, second) : string_type().
int compare(const sub_match& s) const;
5Returns: str().compare(s.str()).
int compare(const string_type& s) const;
6Returns: str().compare(s).
int compare(const value_type* s) const;
7Returns: str().compare(s).
28.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);
1Returns: lhs.compare(rhs) == 0.
template <class BiIter>
bool operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
§ 28.9.2 1110
c
ISO/IEC N????
2Returns: lhs.compare(rhs) != 0.
template <class BiIter>
bool operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
3Returns: lhs.compare(rhs) < 0.
template <class BiIter>
bool operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
4Returns: lhs.compare(rhs) <= 0.
template <class BiIter>
bool operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
5Returns: lhs.compare(rhs) >= 0.
template <class BiIter>
bool operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
6Returns: 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);
7Returns: rhs.compare(lhs.c_str()) == 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);
8Returns: !(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);
9Returns: rhs.compare(lhs.c_str()) > 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);
§ 28.9.2 1111
c
ISO/IEC N????
10 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);
11 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);
12 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);
13 Returns: lhs.compare(rhs.c_str()) == 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);
14 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);
15 Returns: lhs.compare(rhs.c_str()) < 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);
16 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);
§ 28.9.2 1112
c
ISO/IEC N????
17 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);
18 Returns: !(rhs < lhs).
template <class BiIter>
bool operator==(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
19 Returns: rhs.compare(lhs) == 0.
template <class BiIter>
bool operator!=(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
20 Returns: !(lhs == rhs).
template <class BiIter>
bool operator<(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
21 Returns: rhs.compare(lhs) > 0.
template <class BiIter>
bool operator>(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
22 Returns: rhs < lhs.
template <class BiIter>
bool operator>=(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
23 Returns: !(lhs < rhs).
template <class BiIter>
bool operator<=(typename iterator_traits<BiIter>::value_type const* lhs,
const sub_match<BiIter>& rhs);
24 Returns: !(rhs < lhs).
template <class BiIter>
bool operator==(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
25 Returns: lhs.compare(rhs) == 0.
§ 28.9.2 1113
c
ISO/IEC N????
template <class BiIter>
bool operator!=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
26 Returns: !(lhs == rhs).
template <class BiIter>
bool operator<(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
27 Returns: lhs.compare(rhs) < 0.
template <class BiIter>
bool operator>(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
28 Returns: rhs < lhs.
template <class BiIter>
bool operator>=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
29 Returns: !(lhs < rhs).
template <class BiIter>
bool operator<=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const* rhs);
30 Returns: !(rhs < lhs).
template <class BiIter>
bool operator==(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
31 Returns: rhs.compare(typename sub_match<BiIter>::string_type(1, lhs)) == 0.
template <class BiIter>
bool operator!=(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
32 Returns: !(lhs == rhs).
template <class BiIter>
bool operator<(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
33 Returns: rhs.compare(typename sub_match<BiIter>::string_type(1, lhs)) > 0.
§ 28.9.2 1114
c
ISO/IEC N????
template <class BiIter>
bool operator>(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
34 Returns: rhs < lhs.
template <class BiIter>
bool operator>=(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
35 Returns: !(lhs < rhs).
template <class BiIter>
bool operator<=(typename iterator_traits<BiIter>::value_type const& lhs,
const sub_match<BiIter>& rhs);
36 Returns: !(rhs < lhs).
template <class BiIter>
bool operator==(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
37 Returns: lhs.compare(typename sub_match<BiIter>::string_type(1, rhs)) == 0.
template <class BiIter>
bool operator!=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
38 Returns: !(lhs == rhs).
template <class BiIter>
bool operator<(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
39 Returns: lhs.compare(typename sub_match<BiIter>::string_type(1, rhs)) < 0.
template <class BiIter>
bool operator>(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
40 Returns: rhs < lhs.
template <class BiIter>
bool operator>=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
41 Returns: !(lhs < rhs).
§ 28.9.2 1115
c
ISO/IEC N????
template <class BiIter>
bool operator<=(const sub_match<BiIter>& lhs,
typename iterator_traits<BiIter>::value_type const& rhs);
42 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);
43 Returns: (os << m.str()).
28.10 Class template match_results [re.results]
1Class 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.
2The class template match_results shall satisfy the requirements of an allocator-aware container and of a
sequence container, as specified in 23.2.3, except that only operations defined for const-qualified sequence
containers are supported.
3A 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.
4The 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 ndenotes what matched
the marked sub-expression nwithin the matched expression. If the sub-expression nparticipated 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:
typedef sub_match<BidirectionalIterator> value_type;
typedef const value_type& const_reference;
typedef const_reference reference;
typedef implementation-defined const_iterator;
typedef const_iterator iterator;
typedef typename
iterator_traits<BidirectionalIterator>::difference_type difference_type;
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef Allocator allocator_type;
typedef typename iterator_traits<BidirectionalIterator>::
value_type char_type;
typedef basic_string<char_type> string_type;
// 28.10.1, construct/copy/destroy:
explicit match_results(const Allocator& a = Allocator());
match_results(const match_results& m);
§ 28.10 1116
c
ISO/IEC N????
match_results(match_results&& m) noexcept;
match_results& operator=(const match_results& m);
match_results& operator=(match_results&& m);
~match_results();
// 28.10.2, state:
bool ready() const;
// 28.10.3, size:
size_type size() const;
size_type max_size() const;
bool empty() const;
// 28.10.4, 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;
// 28.10.5, 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;
// 28.10.6, allocator:
allocator_type get_allocator() const;
// 28.10.7, swap:
void swap(match_results& that);
};
§ 28.10 1117
c
ISO/IEC N????
}
28.10.1 match_results constructors [re.results.const]
1In all match_results constructors, a copy of the Allocator argument shall be used for any memory allo-
cation performed by the constructor or member functions during the lifetime of the object.
match_results(const Allocator& a = Allocator());
2Effects: Constructs an object of class match_results.
3Postconditions: ready() returns false.size() returns 0.
match_results(const match_results& m);
4Effects: Constructs an object of class match_results, as a copy of m.
match_results(match_results&& m) noexcept;
5Effects: Move-constructs an object of class match_results from msatisfying the same postconditions
as Table 141. Additionally, the stored Allocator value is move constructed from m.get_allocator().
6Throws: Nothing if the allocator’s move constructor throws nothing.
match_results& operator=(const match_results& m);
7Effects: Assigns mto *this. The postconditions of this function are indicated in Table 141.
match_results& operator=(match_results&& m);
8Effects: Move-assigns mto *this. The postconditions of this function are indicated in Table 141.
Table 141 — match_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()
28.10.2 match_results state [re.results.state]
bool ready() const;
1Returns: true if *this has a fully established result state, otherwise false.
§ 28.10.2 1118
c
ISO/IEC N????
28.10.3 match_results size [re.results.size]
size_type size() const;
1Returns: 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 28.11.2 and 28.11.3 specify the effects of those algorithms on their match_results arguments.
— end note ]
size_type max_size() const;
2Returns: The maximum number of sub_match elements that can be stored in *this.
bool empty() const;
3Returns: size() == 0.
28.10.4 match_results element access [re.results.acc]
difference_type length(size_type sub = 0) const;
1Requires: ready() == true.
2Returns: (*this)[sub].length().
difference_type position(size_type sub = 0) const;
3Requires: ready() == true.
4Returns: The distance from the start of the target sequence to (*this)[sub].first.
string_type str(size_type sub = 0) const;
5Requires: ready() == true.
6Returns: string_type((*this)[sub]).
const_reference operator[](size_type n) const;
7Requires: ready() == true.
8Returns: 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;
9Requires: ready() == true.
10 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.
§ 28.10.4 1119
c
ISO/IEC N????
const_reference suffix() const;
11 Requires: ready() == true.
12 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;
13 Returns: A starting iterator that enumerates over all the sub-expressions stored in *this.
const_iterator end() const;
const_iterator cend() const;
14 Returns: A terminating iterator that enumerates over all the sub-expressions stored in *this.
28.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;
1Requires: ready() == true and OutputIter shall satisfy the requirements for an Output Iterator (24.2.4).
2Effects: 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.
3Returns: 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;
4Effects: 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;
5Requires: ready() == true.
6Effects: Constructs an empty string result of type basic_string<char_type, ST, SA> and calls
format(back_inserter(result), fmt, flags).
7Returns: result.
§ 28.10.5 1120
c
ISO/IEC N????
string_type
format(const char_type* fmt,
regex_constants::match_flag_type flags =
regex_constants::format_default) const;
8Requires: ready() == true.
9Effects: Constructs an empty string result of type string_type and calls
format(back_inserter(result), fmt, fmt + char_traits<char_type>::length(fmt), flags).
10 Returns: result.
28.10.6 match_results allocator [re.results.all]
allocator_type get_allocator() const;
1Returns: 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.
28.10.7 match_results swap [re.results.swap]
void swap(match_results& that);
1Effects: Swaps the contents of the two sequences.
2Postcondition: *this contains the sequence of matched sub-expressions that were in that,that con-
tains the sequence of matched sub-expressions that were in *this.
3Complexity: constant time.
template <class BidirectionalIterator, class Allocator>
void swap(match_results<BidirectionalIterator, Allocator>& m1,
match_results<BidirectionalIterator, Allocator>& m2);
4Effects: m1.swap(m2).
28.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);
1Returns: 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 25.— end note ]
template <class BidirectionalIterator, class Allocator>
bool operator!=(const match_results<BidirectionalIterator, Allocator>& m1,
const match_results<BidirectionalIterator, Allocator>& m2);
2Returns: !(m1 == m2).
§ 28.10.8 1121
c
ISO/IEC N????
28.11 Regular expression algorithms [re.alg]
28.11.1 exceptions [re.except]
1The algorithms described in this subclause may throw an exception of type regex_error. If such an
exception eis thrown, e.code() shall return either regex_constants::error_complexity or regex_-
constants::error_stack.
28.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);
1Requires: The type BidirectionalIterator shall satisfy the requirements of a Bidirectional Iterator
(24.2.6).
2Effects: 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. Returns true if such a match exists, false otherwise.
3Postconditions: m.ready() == true in all cases. If the function returns false, then the effect on
parameter mis unspecified except that m.size() returns 0and m.empty() returns true. Otherwise
the effects on parameter mare given in Table 142.
Table 142 — 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 if a full match was found.
m[n].first For all integers n < m.size(), the start of the sequence
that matched sub-expression n. Alternatively, if sub-
expression ndid not participate in the match, then last.
m[n].second For all integers n < m.size(), the end of the sequence that
matched sub-expression n. Alternatively, if sub-expression
ndid not participate in the match, then last.
m[n].matched For all integers 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,
§ 28.11.2 1122
c
ISO/IEC N????
regex_constants::match_flag_type flags =
regex_constants::match_default);
4Effects: 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);
5Returns: 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);
6Returns: 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);
7Returns: 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);
8Returns: regex_match(s.begin(), s.end(), e, flags).
28.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);
§ 28.11.3 1123
c
ISO/IEC N????
1Requires: Type BidirectionalIterator shall satisfy the requirements of a Bidirectional Iterator
(24.2.6).
2Effects: 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.
3Postconditions: m.ready() == true in all cases. If the function returns false, then the effect on
parameter mis unspecified except that m.size() returns 0and m.empty() returns true. Otherwise
the effects on parameter mare given in Table 143.
Table 143 — 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 if a match was found, and false otherwise.
m[n].first For all integers n < m.size(), the start of the sequence
that matched sub-expression n. Alternatively, if sub-
expression ndid not participate in the match, then last.
m[n].second For all integers n < m.size(), the end of the sequence that
matched sub-expression n. Alternatively, if sub-expression
ndid not participate in the match, then last .
m[n].matched For all integers 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);
4Returns: The result of 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 =
§ 28.11.3 1124
c
ISO/IEC N????
regex_constants::match_default);
5Returns: The result of 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);
6Effects: Behaves “as if” by constructing an object what of type match_results<BidirectionalIterator>
and then returning the result of 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);
7Returns: 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);
8Returns: regex_search(s.begin(), s.end(), e, flags).
28.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);
1Effects: Constructs a regex_iterator object ias if by regex_iterator<BidirectionalIterator,
charT, traits> i(first, last, e, flags), and uses ito enumerate through all of the matches
mof 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
§ 28.11.4 1125
c
ISO/IEC N????
std::copy(first, last, out). If any matches are found then, for each such match, if !(flags &
regex_constants::format_no_copy), calls std::copy(m.prefix().first, m.prefix().second,
out), and then calls m.format(out, fmt, flags) for the first form of the function and 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 std::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 non-zero then only the first match found is replaced.
2Returns: 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);
3Effects: 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).
4Returns: 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);
5Effects: 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).
6Returns: result.
28.12 Regular expression iterators [re.iter]
28.12.1 Class template regex_iterator [re.regiter]
1The 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
§ 28.12.1 1126
c
ISO/IEC N????
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 de-
fault 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:
typedef basic_regex<charT, traits> regex_type;
typedef match_results<BidirectionalIterator> value_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
regex_iterator();
regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
const regex_type& re,
regex_constants::match_flag_type m =
regex_constants::match_default);
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
};
}
2An 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 ]
28.12.1.1 regex_iterator constructors [re.regiter.cnstr]
regex_iterator();
§ 28.12.1.1 1127
c
ISO/IEC N????
1Effects: 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);
2Effects: Initializes begin and end to aand 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.
28.12.1.2 regex_iterator comparisons [re.regiter.comp]
bool operator==(const regex_iterator& right) const;
1Returns: 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;
2Returns: !(*this == right).
28.12.1.3 regex_iterator indirection [re.regiter.deref]
const value_type& operator*() const;
1Returns: match.
const value_type* operator->() const;
2Returns: &match.
28.12.1.4 regex_iterator increment [re.regiter.incr]
regex_iterator& operator++();
1Effects: Constructs a local variable start of type BidirectionalIterator and initializes it with the
value of match[0].second.
2If the iterator holds a zero-length match and start == end the operator sets *this to the end-of-
sequence iterator and returns *this.
3Otherwise, 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.
4If 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).
§ 28.12.1.4 1128
c
ISO/IEC N????
If the call returns false the iterator sets *this to the end-of-sequence iterator. The iterator then
returns *this.
5In 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 iin the half-open range [0, match.size())
for which match[i].matched is true, match[i].position() shall return distance(begin, match[i].
first).
6[Note: This means that match[i].position() gives the offset from the beginning of the target se-
quence, which is often not the same as the offset from the sequence passed in the call to regex_search.
— end note ]
7It is unspecified how the implementation makes these adjustments.
8[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);
9Effects:
regex_iterator tmp = *this;
++(*this);
return tmp;
28.12.2 Class template regex_token_iterator [re.tokiter]
1The 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.
2When 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.
3After it is constructed, the iterator finds and stores a value regex_iterator<BidirectionalIterator>
position and sets the internal count Nto 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 Nis incremented; if
Nexceeds or equals subs.size(), then the iterator increments member position and sets count Nto zero.
4If 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.
5The 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.
6It 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.
§ 28.12.2 1129
c
ISO/IEC N????
namespace std {
template <class BidirectionalIterator,
class charT = typename iterator_traits<
BidirectionalIterator>::value_type,
class traits = regex_traits<charT> >
class regex_token_iterator {
public:
typedef basic_regex<charT, traits> regex_type;
typedef sub_match<BidirectionalIterator> value_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
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 std::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 <std::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(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:
typedef
regex_iterator<BidirectionalIterator, charT, traits> position_iterator; // exposition only
position_iterator position; // exposition only
const value_type* result; // exposition only
value_type suffix; // exposition only
std::size_t N; // exposition only
std::vector<int> subs; // exposition only
};
}
7Asuffix iterator is a regex_token_iterator object that points to a final sequence of characters at the end
§ 28.12.2 1130
c
ISO/IEC N????
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.
8[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 ]
9The current match is (*position).prefix() if subs[N] == -1, or (*position)[subs[N]] for any other
value of subs[N].
28.12.2.1 regex_token_iterator constructors [re.tokiter.cnstr]
regex_token_iterator();
1Effects: 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 std::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 <std::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);
2Requires: Each of the initialization values of submatches shall be >= -1.
3Effects: 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.
4Each constructor then sets Nto 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.
28.12.2.2 regex_token_iterator comparisons [re.tokiter.comp]
bool operator==(const regex_token_iterator& right) const;
§ 28.12.2.2 1131
c
ISO/IEC N????
1Returns: 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;
2Returns: !(*this == right).
28.12.2.3 regex_token_iterator indirection [re.tokiter.deref]
const value_type& operator*() const;
1Returns: *result.
const value_type* operator->() const;
2Returns: result.
28.12.2.4 regex_token_iterator increment [re.tokiter.incr]
regex_token_iterator& operator++();
1Effects: Constructs a local variable prev of type position_iterator, initialized with the value of
position.
2If *this is a suffix iterator, sets *this to an end-of-sequence iterator.
3Otherwise, if N + 1 < subs.size(), increments Nand sets result to the address of the current match.
4Otherwise, sets Nto 0 and increments position. If position is not an end-of-sequence iterator the
operator sets result to the address of the current match.
5Otherwise, 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).
6Otherwise, sets *this to an end-of-sequence iterator.
Returns: *this
regex_token_iterator& operator++(int);
7Effects: Constructs a copy tmp of *this, then calls ++(*this).
8Returns: tmp.
28.13 Modified ECMAScript regular expression grammar [re.grammar]
1The regular expression grammar recognized by basic_regex objects constructed with the ECMAScript flag
is that specified by ECMA-262, except as specified below.
2Objects 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.
3The following productions within the ECMAScript grammar are modified as follows:
§ 28.13 1132
c
ISO/IEC N????
ClassAtom ::
-
ClassAtomNoDash
ClassAtomExClass
ClassAtomCollatingElement
ClassAtomEquivalence
4The following new productions are then added:
ClassAtomExClass ::
[: ClassName :]
ClassAtomCollatingElement ::
[. ClassName .]
ClassAtomEquivalence ::
[= ClassName =]
ClassName ::
ClassNameCharacter
ClassNameCharacter ClassName
ClassNameCharacter ::
SourceCharacter but not one of "." "=" ":"
5The productions ClassAtomExClass,ClassAtomCollatingElement and ClassAtomEquivalence provide
functionality equivalent to that of the same features in regular expressions in POSIX.
6The 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
138.
7AClassName 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:]]
8AClassName 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.
9The results from multiple calls to traits_inst.lookup_classname can be bitwise OR’ed together and
subsequently passed to traits_inst.isctype.
10 AClassName 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.
§ 28.13 1133
c
ISO/IEC N????
11 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.
12 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 ]
13 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.
14 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 28.5.2
specified when using the regular expression object in one of the regular expression algorithms 28.11. 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 cand dare compared using the following rules:
1. if (flags() & regex_constants::icase) the two characters are equal if traits_inst.trans-
late_nocase(c) == traits_inst.translate_nocase(d);
2. otherwise, if flags() & regex_constants::collate the two characters are equal if traits_-
inst.translate(c) == traits_inst.translate(d);
3. otherwise, the two characters are equal if c == d.
During matching of a regular expression finite state machine against a sequence of characters, com-
parison of a collating element range c1-c2 against a character cis conducted as follows: if flags() &
regex_constants ::collate is false then the character cis matched if c1 <= c && c <= c2, other-
wise cis 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 char-
acter cis 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.
§ 28.13 1134
c
ISO/IEC N????
29 Atomic operations library [atomics]
29.1 General [atomics.general]
1This Clause describes components for fine-grained atomic access. This access is provided via operations on
atomic objects.
2The following subclauses describe atomics requirements and components for types and operations, as sum-
marized below.
Table 144 — Atomics library summary
Subclause Header(s)
29.3 Order and Consistency
29.4 Lock-free Property
29.5 Atomic Types <atomic>
29.6 Operations on Atomic Types
29.7 Flag Type and Operations
29.8 Fences
29.2 Header <atomic> synopsis [atomics.syn]
namespace std {
// 29.3, order and consistency
enum memory_order;
template <class T>
T kill_dependency(T y) noexcept;
// 29.4, 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
// 29.5, generic types
template<class T> struct atomic;
template<> struct atomic<integral >;
template<class T> struct atomic<T*>;
// 29.6.1, general operations on atomic types
// In the following declarations, atomic-type is either
// atomic<T> or a named base class for Tfrom
// Table 145 or inferred from Table 146 or from bool.
// If it is atomic<T>, then the declaration is a template
§ 29.2 1135
c
ISO/IEC N????
// declaration prefixed with template <class T>.
bool atomic_is_lock_free(const volatile atomic-type *) noexcept;
bool atomic_is_lock_free(const atomic-type *) noexcept;
void atomic_init(volatile atomic-type *, T) noexcept;
void atomic_init(atomic-type *, T) noexcept;
void atomic_store(volatile atomic-type *, T) noexcept;
void atomic_store(atomic-type *, T) noexcept;
void atomic_store_explicit(volatile atomic-type *, T, memory_order) noexcept;
void atomic_store_explicit(atomic-type *, T, memory_order) noexcept;
T atomic_load(const volatile atomic-type *) noexcept;
T atomic_load(const atomic-type *) noexcept;
T atomic_load_explicit(const volatile atomic-type *, memory_order) noexcept;
T atomic_load_explicit(const atomic-type *, memory_order) noexcept;
T atomic_exchange(volatile atomic-type *, T) noexcept;
T atomic_exchange(atomic-type *, T) noexcept;
T atomic_exchange_explicit(volatile atomic-type *, T, memory_order) noexcept;
T atomic_exchange_explicit(atomic-type *, T, memory_order) noexcept;
bool atomic_compare_exchange_weak(volatile atomic-type *, T*, T) noexcept;
bool atomic_compare_exchange_weak(atomic-type *, T*, T) noexcept;
bool atomic_compare_exchange_strong(volatile atomic-type *, T*, T) noexcept;
bool atomic_compare_exchange_strong(atomic-type *, T*, T) noexcept;
bool atomic_compare_exchange_weak_explicit(volatile atomic-type *, T*, T,
memory_order, memory_order) noexcept;
bool atomic_compare_exchange_weak_explicit(atomic-type *, T*, T.
memory_order, memory_order) noexcept;
bool atomic_compare)exchange_strong_explicit(volatile atomic-type *, T*, T,
memory_order, memory_order) noexcept;
bool atomic_compare_exchange_strong_explicit(atomic-type *, T*, T,
memory_order, memory_order) noexcept;
// 29.6.2, templated operations on atomic types
template <class T>
T atomic_fetch_add(volatile atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_add(atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_add_explicit(volatile atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_add_explicit(atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_sub(volatile atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_sub(atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_sub_explicit(volatile atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_sub_explicit(atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_and(volatile atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_and(atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_and_explicit(volatile atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_and_explicit(atomic<T>*, T, memory_order) noexcept;
§ 29.2 1136
c
ISO/IEC N????
template <class T>
T atomic_fetch_or(volatile atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_or(atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_or_explicit(volatile atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_or_explicit(atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_xor(volatile atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_xor(atomic<T>*, T) noexcept;
template <class T>
T atomic_fetch_xor_explicit(volatile atomic<T>*, T, memory_order) noexcept;
template <class T>
T atomic_fetch_xor_explicit(atomic<T>*, T, memory_order) noexcept;
// 29.6.3, arithmetic operations on atomic types
// In the following declarations, atomic-integral is either
// atomic<T> or a named base class for Tfrom
// Table 145 or inferred from Table 146.
// If it is atomic<T>, then the declaration is a template
// specialization declaration prefixed with template <>.
integral atomic_fetch_add(volatile atomic-integral *, integral ) noexcept;
integral atomic_fetch_add(atomic-integral *, integral ) noexcept;
integral atomic_fetch_add_explicit(volatile atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_add_explicit(atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_sub(volatile atomic-integral *, integral ) noexcept;
integral atomic_fetch_sub(atomic-integral *, integral ) noexcept;
integral atomic_fetch_sub_explicit(volatile atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_sub_explicit(atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_and(volatile atomic-integral *, integral ) noexcept;
integral atomic_fetch_and(atomic-integral *, integral ) noexcept;
integral atomic_fetch_and_explicit(volatile atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_and_explicit(atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_or(volatile atomic-integral *, integral ) noexcept;
integral atomic_fetch_or(atomic-integral *, integral ) noexcept;
integral atomic_fetch_or_explicit(volatile atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_or_explicit(atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_xor(volatile atomic-integral *, integral ) noexcept;
integral atomic_fetch_xor(atomic-integral *, integral ) noexcept;
integral atomic_fetch_xor_explicit(volatile atomic-integral *, integral , memory_order) noexcept;
integral atomic_fetch_xor_explicit(atomic-integral *, integral , memory_order) noexcept;
// 29.6.4, partial specializations for pointers
template <class T>
T* atomic_fetch_add(volatile atomic<T*>*, ptrdiff_t) noexcept;
template <class T>
T* atomic_fetch_add(atomic<T*>*, ptrdiff_t) noexcept;
template <class T>
T* atomic_fetch_add_explicit(volatile atomic<T*>*, ptrdiff_t, memory_order) noexcept;
template <class T>
T* atomic_fetch_add_explicit(atomic<T*>*, ptrdiff_t, memory_order) noexcept;
§ 29.2 1137
c
ISO/IEC N????
template <class T>
T* atomic_fetch_sub(volatile atomic<T*>*, ptrdiff_t) noexcept;
template <class T>
T* atomic_fetch_sub(atomic<T*>*, ptrdiff_t) noexcept;
template <class T>
T* atomic_fetch_sub_explicit(volatile atomic<T*>*, ptrdiff_t, memory_order) noexcept;
template <class T>
T* atomic_fetch_sub_explicit(atomic<T*>*, ptrdiff_t, memory_order) noexcept;
// 29.6.5, initialization
#define ATOMIC_VAR_INIT(value) see below
// 29.7, 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
// 29.8, fences
extern "C" void atomic_thread_fence(memory_order) noexcept;
extern "C" void atomic_signal_fence(memory_order) noexcept;
}
29.3 Order and consistency [atomics.order]
namespace std {
typedef enum memory_order {
memory_order_relaxed, memory_order_consume, memory_order_acquire,
memory_order_release, memory_order_acq_rel, memory_order_seq_cst
} memory_order;
}
1The enumeration memory_order specifies the detailed regular (non-atomic) memory synchronization order
as defined in 1.10 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 per-
forms a release operation on the affected memory location.
memory_order_consume: a load operation performs a consume operation on the affected memory
location.
memory_order_acquire,memory_order_acq_rel, and memory_order_seq_cst: a load operation per-
forms an acquire operation on the affected memory location.
[Note: Atomic operations specifying memory_order_relaxed are relaxed with respect to memory order-
ing. 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 ]
§ 29.3 1138
c
ISO/IEC N????
2An atomic operation Athat performs a release operation on an atomic object Msynchronizes with an atomic
operation Bthat performs an acquire operation on Mand takes its value from any side effect in the release
sequence headed by A.
3There shall be a single total order Son 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 Bthat loads a value from an atomic object Mobserves one of the following values:
the result of the last modification Aof Mthat precedes Bin S, if it exists, or
if Aexists, the result of some modification of Min the visible sequence of side effects with respect to
Bthat is not memory_order_seq_cst and that does not happen before A, or
if Adoes not exist, the result of some modification of Min the visible sequence of side effects with
respect to Bthat is not memory_order_seq_cst.
[Note: Although it is not explicitly required that Sinclude 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 ]
4For an atomic operation Bthat reads the value of an atomic object M, if there is a memory_order_seq_-
cst fence Xsequenced before B, then Bobserves either the last memory_order_seq_cst modification of M
preceding Xin the total order Sor a later modification of Min its modification order.
5For atomic operations Aand Bon an atomic object M, where Amodifies Mand Btakes its value, if there is
amemory_order_seq_cst fence Xsuch that Ais sequenced before Xand Bfollows Xin S, then Bobserves
either the effects of Aor a later modification of Min its modification order.
6For atomic operations Aand Bon an atomic object M, where Amodifies Mand Btakes its value, if there
are memory_order_seq_cst fences Xand Ysuch that Ais sequenced before X,Yis sequenced before B,
and Xprecedes Yin S, then Bobserves either the effects of Aor a later modification of Min its modification
order.
7For atomic modifications Aand Bof an atomic object M,Boccurs later than Ain the modification order
of Mif:
there is a memory_order_seq_cst fence Xsuch that Ais sequenced before X, and Xprecedes Bin S,
or
there is a memory_order_seq_cst fence Ysuch that Yis sequenced before B, and Aprecedes Yin
S, or
there are memory_order_seq_cst fences Xand Ysuch that Ais sequenced before X,Yis sequenced
before B, and Xprecedes Yin S.
8[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 ]
9An atomic store shall only store a value that has been computed from constants and program input values
by a finite sequence of program evaluations, such that each evaluation observes the values of variables as
computed by the last prior assignment in the sequence. The ordering of evaluations in this sequence shall
be such that:
if an evaluation Bobserves a value computed by Ain a different thread, then Bdoes not happen
before A, and
§ 29.3 1139
c
ISO/IEC N????
if an evaluation Ais included in the sequence, then every evaluation that assigns to the same variable
and happens before Ais included.
10 [Note: The second requirement disallows “out-of-thin-air” or “speculative” stores of atomics when relaxed
atomics are used. Since unordered operations are involved, evaluations may appear in this sequence out of
thread order. For example, with xand yinitially 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(42, memory_order_relaxed);
is allowed to produce r1 = r2 = 42. The sequence of evaluations justifying this consists of:
y.store(42, memory_order_relaxed);
r1 = y.load(memory_order_relaxed);
x.store(r1, memory_order_relaxed);
r2 = x.load(memory_order_relaxed);
On the other hand,
// 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);
may not produce r1 = r2 = 42, since there is no sequence of evaluations that results in the computation
of 42. In the absence of “relaxed” operations and read-modify-write operations with weaker than memory_-
order_acq_rel ordering, the second requirement has no impact. — end note ]
11 [Note: The requirements do allow r1 == r2 == 42 in the following example, with xand yinitially zero:
// Thread 1:
r1 = x.load(memory_order_relaxed);
if (r1 == 42) y.store(r1, memory_order_relaxed);
// Thread 2:
r2 = y.load(memory_order_relaxed);
if (r2 == 42) x.store(42, memory_order_relaxed);
However, implementations should not allow such behavior. — end note ]
12 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.
13 Implementations should make atomic stores visible to atomic loads within a reasonable amount of time.
template <class T>
T kill_dependency(T y) noexcept;
14 Effects: The argument does not carry a dependency to the return value (1.10).
15 Returns: y.
§ 29.3 1140
c
ISO/IEC N????
29.4 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
1The 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.
2The function atomic_is_lock_free (29.6) 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.
3[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 ]
29.5 Atomic types [atomics.types.generic]
namespace std {
template <class T> struct atomic {
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;
};
§ 29.5 1141
c
ISO/IEC N????
template <> struct atomic<integral > {
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;
§ 29.5 1142
c
ISO/IEC N????
integral operator^=(integral ) noexcept;
};
template <class T> struct atomic<T*> {
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;
};
}
1There is a generic class template atomic<T>. The type of the template argument Tshall be trivially
copyable (3.9). [ Note: Type arguments that are not also statically initializable may be difficult to use.
— end note ]
2The semantics of the operations on specializations of atomic are defined in 29.6.
3Specializations and instantiations of the atomic template shall have a deleted copy constructor, a deleted
§ 29.5 1143
c
ISO/IEC N????
copy assignment operator, and a constexpr value constructor.
4There shall be explicit 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 integral type integral, the specialization atomic<integral> provides additional atomic
operations appropriate to integral types. There shall be a specialization atomic<bool> which provides the
general atomic operations as specified in 29.6.1.
5The atomic integral specializations and the specialization atomic<bool> shall have standard layout. They
shall each have a trivial default constructor and a trivial destructor. They shall each support aggregate
initialization syntax.
6There shall be pointer partial specializations of the atomic class template. These specializations shall have
standard layout, trivial default constructors, and trivial destructors. They shall each support aggregate
initialization syntax.
7There shall be named types corresponding to the integral specializations of atomic, as specified in Table 145,
and a named type atomic_bool corresponding to the specified atomic<bool>. Each named type is either a
typedef to the corresponding specialization or a base class of the corresponding specialization. If it is a base
class, it shall support the same member functions as the corresponding specialization.
Table 145 — atomic integral typedefs
Named type Integral argument type
atomic_char char
atomic_schar signed char
atomic_uchar unsigned char
atomic_short short
atomic_ushort unsigned short
atomic_int int
atomic_uint unsigned int
atomic_long long
atomic_ulong unsigned long
atomic_llong long long
atomic_ullong unsigned long long
atomic_char16_t char16_t
atomic_char32_t char32_t
atomic_wchar_t wchar_t
8There shall be atomic typedefs corresponding to the typedefs in the header <inttypes.h> as specified in
Table 146.
9[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 ]
29.6 Operations on atomic types [atomics.types.operations]
29.6.1 General operations on atomic types [atomics.types.operations.general]
1The implementation shall provide the functions and function templates identified as “general operations on
atomic types” in 29.2.
§ 29.6.1 1144
c
ISO/IEC N????
Table 146 — atomic <inttypes.h> typedefs
Atomic typedef <inttypes.h> type
atomic_int_least8_t int_least8_t
atomic_uint_least8_t uint_least8_t
atomic_int_least16_t int_least16_t
atomic_uint_least16_t uint_least16_t
atomic_int_least32_t int_least32_t
atomic_uint_least32_t uint_least32_t
atomic_int_least64_t int_least64_t
atomic_uint_least64_t uint_least64_t
atomic_int_fast8_t int_fast8_t
atomic_uint_fast8_t uint_fast8_t
atomic_int_fast16_t int_fast16_t
atomic_uint_fast16_t uint_fast16_t
atomic_int_fast32_t int_fast32_t
atomic_uint_fast32_t uint_fast32_t
atomic_int_fast64_t int_fast64_t
atomic_uint_fast64_t uint_fast64_t
atomic_intptr_t intptr_t
atomic_uintptr_t uintptr_t
atomic_size_t size_t
atomic_ptrdiff_t ptrdiff_t
atomic_intmax_t intmax_t
atomic_uintmax_t uintmax_t
2In the declarations of these functions and function templates, the name atomic-type refers to either atomic<T>
or to a named base class for Tfrom Table 145 or inferred from Table 146.
29.6.2 Templated operations on atomic types [atomics.types.operations.templ]
1The implementation shall declare but not define the function templates identified as “templated operations
on atomic types” in 29.2.
29.6.3 Arithmetic operations on atomic types [atomics.types.operations.arith]
1The implementation shall provide the functions and function template specializations identified as “arith-
metic operations on atomic types” in 29.2.
2In the declarations of these functions and function template specializations, the name integral refers to an
integral type and the name atomic-integral refers to either atomic<integral >or to a named base class for
integral from Table 145 or inferred from Table 146.
29.6.4 Operations on atomic pointer types [atomics.types.operations.pointer]
1The implementation shall provide the function template specializations identified as “partial specializations
for pointers” in 29.2.
29.6.5 Requirements for operations on atomic types [atomics.types.operations.req]
1There are only a few kinds of operations on atomic types, though there are many instances on those kinds.
This section specifies each general kind. The specific instances are defined in 29.5,29.6.1,29.6.3, and 29.6.4.
2In the following operation definitions:
an Arefers to one of the atomic types.
a Crefers to its corresponding non-atomic type. The atomic_address atomic type corresponds to the
void* non-atomic type.
§ 29.6.5 1145
c
ISO/IEC N????
an Mrefers to type of the other argument for arithmetic operations. For integral atomic types, Mis
C. For atomic address types, Mis std::ptrdiff_t.
the non member functions not ending in _explicit have the semantics of their corresponding _-
explicit with memory_order arguments of memory_order_seq_cst.
3[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. Thus, volatile
qualified operations on non-volatile objects may be merged under some conditions. — end note ]
A::A() noexcept = default;
4Effects: leaves the atomic object in an uninitialized state. [ Note: These semantics ensure compatibility
with C. — end note ]
constexpr A::A(Cdesired) noexcept;
5Effects: Initializes the object with the value desired. Initialization is not an atomic operation (1.10).
[Note: it is possible to have an access to an atomic object Arace with its construction, for example
by communicating the address of the just-constructed object Ato another thread via memory_order_-
relaxed operations on a suitable atomic pointer variable, and then immediately accessing Ain the
receiving thread. This results in undefined behavior. — end note ]
#define ATOMIC_VAR_INIT(value) see below
6The 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 ]
bool atomic_is_lock_free(const volatile A* object) noexcept;
bool atomic_is_lock_free(const A* object) noexcept;
bool A::is_lock_free() const volatile noexcept;
bool A::is_lock_free() const noexcept;
7Returns: True if the object’s operations are lock-free, false otherwise.
void atomic_init(volatile A* object, Cdesired) noexcept;
void atomic_init(A* object, Cdesired) noexcept;
8Effects: 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 ]
§ 29.6.5 1146
c
ISO/IEC N????
void atomic_store(volatile A* object, Cdesired) noexcept;
void atomic_store(A* object, Cdesired) noexcept;
void atomic_store_explicit(volatile A* object, Cdesired, memory_order order) noexcept;
void atomic_store_explicit(A* object, Cdesired, memory_order order) noexcept;
void A::store(Cdesired, memory_order order = memory_order_seq_cst) volatile noexcept;
void A::store(Cdesired, memory_order order = memory_order_seq_cst) noexcept;
9Requires: The order argument shall not be memory_order_consume,memory_order_acquire, nor
memory_order_acq_rel.
10 Effects: Atomically replaces the value pointed to by object or by this with the value of desired.
Memory is affected according to the value of order.
C A ::operator=(Cdesired) volatile noexcept;
C A ::operator=(Cdesired) noexcept;
11 Effects: store(desired)
12 Returns: desired
Catomic_load(const volatile A* object) noexcept;
Catomic_load(const A* object) noexcept;
Catomic_load_explicit(const volatile A* object, memory_order) noexcept;
Catomic_load_explicit(const A* object, memory_order) noexcept;
C A ::load(memory_order order = memory_order_seq_cst) const volatile noexcept;
C A ::load(memory_order order = memory_order_seq_cst) const noexcept;
13 Requires: The order argument shall not be memory_order_release nor memory_order_acq_rel.
14 Effects: Memory is affected according to the value of order.
15 Returns: Atomically returns the value pointed to by object or by this.
A::operator C() const volatile noexcept;
A::operator C() const noexcept;
16 Effects: load()
17 Returns: The result of load().
Catomic_exchange(volatile A* object, Cdesired) noexcept;
Catomic_exchange(A* object, Cdesired) noexcept;
Catomic_exchange_explicit(volatile A* object, Cdesired, memory_order) noexcept;
Catomic_exchange_explicit(A* object, Cdesired, memory_order) noexcept;
C A ::exchange(Cdesired, memory_order order = memory_order_seq_cst) volatile noexcept;
C A ::exchange(Cdesired, memory_order order = memory_order_seq_cst) noexcept;
18 Effects: Atomically replaces the value pointed to by object or by this with desired. Memory
is affected according to the value of order. These operations are atomic read-modify-write opera-
tions (1.10).
19 Returns: Atomically returns the value pointed to by object or by this immediately before the effects.
§ 29.6.5 1147
c
ISO/IEC N????
bool atomic_compare_exchange_weak(volatile A* object, C* expected, Cdesired) noexcept;
bool atomic_compare_exchange_weak(A* object, C* expected, Cdesired) noexcept;
bool atomic_compare_exchange_strong(volatile A* object, C* expected, Cdesired) noexcept;
bool atomic_compare_exchange_strong(A* object, C* expected, Cdesired) noexcept;
bool atomic_compare_exchange_weak_explicit(volatile A* object, C* expected, Cdesired,
memory_order success, memory_order failure) noexcept;
bool atomic_compare_exchange_weak_explicit(A* object, C* expected, Cdesired,
memory_order success, memory_order failure) noexcept;
bool atomic_compare_exchange_strong_explicit(volatile A* object, C* expected, Cdesired,
memory_order success, memory_order failure) noexcept;
bool atomic_compare_exchange_strong_explicit(A* object, C* expected, Cdesired,
memory_order success, memory_order failure) noexcept;
bool A::compare_exchange_weak(C& expected, Cdesired,
memory_order success, memory_order failure) volatile noexcept;
bool A::compare_exchange_weak(C& expected, Cdesired,
memory_order success, memory_order failure) noexcept;
bool A::compare_exchange_strong(C& expected, Cdesired,
memory_order success, memory_order failure) volatile noexcept;
bool A::compare_exchange_strong(C& expected, Cdesired,
memory_order success, memory_order failure) noexcept;
bool A::compare_exchange_weak(C& expected, Cdesired,
memory_order order = memory_order_seq_cst) volatile noexcept;
bool A::compare_exchange_weak(C& expected, Cdesired,
memory_order order = memory_order_seq_cst) noexcept;
bool A::compare_exchange_strong(C& expected, Cdesired,
memory_order order = memory_order_seq_cst) volatile noexcept;
bool A::compare_exchange_strong(C& expected, Cdesired,
memory_order order = memory_order_seq_cst) noexcept;
20 Requires: The failure argument shall not be memory_order_release nor memory_order_acq_rel.
The failure argument shall be no stronger than the success argument.
21 Effects: Atomically, compares the contents of the memory pointed to by object or by this for equality
with that in expected, and if true, replaces the contents of the memory pointed to by object or by
this with that in desired, and if false, updates the contents of the memory in expected with the
contents of the memory pointed to by object or by this. Further, 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 the operation returns true, these operations are
atomic read-modify-write operations (1.10). Otherwise, these operations are atomic load operations.
22 Returns: The result of the comparison.
23 [Note: For example, the effect of atomic_compare_exchange_strong is
if (memcmp(object, expected, sizeof(*object)) == 0)
memcpy(object, &desired, sizeof(*object));
else
memcpy(expected, object, sizeof(*object));
— 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();
§ 29.6.5 1148
c
ISO/IEC N????
do {
desired = function(expected);
} while (!current.compare_exchange_weak(expected, desired));
— end example ]
24 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.
25 Remark: A weak compare-and-exchange operation may fail spuriously. That is, even when the con-
tents of memory referred to by expected and object 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 ]
26 [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 ]
27 The following operations perform arithmetic computations. The key, operator, and computation correspon-
dence is:
Table 147 — Atomic arithmetic computations
Key Op Computation Key Op Computation
add + addition sub - subtraction
or | bitwise inclusive or xor ˆ bitwise exclusive or
and & bitwise and
Catomic_fetch_key (volatile A* object, Moperand) noexcept;
Catomic_fetch_key (A* object, Moperand) noexcept;
Catomic_fetch_key _explicit(volatile A* object, Moperand, memory_order order) noexcept;
Catomic_fetch_key _explicit(A* object, Moperand, memory_order order) noexcept;
C A ::fetch_key (Moperand, memory_order order = memory_order_seq_cst) volatile noexcept;
C A ::fetch_key (Moperand, memory_order order = memory_order_seq_cst) noexcept;
28 Effects: Atomically replaces the value pointed to by object or by this with the result of the computa-
tion applied to the value pointed to by object or by this and the given operand. Memory is affected
according to the value of order. These operations are atomic read-modify-write operations (1.10).
29 Returns: Atomically, the value pointed to by object or by this immediately before the effects.
30 Remark: For signed integer types, arithmetic is defined to use two’s complement representation. There
are no undefined results. For address types, the result may be an undefined address, but the operations
otherwise have no undefined behavior.
§ 29.6.5 1149
c
ISO/IEC N????
C A ::operator op =(Moperand) volatile noexcept;
C A ::operator op =(Moperand) noexcept;
31 Effects: fetch_key (operand)
32 Returns: fetch_key (operand) op operand
C A ::operator++(int) volatile noexcept;
C A ::operator++(int) noexcept;
33 Returns: fetch_add(1)
C A ::operator--(int) volatile noexcept;
C A ::operator--(int) noexcept;
34 Returns: fetch_sub(1)
C A ::operator++() volatile noexcept;
C A ::operator++() noexcept;
35 Effects: fetch_add(1)
36 Returns: fetch_add(1) + 1
C A ::operator--() volatile noexcept;
C A ::operator--() noexcept;
37 Effects: fetch_sub(1)
38 Returns: fetch_sub(1) - 1
29.7 Flag type and operations [atomics.flag]
namespace std {
typedef 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;
} 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
}
§ 29.7 1150
c
ISO/IEC N????
1The atomic_flag type provides the classic test-and-set functionality. It has two states, set and clear.
2Operations on an object of type atomic_flag shall be lock-free. [ Note: Hence the operations should also
be address-free. No other type requires lock-free operations, so the atomic_flag type is the minimum
hardware-implemented type needed to conform to this International standard. The remaining types can be
emulated with atomic_flag, though with less than ideal properties. — end note ]
3The atomic_flag type shall have standard layout. It shall have a trivial default constructor, a deleted copy
constructor, a deleted copy assignment operator, and a trivial destructor.
4The 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. For a static-duration object, that initialization shall be static. It is
unspecified whether an uninitialized atomic_flag object has an initial state of set or clear.[ Example:
atomic_flag guard = ATOMIC_FLAG_INIT;
— end example ]
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;
5Effects: 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 (1.10).
6Returns: 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;
7Requires: The order argument shall not be memory_order_consume,memory_order_acquire, nor
memory_order_acq_rel.
8Effects: Atomically sets the value pointed to by object or by this to false. Memory is affected
according to the value of order.
29.8 Fences [atomics.fences]
1This 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.
2A release fence Asynchronizes with an acquire fence Bif there exist atomic operations Xand Y, both
operating on some atomic object M, such that Ais sequenced before X,Xmodifies M,Yis sequenced before
B, and Yreads the value written by Xor a value written by any side effect in the hypothetical release
sequence Xwould head if it were a release operation.
3A release fence Asynchronizes with an atomic operation Bthat performs an acquire operation on an atomic
object Mif there exists an atomic operation Xsuch that Ais sequenced before X,Xmodifies M, and B
reads the value written by Xor a value written by any side effect in the hypothetical release sequence X
would head if it were a release operation.
4An atomic operation Athat is a release operation on an atomic object Msynchronizes with an acquire fence
Bif there exists some atomic operation Xon Msuch that Xis sequenced before Band reads the value
written by Aor a value written by any side effect in the release sequence headed by A.
§ 29.8 1151
c
ISO/IEC N????
extern "C" void atomic_thread_fence(memory_order order) noexcept;
5Effects: 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;
6Effects: 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.
7Note: atomic_signal_fence can be used to specify the order in which actions performed by the thread
become visible to the signal handler.
8Note: 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.
§ 29.8 1152
c
ISO/IEC N????
30 Thread support library [thread]
30.1 General [thread.general]
1The following subclauses describe components to create and manage threads (1.10), perform mutual exclu-
sion, and communicate conditions and values between threads, as summarized in Table 148.
Table 148 — Thread support library summary
Subclause Header(s)
30.2 Requirements
30.3 Threads <thread>
30.4 Mutual exclusion <mutex>
<shared_mutex>
30.5 Condition variables <condition_variable>
30.6 Futures <future>
30.2 Requirements [thread.req]
30.2.1 Template parameter names [thread.req.paramname]
1Throughout this Clause, the names of template parameters are used to express type requirements.
2If a parameter is Predicate,operator() applied to the actual template argument shall return a value that
is convertible to bool.
30.2.2 Exceptions [thread.req.exception]
1Some functions described in this Clause are specified to throw exceptions of type system_error (19.5.6).
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 17.6.5.12.
[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 (19.5) and an exception of type system_error is thrown.
— end example ]
2The 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.
30.2.3 Native handles [thread.req.native]
1Several 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 ]
30.2.4 Timing specifications [thread.req.timing]
1Several 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 20.13.
§ 30.2.4 1153
c
ISO/IEC N????
2Implementations necessarily have some delay in returning from a timeout. Any overhead in interrupt re-
sponse, function return, and scheduling induces a “quality of implementation” delay, expressed as duration
Di. Ideally, this delay would be zero. Further, any contention for processor and memory resources induces
a “quality of management” delay, expressed as duration Dm. The delay durations may vary from timeout
to timeout, but in all cases shorter is better.
3The 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.339
Given a duration argument Dt, the real-time duration of the timeout is Dt+Di+Dm.
4The 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 Ct, the clock time point of the return
from timeout should be Ct+Di+Dmwhen the clock is not adjusted during the timeout. If the clock is
adjusted to the time Caduring the timeout, the behavior should be as follows:
if Ca> Ct, the waiting function should wake as soon as possible, i.e. Ca+Di+Dm, 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 Ca<=Ct, the waiting function should not time out until Clock::now() returns a time Cn>=Ct,
i.e. waking at Ct+Di+Dm. [ 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 Ctand 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 ]
5[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 ]
6The 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.
7Implementation-provided clocks that are used for these functions shall meet the TrivialClock requirements
(20.13.3).
8A 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 20.13.7 do not throw exceptions. — end note ]
30.2.5 Requirements for Lockable types [thread.req.lockable]
30.2.5.1 In general [thread.req.lockable.general]
1An 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.
2[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 ]
3The standard library templates unique_lock (30.4.2.2), lock_guard (30.4.2.1), lock,try_lock (30.4.3),
and condition_variable_any (30.5.2) all operate on user-supplied lockable objects. The BasicLockable
339) All implementations for which standard time units are meaningful must necessarily have a steady clock within their
hardware implementation.
§ 30.2.5.1 1154
c
ISO/IEC N????
requirements, the Lockable requirements, and the TimedLockable requirements list the requirements im-
posed 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 ]
30.2.5.2 BasicLockable requirements [thread.req.lockable.basic]
1A type Lmeets the BasicLockable requirements if the following expressions are well-formed and have the
specified semantics (mdenotes a value of type L).
m.lock()
2Effects: 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()
3Requires: The current execution agent shall hold a lock on m.
4Effects: Releases a lock on mheld by the current execution agent.
5Throws: Nothing.
30.2.5.3 Lockable requirements [thread.req.lockable.req]
1A type Lmeets the Lockable requirements if it meets the BasicLockable requirements and the following
expressions are well-formed and have the specified semantics (mdenotes a value of type L).
m.try_lock()
2Effects: 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.
3Return type: bool.
4Returns: true if the lock was acquired, false otherwise.
30.2.5.4 TimedLockable requirements [thread.req.lockable.timed]
1A type Lmeets the TimedLockable requirements if it meets the Lockable requirements and the following
expressions are well-formed and have the specified semantics (mdenotes a value of type L,rel_time denotes
a value of an instantiation of duration (20.13.5), and abs_time denotes a value of an instantiation of
time_point (20.13.6)).
m.try_lock_for(rel_time)
2Effects: attempts to acquire a lock for the current execution agent within the relative timeout (30.2.4)
specified by rel_time. The function shall not return within the timeout specified by rel_time unless
it has obtained a lock on mfor the current execution agent. If an exception is thrown then a lock shall
not have been acquired for the current execution agent.
3Return type: bool.
4Returns: true if the lock was acquired, false otherwise.
m.try_lock_until(abs_time)
5Effects: attempts to acquire a lock for the current execution agent before the absolute timeout (30.2.4)
specified by abs_time. The function shall not return before the timeout specified by abs_time unless
it has obtained a lock on mfor the current execution agent. If an exception is thrown then a lock shall
not have been acquired for the current execution agent.
6Return type: bool.
7Returns: true if the lock was acquired, false otherwise.
§ 30.2.5.4 1155
c
ISO/IEC N????
30.2.6 decay_copy [thread.decaycopy]
1In 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); }
30.3 Threads [thread.threads]
130.3 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 ]
Header <thread> synopsis
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);
}
}
30.3.1 Class thread [thread.thread.class]
1The 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: Athread 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;
typedef implementation-defined native_handle_type; // See 30.2.3
// 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:
§ 30.3.1 1156
c
ISO/IEC N????
void swap(thread&) noexcept;
bool joinable() const noexcept;
void join();
void detach();
id get_id() const noexcept;
native_handle_type native_handle(); // See 30.2.3
// static members:
static unsigned hardware_concurrency() noexcept;
};
}
30.3.1.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>;
}
1An 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 (30.3.1). 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 std::thread object that does not represent threads
of execution.
2thread::id shall be a trivially copyable class (Clause 9). The library may reuse the value of a thread::id
of a terminated thread that can no longer be joined.
3[Note: Relational operators allow thread::id objects to be used as keys in associative containers. — end
note ]
id() noexcept;
4Effects: Constructs an object of type id.
5Postconditions: The constructed object does not represent a thread of execution.
bool operator==(thread::id x, thread::id y) noexcept;
6Returns: true only if xand yrepresent the same thread of execution or neither xnor yrepresents a
thread of execution.
§ 30.3.1.1 1157
c
ISO/IEC N????
bool operator!=(thread::id x, thread::id y) noexcept;
7Returns: !(x == y)
bool operator<(thread::id x, thread::id y) noexcept;
8Returns: A value such that operator< is a total ordering as described in 25.4.
bool operator<=(thread::id x, thread::id y) noexcept;
9Returns: !(y < x)
bool operator>(thread::id x, thread::id y) noexcept;
10 Returns: y<x
bool operator>=(thread::id x, thread::id y) noexcept;
11 Returns: !(x < y)
template<class charT, class traits>
basic_ostream<charT, traits>&
operator<< (basic_ostream<charT, traits>&& out, thread::id id);
12 Effects: Inserts an unspecified text representation of id into out. For two objects of type thread::id
xand 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.
13 Returns: out
template <> struct hash<thread::id>;
14 The template specialization shall meet the requirements of class template hash (20.10.12).
30.3.1.2 thread constructors [thread.thread.constr]
thread() noexcept;
1Effects: Constructs a thread object that does not represent a thread of execution.
2Postcondition: get_id() == id()
template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
3Requires: Fand each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE (DECAY_-
COPY ( std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) (20.10.2) shall be a
valid expression.
4Effects: 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
§ 30.3.1.2 1158
c
ISO/IEC N????
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))...) ter-
minates with an uncaught exception, std::terminate shall be called.
5Synchronization: The completion of the invocation of the constructor synchronizes with the beginning
of the invocation of the copy of f.
6Postconditions: get_id() != id().*this represents the newly started thread.
7Throws: system_error if unable to start the new thread.
8Error conditions:
resource_unavailable_try_again — the system lacked the necessary resources to create an-
other thread, or the system-imposed limit on the number of threads in a process would be ex-
ceeded.
thread(thread&& x) noexcept;
9Effects: Constructs an object of type thread from x, and sets xto a default constructed state.
10 Postconditions: x.get_id() == id() and get_id() returns the value of x.get_id() prior to the
start of construction.
30.3.1.3 thread destructor [thread.thread.destr]
~thread();
1If joinable(), calls std::terminate(). Otherwise, has no effects. [ Note: Either implicitly detach-
ing 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 raised. Thus the pro-
grammer must ensure that the destructor is never executed while the thread is still joinable. — end
note ]
30.3.1.4 thread assignment [thread.thread.assign]
thread& operator=(thread&& x) noexcept;
1Effects: If joinable(), calls std::terminate(). Otherwise, assigns the state of xto *this and sets
xto a default constructed state.
2Postconditions: x.get_id() == id() and get_id() returns the value of x.get_id() prior to the
assignment.
3Returns: *this
30.3.1.5 thread members [thread.thread.member]
void swap(thread& x) noexcept;
1Effects: Swaps the state of *this and x.
bool joinable() const noexcept;
2Returns: get_id() != id()
void join();
§ 30.3.1.5 1159
c
ISO/IEC N????
3Requires: joinable() is true.
4Effects: Blocks until the thread represented by *this has completed.
5Synchronization: The completion of the thread represented by *this synchronizes with (1.10) the
corresponding successful join() return. [ Note: Operations on *this are not synchronized. — end
note ]
6Postconditions: The thread represented by *this has completed. get_id() == id().
7Throws: system_error when an exception is required (30.2.2).
8Error conditions:
resource_deadlock_would_occur — if deadlock is detected or this->get_id() == std::this_-
thread::get_id().
no_such_process — if the thread is not valid.
invalid_argument — if the thread is not joinable.
void detach();
9Requires: joinable() is true.
10 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.
11 Postcondition: get_id() == id().
12 Throws: system_error when an exception is required (30.2.2).
13 Error conditions:
no_such_process — if the thread is not valid.
invalid_argument — if the thread is not joinable.
id get_id() const noexcept;
14 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.
30.3.1.6 thread static members [thread.thread.static]
unsigned hardware_concurrency() noexcept;
1Returns: 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.
30.3.1.7 thread specialized algorithms [thread.thread.algorithm]
void swap(thread& x, thread& y) noexcept;
1Effects: x.swap(y)
§ 30.3.1.7 1160
c
ISO/IEC N????
30.3.2 Namespace this_thread [thread.thread.this]
namespace std {
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);
}
}
thread::id this_thread::get_id() noexcept;
1Returns: 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;
2Effects: Offers the implementation the opportunity to reschedule.
3Synchronization: None.
template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
4Effects: Blocks the calling thread for the absolute timeout (30.2.4) specified by abs_time.
5Synchronization: None.
6Throws: Timeout-related exceptions (30.2.4).
template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
7Effects: Blocks the calling thread for the relative timeout (30.2.4) specified by rel_time.
8Synchronization: None.
9Throws: Timeout-related exceptions (30.2.4).
30.4 Mutual exclusion [thread.mutex]
1This section provides mechanisms for mutual exclusion: mutexes, locks, and call once. These mechanisms
ease the production of race-free programs (1.10).
Header <mutex> synopsis
namespace std {
class mutex;
class recursive_mutex;
class timed_mutex;
class recursive_timed_mutex;
struct defer_lock_t { };
§ 30.4 1161
c
ISO/IEC N????
struct try_to_lock_t { };
struct adopt_lock_t { };
constexpr defer_lock_t defer_lock { };
constexpr try_to_lock_t try_to_lock { };
constexpr adopt_lock_t adopt_lock { };
template <class Mutex> class lock_guard;
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 {
constexpr once_flag() noexcept;
once_flag(const once_flag&) = delete;
once_flag& operator=(const once_flag&) = delete;
};
template<class Callable, class ...Args>
void call_once(once_flag& flag, Callable&& func, Args&&... args);
}
Header <shared_mutex> synopsis
namespace std {
class shared_mutex;
template <class Mutex> class shared_lock;
template <class Mutex>
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
}
30.4.1 Mutex requirements [thread.mutex.requirements]
30.4.1.1 In general [thread.mutex.requirements.general]
1A mutex object facilitates protection against data races and allows safe synchronization of data between
execution agents (30.2.5). 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. The mutex types supplied by the standard library
provide exclusive ownership semantics: only one thread may own the mutex at a time. Both recursive and
non-recursive mutexes are supplied.
30.4.1.2 Mutex types [thread.mutex.requirements.mutex]
1The mutex types are the standard library types std::mutex,std::recursive_mutex,std::timed_mutex,
std::recursive_timed_mutex, and std::shared_mutex. They shall meet the requirements set out in this
section. In this description, mdenotes an object of a mutex type.
2The mutex types shall meet the Lockable requirements (30.2.5.3).
3The 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.
4The 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.
§ 30.4.1.2 1162
c
ISO/IEC N????
operation_not_permitted — if the thread does not have the privilege to perform the operation.
device_or_resource_busy — if any native handle type manipulated is already locked.
invalid_argument — if any native handle type manipulated as part of mutex construction is incorrect.
5The implementation shall provide lock and unlock operations, as described below. For purposes of determin-
ing the existence of a data race, these behave as atomic operations (1.10). 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 (1.10) 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 ]
6The expression m.lock() shall be well-formed and have the following semantics:
7Requires: If mis of type std::mutex or std::timed_mutex, the calling thread does not own the mutex.
8Effects: Blocks the calling thread until ownership of the mutex can be obtained for the calling thread.
9Postcondition: The calling thread owns the mutex.
10 Return type: void
11 Synchronization: Prior unlock() operations on the same object shall synchronize with (1.10) this
operation.
12 Throws: system_error when an exception is required (30.2.2).
13 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.
device_or_resource_busy — if the mutex is already locked and blocking is not possible.
14 The expression m.try_lock() shall be well-formed and have the following semantics:
15 Requires: If mis of type std::mutex or std::timed_mutex, the calling thread does not own the mutex.
16 Effects: Attempts to obtain ownership of the mutex for the calling thread without blocking. If own-
ership 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 29). — end note ] An implementation should ensure that try_lock() does not consistently
return false in the absence of contending mutex acquisitions.
17 Return type: bool
18 Returns: true if ownership of the mutex was obtained for the calling thread, otherwise false.
19 Synchronization: If try_lock() returns true, prior unlock() operations on the same object synchro-
nize with (1.10) 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 ]
20 Throws: Nothing.
21 The expression m.unlock() shall be well-formed and have the following semantics:
§ 30.4.1.2 1163
c
ISO/IEC N????
22 Requires: The calling thread shall own the mutex.
23 Effects: Releases the calling thread’s ownership of the mutex.
24 Return type: void
25 Synchronization: This operation synchronizes with (1.10) subsequent lock operations that obtain own-
ership on the same object.
26 Throws: Nothing.
30.4.1.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();
typedef implementation-defined native_handle_type; // See 30.2.3
native_handle_type native_handle(); // See 30.2.3
};
}
1The 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().
2[Note: After a thread Ahas called unlock(), releasing a mutex, it is possible for another thread Bto lock
the same mutex, observe that it is no longer in use, unlock it, and destroy it, before thread Aappears to
have returned from its unlock call. Implementations are required to handle such scenarios correctly, as long
as thread Adoesn’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 ]
3The class mutex shall satisfy all the Mutex requirements (30.4.1). It shall be a standard-layout class
(Clause 9).
4[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 ]
5The 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.
30.4.1.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;
§ 30.4.1.2.2 1164
c
ISO/IEC N????
void lock();
bool try_lock() noexcept;
void unlock();
typedef implementation-defined native_handle_type; // See 30.2.3
native_handle_type native_handle(); // See 30.2.3
};
}
1The 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.
2The class recursive_mutex shall satisfy all the Mutex requirements (30.4.1). It shall be a standard-layout
class (Clause 9).
3A 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.
4The 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.
30.4.1.3 Timed mutex types [thread.timedmutex.requirements]
1The timed mutex types are the standard library types std::timed_mutex,std::recursive_timed_mutex,
and std::shared_mutex. They shall meet the requirements set out below. In this description, mdenotes an
object of a mutex type, rel_time denotes an object of an instantiation of duration (20.13.5), and abs_time
denotes an object of an instantiation of time_point (20.13.6).
2The timed mutex types shall meet the TimedLockable requirements (30.2.5.4).
3The expression m.try_lock_for(rel_time) shall be well-formed and have the following semantics:
4Requires: If mis of type std::timed_mutex, the calling thread does not own the mutex.
5Effects: The function attempts to obtain ownership of the mutex within the relative timeout (30.2.4)
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 ]
6Return type: bool
7Returns: true if ownership was obtained, otherwise false.
8Synchronization: If try_lock_for() returns true, prior unlock() operations on the same object
synchronize with (1.10) this operation.
9Throws: Timeout-related exceptions (30.2.4).
10 The expression m.try_lock_until(abs_time) shall be well-formed and have the following semantics:
11 Requires: If mis of type std::timed_mutex, the calling thread does not own the mutex.
12 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
§ 30.4.1.3 1165
c
ISO/IEC N????
shall return before the absolute timeout (30.2.4) 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 ]
13 Return type: bool
14 Returns: true if ownership was obtained, otherwise false.
15 Synchronization: If try_lock_until() returns true, prior unlock() operations on the same object
synchronize with (1.10) this operation.
16 Throws: Timeout-related exceptions (30.2.4).
30.4.1.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();
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();
typedef implementation-defined native_handle_type; // See 30.2.3
native_handle_type native_handle(); // See 30.2.3
};
}
1The 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).
2The class timed_mutex shall satisfy all of the TimedMutex requirements (30.4.1.3). It shall be a standard-
layout class (Clause 9).
3The 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.
30.4.1.3.2 Class recursive_timed_mutex [thread.timedmutex.recursive]
namespace std {
class recursive_timed_mutex {
§ 30.4.1.3.2 1166
c
ISO/IEC N????
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();
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();
typedef implementation-defined native_handle_type; // See 30.2.3
native_handle_type native_handle(); // See 30.2.3
};
}
1The 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).
2The class recursive_timed_mutex shall satisfy all of the TimedMutex requirements (30.4.1.3). It shall be a
standard-layout class (Clause 9).
3A 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.
4The 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.
30.4.1.4 Shared mutex types [thread.sharedmutex.requirements]
1The standard library type std::shared_mutex is a shared mutex type. Shared mutex types shall meet the
requirements of timed mutex types (30.4.1.3), and additionally shall meet the requirements set out below.
In this description, mdenotes an object of a mutex type, rel_type denotes an object of an instantiation of
duration (20.13.5), and abs_time denotes an object of an instantiation of time_point (20.13.6).
2In addition to the exclusive lock ownership mode specified in 30.4.1.2, 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.
§ 30.4.1.4 1167
c
ISO/IEC N????
3The expression m.lock_shared() shall be well-formed and have the following semantics:
4Requires: The calling thread has no ownership of the mutex.
5Effects: Blocks the calling thread until shared ownership of the mutex can be obtained for the calling
thread.
6Postcondition: The calling thread has a shared lock on the mutex.
7Return type: void.
8Synchronization: Prior unlock() operations on the same object shall synchronize with (1.10) this
operation.
9Throws: system_error when an exception is required (30.2.2).
10 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.
device_or_resource_busy — if the mutex is already locked and blocking is not possible.
11 The expression m.unlock_shared() shall be well-formed and have the following semantics:
12 Requires: The calling thread shall hold a shared lock on the mutex.
13 Effects: Releases a shared lock on the mutex held by the calling thread.
14 Return type: void.
15 Synchronization: This operation synchronizes with (1.10) subsequent lock() operations that obtain
ownership on the same object.
16 Throws: Nothing.
17 The expression m.try_lock_shared() shall be well-formed and have the following semantics:
18 Requires: The calling thread has no ownership of the mutex.
19 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.
20 Return type: bool.
21 Returns: true if the shared ownership lock was acquired, false otherwise.
22 Synchronization: If try_lock_shared() returns true, prior unlock() operations on the same object
synchronize with (1.10) this operation.
23 Throws: Nothing.
24 The expression m.try_lock_shared_for(rel_time) shall be well-formed and have the following semantics:
25 Requires: The calling thread has no ownership of the mutex.
26 Effects: If the tick period of rel_time is not exactly convertible to the native tick period, the
duration shall be rounded up to the nearest native tick period. Attempts to obtain shared lock
ownership for the calling thread within the relative timeout (30.2.4) 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 ]
§ 30.4.1.4 1168
c
ISO/IEC N????
27 Return type: bool.
28 Returns: true if the shared lock was acquired, false otherwise.
29 Synchronization: If try_lock_shared_for() returns true, prior unlock() operations on the same
object synchronize with (1.10) this operation.
30 Throws: Nothing.
31 The expression m.try_lock_shared_until(abs_time) shall be well-formed and have the following seman-
tics:
32 Requires: The calling thread has no ownership of the mutex.
33 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 (30.2.4) 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 ]
34 Return type: bool.
35 Returns: true if the shared lock was acquired, false otherwise.
36 Synchronization: If try_lock_shared_until() returns true, prior unlock() operations on the same
object synchronize with (1.10) this operation.
37 Throws: Nothing.
30.4.1.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();
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
§ 30.4.1.4.1 1169
c
ISO/IEC N????
try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock_shared();
};
}
1The class shared_mutex provides a non-recursive mutex with shared ownership semantics.
2The class shared_mutex shall satisfy all of the SharedMutex requirements (30.4.1.4). It shall be a standard-
layout class (Clause 9).
3The 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.
a thread terminates while possessing any ownership of a shared_mutex.
30.4.2 Locks [thread.lock]
1Alock 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 ]
2Some 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
constexpr defer_lock_t defer_lock { };
constexpr try_to_lock_t try_to_lock { };
constexpr adopt_lock_t adopt_lock { };
}
30.4.2.1 Class template lock_guard [thread.lock.guard]
namespace std {
template <class Mutex>
class lock_guard {
public:
typedef Mutex mutex_type;
explicit lock_guard(mutex_type& m);
lock_guard(mutex_type& m, adopt_lock_t);
~lock_guard();
lock_guard(lock_guard const&) = delete;
lock_guard& operator=(lock_guard const&) = delete;
private:
mutex_type& pm; // exposition only
};
§ 30.4.2.1 1170
c
ISO/IEC N????
}
1An 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 (3.8). 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 (30.2.5.2).
explicit lock_guard(mutex_type& m);
2Requires: If mutex_type is not a recursive mutex, the calling thread does not own the mutex m.
3Effects: m.lock()
4Postcondition: &pm == &m
lock_guard(mutex_type& m, adopt_lock_t);
5Requires: The calling thread owns the mutex m.
6Postcondition: &pm == &m
7Throws: Nothing.
~lock_guard();
8Effects: pm.unlock()
30.4.2.2 Class template unique_lock [thread.lock.unique]
namespace std {
template <class Mutex>
class unique_lock {
public:
typedef Mutex mutex_type;
// 30.4.2.2.1, 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(unique_lock const&) = delete;
unique_lock& operator=(unique_lock const&) = delete;
unique_lock(unique_lock&& u) noexcept;
unique_lock& operator=(unique_lock&& u) noexcept;
// 30.4.2.2.2, locking:
void lock();
bool try_lock();
§ 30.4.2.2 1171
c
ISO/IEC N????
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();
// 30.4.2.2.3, modifiers:
void swap(unique_lock& u) noexcept;
mutex_type* release() noexcept;
// 30.4.2.2.4, 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>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
}
1An 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 (3.8) of the unique_lock object. The supplied Mutex
type shall meet the BasicLockable requirements (30.2.5.2).
2[Note: unique_lock<Mutex> meets the BasicLockable requirements. If Mutex meets the Lockable re-
quirements (30.2.5.3), unique_lock<Mutex> also meets the Lockable requirements; if Mutex meets the
TimedLockable requirements (30.2.5.4), unique_lock<Mutex> also meets the TimedLockable requirements.
— end note ]
30.4.2.2.1 unique_lock constructors, destructor, and assignment [thread.lock.unique.cons]
unique_lock() noexcept;
1Effects: Constructs an object of type unique_lock.
2Postconditions: pm == 0 and owns == false.
explicit unique_lock(mutex_type& m);
3Requires: If mutex_type is not a recursive mutex the calling thread does not own the mutex.
4Effects: Constructs an object of type unique_lock and calls m.lock().
5Postconditions: pm == &m and owns == true.
unique_lock(mutex_type& m, defer_lock_t) noexcept;
6Effects: Constructs an object of type unique_lock.
7Postconditions: pm == &m and owns == false.
§ 30.4.2.2.1 1172
c
ISO/IEC N????
unique_lock(mutex_type& m, try_to_lock_t);
8Requires: The supplied Mutex type shall meet the Lockable requirements (30.2.5.3). If mutex_type is
not a recursive mutex the calling thread does not own the mutex.
9Effects: Constructs an object of type unique_lock and calls m.try_lock().
10 Postconditions: pm == &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);
11 Requires: The calling thread own the mutex.
12 Effects: Constructs an object of type unique_lock.
13 Postconditions: pm == &m and owns == true.
14 Throws: Nothing.
template <class Clock, class Duration>
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
15 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 (30.2.5.4).
16 Effects: Constructs an object of type unique_lock and calls m.try_lock_until(abs_time).
17 Postconditions: pm == &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);
18 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 (30.2.5.4).
19 Effects: Constructs an object of type unique_lock and calls m.try_lock_for(rel_time).
20 Postconditions: pm == &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;
21 Postconditions: pm == u_p.pm and owns == u_p.owns (where u_p is the state of ujust prior to this
construction), u.pm == 0 and u.owns == false.
unique_lock& operator=(unique_lock&& u) noexcept;
22 Effects: If owns calls pm->unlock().
23 Postconditions: pm == u_p.pm and owns == u_p.owns (where u_p is the state of ujust prior to this
construction), u.pm == 0 and u.owns == false.
24 [Note: With a recursive mutex it is possible for both *this and uto own the same mutex before the
assignment. In this case, *this will own the mutex after the assignment and uwill not. — end note ]
~unique_lock();
25 Effects: If owns calls pm->unlock().
§ 30.4.2.2.1 1173
c
ISO/IEC N????
30.4.2.2.2 unique_lock locking [thread.lock.unique.locking]
void lock();
1Effects: pm->lock()
2Postcondition: owns == true
3Throws: Any exception thrown by pm->lock().system_error if an exception is required (30.2.2).
system_error with an error condition of operation_not_permitted if pm is 0. system_error with
an error condition of resource_deadlock_would_occur if on entry owns is true.
bool try_lock();
4Requires: The supplied Mutex shall meet the Lockable requirements (30.2.5.3).
5Effects: pm->try_lock()
6Returns: The value returned by the call to try_lock().
7Postcondition: owns == res, where res is the value returned by the call to try_lock().
8Throws: Any exception thrown by pm->try_lock().system_error if an exception is required (30.2.2).
system_error with an error condition of operation_not_permitted if pm is 0. system_error with
an error condition of 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);
9Requires: The supplied Mutex type shall meet the TimedLockable requirements (30.2.5.4).
10 Effects: pm->try_lock_until(abs_time)
11 Returns: The value returned by the call to try_lock_until(abs_time).
12 Postcondition: owns == res, where res is the value returned by the call to try_lock_until(abs_-
time).
13 Throws: Any exception thrown by pm->try_lock_until().system_error if an exception is re-
quired (30.2.2). system_error with an error condition of operation_not_permitted if pm is 0.
system_error with an error condition of 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);
14 Requires: The supplied Mutex type shall meet the TimedLockable requirements (30.2.5.4).
15 Effects: pm->try_lock_for(rel_time).
16 Returns: The value returned by the call to try_lock_until(rel_time).
17 Postcondition: owns == res, where res is the value returned by the call to try_lock_for(rel_time).
18 Throws: Any exception thrown by pm->try_lock_for().system_error if an exception is required
(30.2.2). system_error with an error condition of operation_not_permitted if pm is 0. system_-
error with an error condition of resource_deadlock_would_occur if on entry owns is true.
void unlock();
§ 30.4.2.2.2 1174
c
ISO/IEC N????
19 Effects: pm->unlock()
20 Postcondition: owns == false
21 Throws: system_error when an exception is required (30.2.2).
22 Error conditions:
operation_not_permitted — if on entry owns is false.
30.4.2.2.3 unique_lock modifiers [thread.lock.unique.mod]
void swap(unique_lock& u) noexcept;
1Effects: Swaps the data members of *this and u.
mutex_type* release() noexcept;
2Returns: The previous value of pm.
3Postconditions: pm == 0 and owns == false.
template <class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
4Effects: x.swap(y)
30.4.2.2.4 unique_lock observers [thread.lock.unique.obs]
bool owns_lock() const noexcept;
1Returns: owns
explicit operator bool() const noexcept;
2Returns: owns
mutex_type *mutex() const noexcept;
3Returns: pm
30.4.2.3 Class template shared_lock [thread.lock.shared]
namespace std {
template <class Mutex>
class shared_lock {
public:
typedef Mutex mutex_type;
// Shared locking
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>
§ 30.4.2.3 1175
c
ISO/IEC N????
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(shared_lock const&) = delete;
shared_lock& operator=(shared_lock const&) = delete;
shared_lock(shared_lock&& u) noexcept;
shared_lock& operator=(shared_lock&& u) noexcept;
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();
// Setters
void swap(shared_lock& u) noexcept;
mutex_type* release() noexcept;
// Getters
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>
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
}// std
1An 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 trans-
ferred, 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 (3.8) of the shared_lock object.
The supplied Mutex type shall meet the shared mutex requirements (30.4.1.4).
2[Note: shared_lock<Mutex> meets the TimedLockable requirements (30.2.5.4). — end note ]
30.4.2.3.1 shared_lock constructors, destructor, and assignment [thread.lock.shared.cons]
shared_lock() noexcept;
1Effects: Constructs an object of type shared_lock.
2Postconditions: pm == nullptr and owns == false.
explicit shared_lock(mutex_type& m);
§ 30.4.2.3.1 1176
c
ISO/IEC N????
3Requires: The calling thread does not own the mutex for any ownership mode.
4Effects: Constructs an object of type shared_lock and calls m.lock_shared().
5Postconditions: pm == &m and owns == true.
shared_lock(mutex_type& m, defer_lock_t) noexcept;
6Effects: Constructs an object of type shared_lock.
7Postconditions: pm == &m and owns == false.
shared_lock(mutex_type& m, try_to_lock_t);
8Requires: The calling thread does not own the mutex for any ownership mode.
9Effects: Constructs an object of type shared_lock and calls m.try_lock_shared().
10 Postconditions: pm == &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);
11 Requires: The calling thread has shared ownership of the mutex.
12 Effects: Constructs an object of type shared_lock.
13 Postconditions: pm == &m and owns == true.
template <class Clock, class Duration>
shared_lock(mutex_type& m,
const chrono::time_point<Clock, Duration>& abs_time);
14 Requires: The calling thread does not own the mutex for any ownership mode.
15 Effects: Constructs an object of type shared_lock and calls m.try_lock_shared_until(abs_time).
16 Postconditions: pm == &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);
17 Requires: The calling thread does not own the mutex for any ownership mode.
18 Effects: Constructs an object of type shared_lock and calls m.try_lock_shared_for(rel_time).
19 Postconditions: pm == &m and owns == res where res is the value returned by the call to m.try_-
lock_shared_for(rel_time).
~shared_lock();
20 Effects: If owns calls pm->unlock_shared().
shared_lock(shared_lock&& sl) noexcept;
§ 30.4.2.3.1 1177
c
ISO/IEC N????
21 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;
22 Effects: If owns calls pm->unlock_shared().
23 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.
30.4.2.3.2 shared_lock locking [thread.lock.shared.locking]
void lock();
1Effects: pm->lock_shared().
2Postconditions: owns == true.
3Throws: Any exception thrown by pm->lock_shared().system_error if an exception is required (30.2.2).
system_error with an error condition of operation_not_permitted if pm is nullptr.system_error
with an error condition of resource_deadlock_would_occur if on entry owns is true.
bool try_lock();
4Effects: pm->try_lock_shared().
5Returns: The value returned by the call to pm->try_lock_shared().
6Postconditions: owns == res, where res is the value returned by the call to pm->try_lock_shared().
7Throws: Any exception thrown by pm->try_lock_shared().system_error if an exception is re-
quired (30.2.2). system_error with an error condition of operation_not_permitted if pm is nullptr.
system_error with an error condition of 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);
8Effects: pm->try_lock_shared_until(abs_time).
9Returns: The value returned by the call to pm->try_lock_shared_until(abs_time).
10 Postconditions: owns == res, where res is the value returned by the call to pm->try_lock_shared_-
until(abs_time).
11 Throws: Any exception thrown by pm->try_lock_shared_until(abs_time).system_error if an
exception is required (30.2.2). system_error with an error condition of operation_not_permitted
if pm is nullptr.system_error with an error condition of 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);
12 Effects: pm->try_lock_shared_for(rel_time).
13 Returns: The value returned by the call to pm->try_lock_shared_for(rel_time).
14 Postconditions: owns == res, where res is the value returned by the call to pm->try_lock_shared_-
for(rel_time).
§ 30.4.2.3.2 1178
c
ISO/IEC N????
15 Throws: Any exception thrown by pm->try_lock_shared_for(rel_time).system_error if an ex-
ception is required (30.2.2). system_error with an error condition of operation_not_permitted
if pm is nullptr.system_error with an error condition of resource_deadlock_would_occur if on
entry owns is true.
void unlock();
16 Effects: pm->unlock_shared().
17 Postconditions: owns == false.
18 Throws: system_error when an exception is required (30.2.2).
19 Error conditions:
operation_not_permitted — if on entry owns is false.
30.4.2.3.3 shared_lock modifiers [thread.lock.shared.mod]
void swap(shared_lock& sl) noexcept;
1Effects: Swaps the data members of *this and sl.
mutex_type* release() noexcept;
2Returns: The previous value of pm.
3Postconditions: pm == nullptr and owns == false.
template <class Mutex>
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
4Effects: x.swap(y).
30.4.2.3.4 shared_lock observers [thread.lock.shared.obs]
bool owns_lock() const noexcept;
1Returns: owns.
explicit operator bool () const noexcept;
2Returns: owns.
mutex_type* mutex() const noexcept;
3Returns: pm.
§ 30.4.2.3.4 1179
c
ISO/IEC N????
30.4.3 Generic locking algorithms [thread.lock.algorithm]
template <class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
1Requires: Each template parameter type shall meet the Lockable requirements. [ Note: The unique_-
lock class template meets these requirements when suitably instantiated. — end note ]
2Effects: 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().
3Returns: -1 if all calls to try_lock() returned true, otherwise a 0-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&...);
4Requires: Each template parameter type shall meet the Lockable requirements, [ Note: The unique_-
lock class template meets these requirements when suitably instantiated. — end note ]
5Effects: 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().
30.4.4 Call once [thread.once]
The class once_flag is an opaque data structure that call_once uses to initialize data without causing
a data race or deadlock.
30.4.4.1 Struct once_flag [thread.once.onceflag]
constexpr once_flag() noexcept;
1Effects: Constructs an object of type once_flag.
2Synchronization: The construction of a once_flag object is not synchronized.
3Postcondition: 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.
30.4.4.2 Function call_once [thread.once.callonce]
template<class Callable, class ...Args>
void call_once(once_flag& flag, Callable&& func, Args&&... args);
1Requires: Callable and each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE (
DECAY_COPY ( std::forward<Callable>(func)), DECAY_COPY (std::forward<Args>(args))...)
(20.10.2) shall be a valid expression.
2Effects: 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 (DECAY_-
COPY ( std::forward<Callable>(func)), DECAY_COPY (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
§ 30.4.4.2 1180
c
ISO/IEC N????
returning execution. [ Note: passive executions allow other threads to reliably observe the results
produced by the earlier returning execution. — end note ]
3Synchronization: For any given once_flag: all active executions occur in a total order; completion
of an active execution synchronizes with (1.10) the start of the next one in this total order; and the
returning execution synchronizes with the return from all passive executions.
4Throws: system_error when an exception is required (30.2.2), or any exception thrown by func.
5[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 ]
30.5 Condition variables [thread.condition]
1Condition 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.
2Condition variables permit concurrent invocation of the wait,wait_for,wait_until,notify_one and
notify_all member functions.
3The 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. the release of the mutex and entry into the waiting state;
2. the unblocking of the wait; and
3. the reacquisition of the lock.
§ 30.5 1181
c
ISO/IEC N????
4The 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.
5Condition variable construction and destruction need not be synchronized.
Header condition_variable synopsis
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 };
}
void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
6Requires: 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.
7Effects: 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();
8Synchronization: The implied lk.unlock() call is sequenced after the destruction of all objects with
thread storage duration associated with the current thread.
9Note: 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.
10 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.
30.5.1 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;
§ 30.5.1 1182
c
ISO/IEC N????
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);
typedef implementation-defined native_handle_type; // See 30.2.3
native_handle_type native_handle(); // See 30.2.3
};
}
1The class condition_variable shall be a standard-layout class (Clause 9).
condition_variable();
2Effects: Constructs an object of type condition_variable.
3Throws: system_error when an exception is required (30.2.2).
4Error conditions:
resource_unavailable_try_again — if some non-memory resource limitation prevents initial-
ization.
~condition_variable();
5Requires: 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 ]
6Effects: Destroys the object.
void notify_one() noexcept;
7Effects: If any threads are blocked waiting for *this, unblocks one of those threads.
void notify_all() noexcept;
§ 30.5.1 1183
c
ISO/IEC N????
8Effects: Unblocks all threads that are blocked waiting for *this.
void wait(unique_lock<mutex>& lock);
9Requires: 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.
10 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.
If the function exits via an exception, lock.lock() shall be called prior to exiting the function
scope.
11 Postcondition: lock.owns_lock() is true and lock.mutex() is locked by the calling thread.
12 Throws: system_error when an exception is required (30.2.2).
13 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Predicate>
void wait(unique_lock<mutex>& lock, Predicate pred);
14 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.
15 Effects: Equivalent to:
while (!pred())
wait(lock);
16 Postcondition: lock.owns_lock() is true and lock.mutex() is locked by the calling thread.
17 Throws: system_error when an exception is required (30.2.2), timeout-related exceptions (30.2.4), or
any exception thrown by pred.
18 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Clock, class Duration>
cv_status wait_until(unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& abs_time);
19 Requires: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either
§ 30.5.1 1184
c
ISO/IEC N????
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.
20 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 (30.2.4) specified by abs_time, or spuriously.
If the function exits via an exception, lock.lock() shall be called prior to exiting the function
scope.
21 Postcondition: lock.owns_lock() is true and lock.mutex() is locked by the calling thread.
22 Returns: cv_status::timeout if the absolute timeout (30.2.4) specified by abs_time expired, other-
wise cv_status::no_timeout.
23 Throws: system_error when an exception is required (30.2.2) or timeout-related exceptions (30.2.4).
24 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Rep, class Period>
cv_status wait_for(unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& rel_time);
25 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.
26 Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time);
27 Returns: cv_status::timeout if the relative timeout (30.2.4) specified by rel_time expired, otherwise
cv_status::no_timeout.
28 Postcondition: lock.owns_lock() is true and lock.mutex() is locked by the calling thread.
29 Throws: system_error when an exception is required (30.2.2) or timeout-related exceptions (30.2.4).
30 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Clock, class Duration, class Predicate>
bool wait_until(unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& abs_time,
Predicate pred);
31 Requires: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either
§ 30.5.1 1185
c
ISO/IEC N????
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.
32 Effects: Equivalent to:
while (!pred())
if (wait_until(lock, abs_time) == cv_status::timeout)
return pred();
return true;
33 Postcondition: lock.owns_lock() is true and lock.mutex() is locked by the calling thread.
34 [Note: The returned value indicates whether the predicate evaluated to true regardless of whether
the timeout was triggered. — end note ]
35 Throws: system_error when an exception is required (30.2.2), timeout-related exceptions (30.2.4), or
any exception thrown by pred.
36 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Rep, class Period, class Predicate>
bool wait_for(unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& rel_time,
Predicate pred);
37 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.
38 Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
39 [Note: There is no blocking if pred() is initially true, even if the timeout has already expired. — end
note ]
40 Postcondition: lock.owns_lock() is true and lock.mutex() is locked by the calling thread.
41 [Note: The returned value indicates whether the predicate evaluates to true regardless of whether the
timeout was triggered. — end note ]
42 Throws: system_error when an exception is required (30.2.2), timeout-related exceptions (30.2.4), or
any exception thrown by pred.
43 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
§ 30.5.1 1186
c
ISO/IEC N????
30.5.2 Class condition_variable_any [thread.condition.condvarany]
1ALock type shall meet the BasicLockable requirements (30.2.5.2). [ 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();
2Effects: Constructs an object of type condition_variable_any.
3Throws: bad_alloc or system_error when an exception is required (30.2.2).
4Error conditions:
resource_unavailable_try_again — if some non-memory resource limitation prevents initial-
ization.
operation_not_permitted — if the thread does not have the privilege to perform the operation.
~condition_variable_any();
5Requires: 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
§ 30.5.2 1187
c
ISO/IEC N????
functions in a loop or using the overloads of wait,wait_for, or wait_until that take a predicate.
— end note ]
6Effects: Destroys the object.
void notify_one() noexcept;
7Effects: If any threads are blocked waiting for *this, unblocks one of those threads.
void notify_all() noexcept;
8Effects: Unblocks all threads that are blocked waiting for *this.
template <class Lock>
void wait(Lock& lock);
9Note: 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.
10 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.
If the function exits via an exception, lock.lock() shall be called prior to exiting the function
scope.
11 Postcondition: lock is locked by the calling thread.
12 Throws: system_error when an exception is required (30.2.2).
13 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Lock, class Predicate>
void wait(Lock& lock, Predicate pred);
14 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);
15 Effects:
Atomically calls lock.unlock() and blocks on *this.
When unblocked, calls lock.lock() (possibly blocking on the lock) and returns.
§ 30.5.2 1188
c
ISO/IEC N????
The function will unblock when signaled by a call to notify_one(), a call to notify_all(),
expiration of the absolute timeout (30.2.4) specified by abs_time, or spuriously.
If the function exits via an exception, lock.lock() shall be called prior to exiting the function
scope.
16 Postcondition: lock is locked by the calling thread.
17 Returns: cv_status::timeout if the absolute timeout (30.2.4) specified by abs_time expired, other-
wise cv_status::no_timeout.
18 Throws: system_error when an exception is required (30.2.2) or timeout-related exceptions (30.2.4).
19 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Lock, class Rep, class Period>
cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
20 Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time);
21 Returns: cv_status::timeout if the relative timeout (30.2.4) specified by rel_time expired, otherwise
cv_status::no_timeout.
22 Postcondition: lock is locked by the calling thread.
23 Throws: system_error when an exception is required (30.2.2) or timeout-related exceptions (30.2.4).
24 Error conditions:
equivalent error condition from lock.lock() or lock.unlock().
template <class Lock, class Clock, class Duration, class Predicate>
bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
25 Effects: Equivalent to:
while (!pred())
if (wait_until(lock, abs_time) == cv_status::timeout)
return pred();
return true;
26 [Note: There is no blocking if pred() is initially true, or if the timeout has already expired. — end
note ]
27 [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);
28 Effects: Equivalent to:
return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
§ 30.5.2 1189
c
ISO/IEC N????
30.6 Futures [futures]
30.6.1 Overview [futures.overview]
130.6 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 ]
Header <future> synopsis
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>;
§ 30.6.1 1190
c
ISO/IEC N????
template <class> class packaged_task; // undefined
template <class R, class... ArgTypes>
class packaged_task<R(ArgTypes...)>;
template <class R>
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<result_of_t<decay_t<F>(decay_t<Args>...)>>
async(F&& f, Args&&... args);
template <class F, class... Args>
future<result_of_t<decay_t<F>(decay_t<Args>...)>>
async(launch policy, F&& f, Args&&... args);
}
2The enum type launch is a bitmask type (17.5.2.1.3) with launch::async and launch::deferred denoting
individual bits. [ 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. Implemen-
tations 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 ]
3The enum values of future_errc are distinct and not zero.
30.6.2 Error handling [futures.errors]
const error_category& future_category() noexcept;
1Returns: A reference to an object of a type derived from class error_category.
2The 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;
3Returns: error_code(static_cast<int>(e), future_category()).
error_condition make_error_condition(future_errc e) noexcept;
4Returns: error_condition(static_cast<int>(e), future_category()).
30.6.3 Class future_error [futures.future_error]
namespace std {
class future_error : public logic_error {
public:
future_error(error_code ec); // exposition only
const error_code& code() const noexcept;
const char* what() const noexcept;
};
}
const error_code& code() const noexcept;
§ 30.6.3 1191
c
ISO/IEC N????
1Returns: The value of ec that was passed to the object’s constructor.
const char* what() const noexcept;
2Returns: An ntbs incorporating code().message().
30.6.4 Shared state [futures.state]
1Many of the classes introduced in this sub-clause 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 ]
2[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 ]
3An asynchronous return object is an object that reads results from an 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 (30.2.5), then it is a
timed waiting function, otherwise it is a non-timed waiting function.
4An 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.
5When 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.
6When 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.
7When 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.
8A 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.
9Calls to functions that successfully set the stored result of a shared state synchronize with (1.10) 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 (1.10) the successful return from a
call to a waiting function on the shared state.
§ 30.6.4 1192
c
ISO/IEC N????
10 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 (3.7.2) is
sequenced before making that shared state ready.
11 Access to the result of the same shared state may conflict (1.10). [ 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 avoid-
ance (17.6.5.9). For example, concurrent accesses through references returned by shared_future::get() (30.6.7)
must either use read-only operations or provide additional synchronization. — end note ]
30.6.5 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(const R& r);
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>;
}
1The implementation shall provide the template promise and two specializations, promise<R&> and promise<
void>. These differ only in the argument type of the member function set_value, as set out in its description,
below.
2The set_value,set_exception,set_value_at_thread_exit, and set_exception_at_thread_exit mem-
ber 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 { };
3Requires: Alloc shall be an Allocator (17.6.3.5).
§ 30.6.5 1193
c
ISO/IEC N????
promise();
template <class Allocator>
promise(allocator_arg_t, const Allocator& a);
4Effects: 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;
5Effects: constructs a new promise object and transfers ownership of the shared state of rhs (if any)
to the newly-constructed object.
6Postcondition: rhs has no shared state.
~promise();
7Effects: Abandons any shared state (30.6.4).
promise& operator=(promise&& rhs) noexcept;
8Effects: Abandons any shared state (30.6.4) and then as if promise(std::move(rhs)).swap(*this).
9Returns: *this.
void swap(promise& other) noexcept;
10 Effects: Exchanges the shared state of *this and other.
11 Postcondition: *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();
12 Returns: Afuture<R> object with the same shared state as *this.
13 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.
14 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();
15 Effects: atomically stores the value rin the shared state and makes that state ready (30.6.4).
16 Throws:
future_error if its shared state already has a stored value or exception, or
§ 30.6.5 1194
c
ISO/IEC N????
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.
17 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);
18 Effects: atomically stores the exception pointer pin the shared state and makes that state ready (30.6.4).
19 Throws: future_error if its shared state already has a stored value or exception.
20 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();
21 Effects: Stores the value rin 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.
22 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.
23 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);
24 Effects: Stores the exception pointer pin 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.
25 Throws: future_error if an error condition occurs.
26 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);
27 Effects: x.swap(y).
§ 30.6.5 1195
c
ISO/IEC N????
30.6.6 Class template future [futures.unique_future]
1The 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 (30.6.4) 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.
2[Note: Member functions of future do not synchronize with themselves or with member functions of
shared_future.— end note ]
3The effect of calling any member function other than the destructor, the move-assignment operator, or valid
on a future object for which valid() == false is undefined. [ 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();
// 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;
};
}
4The 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;
5Effects: constructs an empty future object that does not refer to an shared state.
6Postcondition: valid() == false.
future(future&& rhs) noexcept;
7Effects: move constructs a future object that refers to the shared state that was originally referred
to by rhs (if any).
8Postconditions:
§ 30.6.6 1196
c
ISO/IEC N????
valid() returns the same value as rhs.valid() prior to the constructor invocation.
rhs.valid() == false.
~future();
9Effects:
releases any shared state (30.6.4);
destroys *this.
future& operator=(future&& rhs) noexcept;
10 Effects:
releases any shared state (30.6.4).
move assigns the contents of rhs to *this.
11 Postconditions:
valid() returns the same value as rhs.valid() prior to the assignment.
rhs.valid() == false.
shared_future<R> share();
12 Returns: shared_future<R>(std::move(*this)).
13 Postcondition: valid() == false.
R future::get();
R& future<R&>::get();
void future<void>::get();
14 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.
15 Effects: wait()s until the shared state is ready, then retrieves the value stored in the shared state.
16 Returns:
future::get() returns the value vstored 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.
17 Throws: the stored exception, if an exception was stored in the shared state.
18 Postcondition: valid() == false.
bool valid() const noexcept;
19 Returns: true only if *this refers to a shared state.
void wait() const;
§ 30.6.6 1197
c
ISO/IEC N????
20 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;
21 Effects: none if the shared state contains a deferred function (30.6.8), otherwise blocks until the shared
state is ready or until the relative timeout (30.2.4) specified by rel_time has expired.
22 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 (30.2.4) spec-
ified by rel_time has expired.
23 Throws: timeout-related exceptions (30.2.4).
template <class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
24 Effects: none if the shared state contains a deferred function (30.6.8), otherwise blocks until the shared
state is ready or until the absolute timeout (30.2.4) specified by abs_time has expired.
25 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 (30.2.4) spec-
ified by abs_time has expired.
26 Throws: timeout-related exceptions (30.2.4).
30.6.7 Class template shared_future [futures.shared_future]
1The 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 (30.6.4) 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.
2[Note: Member functions of shared_future do not synchronize with themselves, but they synchronize with
the shared shared state. — end note ]
3The effect of calling any member function other than the destructor, the move-assignment operator, or
valid() on a shared_future object for which valid() == false is undefined. [ 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);
§ 30.6.7 1198
c
ISO/IEC N????
shared_future(future<R>&&) noexcept;
shared_future(shared_future&& rhs) noexcept;
~shared_future();
shared_future& operator=(const shared_future& rhs);
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;
};
}
4The 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;
5Effects: constructs an empty shared_future object that does not refer to an shared state.
6Postcondition: valid() == false.
shared_future(const shared_future& rhs);
7Effects: constructs a shared_future object that refers to the same shared state as rhs (if any).
8Postcondition: valid() returns the same value as rhs.valid().
shared_future(future<R>&& rhs) noexcept;
shared_future(shared_future&& rhs) noexcept;
9Effects: move constructs a shared_future object that refers to the shared state that was originally
referred to by rhs (if any).
10 Postconditions:
valid() returns the same value as rhs.valid() returned prior to the constructor invocation.
rhs.valid() == false.
~shared_future();
11 Effects:
releases any shared state (30.6.4);
destroys *this.
shared_future& operator=(shared_future&& rhs) noexcept;
§ 30.6.7 1199
c
ISO/IEC N????
12 Effects:
releases any shared state (30.6.4);
move assigns the contents of rhs to *this.
13 Postconditions:
valid() returns the same value as rhs.valid() returned prior to the assignment.
rhs.valid() == false.
shared_future& operator=(const shared_future& rhs);
14 Effects:
releases any shared state (30.6.4);
assigns the contents of rhs to *this. [ Note: As a result, *this refers to the same shared state
as rhs (if any). — end note ]
15 Postconditions: valid() == rhs.valid().
const R& shared_future::get() const;
R& shared_future<R&>::get() const;
void shared_future<void>::get() const;
16 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.
17 Note: access to a value object stored in the shared state is unsynchronized, so programmers should
apply only those operations on Rthat do not introduce a data race (1.10).
18 Effects: wait()s until the shared state is ready, then retrieves the value stored in the shared state.
19 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.
20 Throws: the stored exception, if an exception was stored in the shared state.
bool valid() const noexcept;
21 Returns: true only if *this refers to a shared state.
void wait() const;
22 Effects: blocks until the shared state is ready.
§ 30.6.7 1200
c
ISO/IEC N????
template <class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
23 Effects: none if the shared state contains a deferred function (30.6.8), otherwise blocks until the shared
state is ready or until the relative timeout (30.2.4) specified by rel_time has expired.
24 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 (30.2.4) spec-
ified by rel_time has expired.
25 Throws: timeout-related exceptions (30.2.4).
template <class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
26 Effects: none if the shared state contains a deferred function (30.6.8), otherwise blocks until the shared
state is ready or until the absolute timeout (30.2.4) specified by abs_time has expired.
27 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 (30.2.4) spec-
ified by abs_time has expired.
28 Throws: timeout-related exceptions (30.2.4).
30.6.8 Function template async [futures.async]
1The 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<result_of_t<decay_t<F>(decay_t<Args>...)>> async(F&& f, Args&&... args);
template <class F, class... Args>
future<result_of_t<decay_t<F>(decay_t<Args>...)>> async(launch policy, F&& f, Args&&... args);
2Requires: Fand each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE (DECAY_-
COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) (20.10.2,30.3.1.2) shall
be a valid expression.
3Effects: 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 Fand 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 policy & launch::async is non-zero — calls INVOKE (DECAY_COPY (std::forward<F>(f)),
DECAY_COPY (std::forward<Args>(args))...) (20.10.2,30.3.1.2) as if in a new thread of ex-
ecution represented by a thread object with the calls to DECAY_COPY () being evaluated in the
§ 30.6.8 1201
c
ISO/IEC N????
thread that called async. Any return value is stored as the result in the shared state. Any excep-
tion 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 policy & launch::deferred is non-zero — Stores DECAY_COPY (std::forward<F>(f)) and
DECAY_COPY (std::forward<Args>(args))... in the shared state. These copies of fand args
constitute a deferred function. Invocation of the deferred function evaluates INVOKE (std::move(g),
std::move(xyz)) where gis the stored value of DECAY_COPY (std::forward<F>(f)) and xyz is
the stored copy of DECAY_COPY (std::forward<Args>(args)).... The shared state is not made
ready until the function has completed. The first call to a non-timed waiting function (30.6.4)
on an asynchronous return object referring to this shared state shall invoke the deferred func-
tion 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 ]
4Returns: An object of type future<result_of_t<decay_t<F>(decay_t<Args>...)>> that refers to
the shared state created by this call to async.
5Synchronization: Regardless of the provided policy argument,
the invocation of async synchronizes with (1.10) 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 fis sequenced before (1.10) the shared state is made ready. [ Note:
fmight 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 (30.3.1.5);
the associated thread completion synchronizes with (1.10) 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.
6Throws: system_error if policy is launch::async and the implementation is unable to start a new
thread.
7Error conditions:
resource_unavailable_try_again — if policy is launch::async and the system is unable to
start a new thread.
8[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
}
§ 30.6.8 1202
c
ISO/IEC N????
[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 ]
30.6.9 Class template packaged_task [futures.task]
1The 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.
2When 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; // undefined
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);
template <class F, class Allocator>
explicit packaged_task(allocator_arg_t, const Allocator& a, 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>;
}
30.6.9.1 packaged_task member functions [futures.task.members]
packaged_task() noexcept;
§ 30.6.9.1 1203
c
ISO/IEC N????
1Effects: constructs a packaged_task object with no shared state and no stored task.
template <class F>
packaged_task(F&& f);
template <class F, class Allocator>
explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
2Requires: INVOKE (f, t1, t2, ..., tN, R), where t1, t2, ..., tN are values of the corresponding
types in ArgTypes..., shall be a valid expression. Invoking a copy of fshall behave the same as
invoking f.
3Effects: constructs a new packaged_task object with a shared state and initializes the object’s stored
task with std::forward<F>(f). The constructors that take an Allocator argument use it to allocate
memory needed to store the internal data structures.
4Throws: any exceptions thrown by the copy or move constructor of f, or std::bad_alloc if memory
for the internal data structures could not be allocated.
packaged_task(packaged_task&& rhs) noexcept;
5Effects: 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.
6Postcondition: rhs has no shared state.
packaged_task& operator=(packaged_task&& rhs) noexcept;
7Effects:
releases any shared state (30.6.4).
packaged_task(std::move(rhs)).swap(*this).
~packaged_task();
8Effects: Abandons any shared state. (30.6.4).
void swap(packaged_task& other) noexcept;
9Effects: exchanges the shared states and stored tasks of *this and other.
10 Postcondition: *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;
11 Returns: true only if *this has a shared state.
future<R> get_future();
12 Returns: Afuture object that shares the same shared state as *this.
13 Throws: afuture_error object if an error occurs.
14 Error conditions:
§ 30.6.9.1 1204
c
ISO/IEC N????
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);
15 Effects: INVOKE (f, t1, t2, ..., tN, R), where fis 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.
16 Throws: afuture_error exception object if there is no shared state or the stored task has already
been invoked.
17 Error conditions:
promise_already_satisfied if the stored task has already been invoked.
no_state if *this has no shared state.
18 Synchronization: a successful call to operator() synchronizes with (1.10) a call to any member func-
tion of a future or shared_future object that shares the shared state of *this. The completion of
the invocation of the stored task and the storage of the result (whether normal or exceptional) into
the shared state synchronizes with (1.10) the successful return from any member function that detects
that the state is set to ready. [ Note: operator() synchronizes and serializes with other functions
through the shared state. — end note ]
void make_ready_at_thread_exit(ArgTypes... args);
19 Effects: INVOKE (f, t1, t2, ..., tN, R), where fis 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 (30.6.4) 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.
20 Throws: future_error if an error condition occurs.
21 Error conditions:
promise_already_satisfied if the stored task has already been invoked.
no_state if *this has no shared state.
void reset();
22 Effects: as if *this = packaged_task(std::move(f)), where fis the task stored in *this. [ Note:
This constructs a new shared state for *this. The old state is abandoned (30.6.4). — end note ]
23 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.
§ 30.6.9.1 1205
c
ISO/IEC N????
30.6.9.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;
1Effects: x.swap(y)
template <class R, class Alloc>
struct uses_allocator<packaged_task<R>, Alloc>
: true_type { };
2Requires: Alloc shall be an Allocator (17.6.3.5).
§ 30.6.9.2 1206
c
ISO/IEC N????
Annex A (informative)
Grammar summary [gram]
1This summary of C++ syntax 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 (6.8,7.1,10.2) 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]
1New context-dependent keywords are introduced into a program by typedef (7.1.3), namespace (7.3.1),
class (clause 9), enumeration (7.2), and template (clause 14) declarations.
typedef-name:
identifier
namespace-name:
original-namespace-name
namespace-alias
original-namespace-name:
identifier
namespace-alias:
identifier
class-name:
identifier
simple-template-id
enum-name:
identifier
template-name:
identifier
Note that a typedef-name naming a class is also a class-name (9.1).
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
§ A.2 1207
c
ISO/IEC N????
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 esign
pp-number Esign
pp-number .
identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
identifier-nondigit:
nondigit
universal-character-name
other implementation-defined characters
nondigit: one of
abcdefghijklm
nopqrstuvwxyz
ABCDEFGHIJKLM
NOPQRSTUVWXYZ_
digit: one of
0123456789
preprocessing-op-or-punc:one of
{}[]###()
<: :> <% %> %: %:%: ; : ...
new delete ? :: . .*
+-*/%ˆ&|~
! = < > += -= *= /= %=
ˆ= &= |= << >> >>= <<= == !=
<= >= && || ++ -- , ->* ->
and and_eq bitand bitor compl not not_eq
or or_eq xor xor_eq
§ A.2 1208
c
ISO/IEC N????
literal:
integer-literal
character-literal
floating-literal
string-literal
boolean-literal
pointer-literal
user-defined-literal
integer-literal:
decimal-literal integer-suffixopt
octal-literal integer-suffixopt
hexadecimal-literal integer-suffixopt
binary-literal integer-suffixopt
decimal-literal:
nonzero-digit
decimal-literal digit
octal-literal:
0
octal-literal octal-digit
hexadecimal-literal:
0x hexadecimal-digit
0X hexadecimal-digit
hexadecimal-literal hexadecimal-digit
binary-literal:
0b binary-digit
0B binary-digit
binary-literal binary-digit
nonzero-digit: one of
123456789
octal-digit: one of
01234567
hexadecimal-digit: one of
0123456789
abcdef
ABCDEF
binary-digit:
0
1
integer-suffix:
unsigned-suffix long-suffixopt
unsigned-suffix long-long-suffixopt
long-suffix unsigned-suffixopt
long-long-suffix unsigned-suffixopt
unsigned-suffix: one of
u U
long-suffix: one of
l L
long-long-suffix: one of
ll LL
character-literal:
c-char-sequence
uc-char-sequence
Uc-char-sequence
Lc-char-sequence
§ A.2 1209
c
ISO/IEC N????
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:
fractional-constant exponent-partopt floating-suffixopt
digit-sequence exponent-part floating-suffixopt
fractional-constant:
digit-sequenceopt .digit-sequence
digit-sequence .
exponent-part:
esignopt digit-sequence
Esignopt digit-sequence
sign: one of
+ -
digit-sequence:
digit
digit-sequence digit
floating-suffix: one of
flFL
string-literal:
encoding-prefixopt "s-char-sequenceopt "
encoding-prefixopt Rraw-string
encoding-prefix:
u8
u
U
L
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
§ A.2 1210
c
ISO/IEC N????
raw-string:
"d-char-sequenceopt (r-char-sequenceopt )d-char-sequenceopt "
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-partopt ud-suffix
digit-sequence exponent-part ud-suffix
user-defined-string-literal:
string-literal ud-suffix
user-defined-character-literal:
character-literal ud-suffix
ud-suffix:
identifier
A.3 Basic concepts [gram.basic]
translation-unit:
declaration-seqopt
§ A.3 1211
c
ISO/IEC N????
A.4 Expressions [gram.expr]
primary-expression:
literal
this
(expression )
id-expression
lambda-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 templateopt unqualified-id
nested-name-specifier:
::
type-name ::
namespace-name ::
decltype-specifier ::
nested-name-specifier identifier ::
nested-name-specifier templateopt simple-template-id ::
lambda-expression:
lambda-introducer lambda-declaratoropt compound-statement
lambda-introducer:
[lambda-captureopt ]
lambda-capture:
capture-default
capture-list
capture-default ,capture-list
capture-default:
&
=
capture-list:
capture ...opt
capture-list ,capture ...opt
capture:
simple-capture
init-capture
simple-capture:
identifier
&identifier
this
init-capture:
identifier initializer
&identifier initializer
§ A.4 1212
c
ISO/IEC N????
lambda-declarator:
(parameter-declaration-clause ) mutableopt
exception-specificationopt attribute-specifier-seqopt trailing-return-typeopt
postfix-expression:
primary-expression
postfix-expression [expression ]
postfix-expression [braced-init-list ]
postfix-expression (expression-listopt )
simple-type-specifier (expression-listopt )
typename-specifier (expression-listopt )
simple-type-specifier braced-init-list
typename-specifier braced-init-list
postfix-expression . templateopt id-expression
postfix-expression -> templateopt 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-specifieropt type-name :: ~type-name
nested-name-specifier template simple-template-id :: ~type-name
nested-name-specifieropt ~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:
::opt new new-placementopt new-type-id new-initializeropt
::opt new new-placementopt (type-id )new-initializeropt
new-placement:
(expression-list )
new-type-id:
type-specifier-seq new-declaratoropt
§ A.4 1213
c
ISO/IEC N????
new-declarator:
ptr-operator new-declaratoropt
noptr-new-declarator
noptr-new-declarator:
[expression ]attribute-specifier-seqopt
noptr-new-declarator [constant-expression ]attribute-specifier-seqopt
new-initializer:
(expression-listopt )
braced-init-list
delete-expression:
::opt delete cast-expression
::opt 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
§ A.4 1214
c
ISO/IEC N????
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
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]
statement:
labeled-statement
attribute-specifier-seqopt expression-statement
attribute-specifier-seqopt compound-statement
attribute-specifier-seqopt selection-statement
attribute-specifier-seqopt iteration-statement
attribute-specifier-seqopt jump-statement
declaration-statement
attribute-specifier-seqopt try-block
labeled-statement:
attribute-specifier-seqopt identifier :statement
attribute-specifier-seqopt case constant-expression :statement
attribute-specifier-seqopt default : statement
expression-statement:
expressionopt ;
compound-statement:
{statement-seqopt }
statement-seq:
statement
statement-seq statement
selection-statement:
if ( condition )statement
if ( condition )statement else statement
switch ( condition )statement
condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator =initializer-clause
attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list
§ A.5 1215
c
ISO/IEC N????
iteration-statement:
while ( condition )statement
do statement while ( expression ) ;
for ( for-init-statement conditionopt ;expressionopt )statement
for ( for-range-declaration :for-range-initializer )statement
for-init-statement:
expression-statement
simple-declaration
for-range-declaration:
attribute-specifier-seqopt decl-specifier-seq declarator
for-range-initializer:
expression
braced-init-list
jump-statement:
break ;
continue ;
return expressionopt ;
return braced-init-list ;
goto identifier ;
declaration-statement:
block-declaration
A.6 Declarations [gram.dcl]
declaration-seq:
declaration
declaration-seq declaration
declaration:
block-declaration
function-definition
template-declaration
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
alias-declaration:
using identifier attribute-specifier-seqopt = type-id ;
simple-declaration:
decl-specifier-seqopt init-declarator-listopt ;
attribute-specifier-seq decl-specifier-seqopt init-declarator-list ;
static_assert-declaration:
static_assert ( constant-expression ,string-literal ) ;
empty-declaration:
;
§ A.6 1216
c
ISO/IEC N????
attribute-declaration:
attribute-specifier-seq ;
decl-specifier:
storage-class-specifier
type-specifier
function-specifier
friend
typedef
constexpr
decl-specifier-seq:
decl-specifier attribute-specifier-seqopt
decl-specifier decl-specifier-seq
storage-class-specifier:
register
static
thread_local
extern
mutable
function-specifier:
inline
virtual
explicit
typedef-name:
identifier
type-specifier:
trailing-type-specifier
class-specifier
enum-specifier
trailing-type-specifier:
simple-type-specifier
elaborated-type-specifier
typename-specifier
cv-qualifier
type-specifier-seq:
type-specifier attribute-specifier-seqopt
type-specifier type-specifier-seq
trailing-type-specifier-seq:
trailing-type-specifier attribute-specifier-seqopt
trailing-type-specifier trailing-type-specifier-seq
§ A.6 1217
c
ISO/IEC N????
simple-type-specifier:
nested-name-specifieropt type-name
nested-name-specifier template simple-template-id
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-seqopt nested-name-specifieropt identifier
class-key nested-name-specifieropt templateopt simple-template-id
enum nested-name-specifieropt identifier
enum-name:
identifier
enum-specifier:
enum-head {enumerator-listopt }
enum-head {enumerator-list , }
enum-head:
enum-key attribute-specifier-seqopt identifieropt enum-baseopt
enum-key attribute-specifier-seqopt nested-name-specifier identifier
enum-baseopt
opaque-enum-declaration:
enum-key attribute-specifier-seqopt identifier enum-baseopt ;
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
§ A.6 1218
c
ISO/IEC N????
enumerator:
identifier
namespace-name:
original-namespace-name
namespace-alias
original-namespace-name:
identifier
namespace-definition:
named-namespace-definition
unnamed-namespace-definition
named-namespace-definition:
original-namespace-definition
extension-namespace-definition
original-namespace-definition:
inlineopt namespace identifier {namespace-body }
extension-namespace-definition:
inlineopt namespace original-namespace-name {namespace-body }
unnamed-namespace-definition:
inlineopt namespace { namespace-body }
namespace-body:
declaration-seqopt
namespace-alias:
identifier
namespace-alias-definition:
namespace identifier =qualified-namespace-specifier ;
qualified-namespace-specifier:
nested-name-specifieropt namespace-name
using-declaration:
using typenameopt nested-name-specifier unqualified-id ;
using :: unqualified-id ;
using-directive:
attribute-specifier-seqopt using namespace nested-name-specifieropt namespace-name ;
asm-definition:
asm ( string-literal ) ;
linkage-specification:
extern string-literal {declaration-seqopt }
extern string-literal declaration
attribute-specifier-seq:
attribute-specifier-seqopt attribute-specifier
attribute-specifier:
[ [ attribute-list ] ]
alignment-specifier
alignment-specifier:
alignas ( type-id ...opt )
alignas ( assignment-expression ...opt )
attribute-list:
attributeopt
attribute-list ,attributeopt
attribute ...
attribute-list ,attribute ...
attribute:
attribute-token attribute-argument-clauseopt
§ A.6 1219
c
ISO/IEC N????
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-tokenopt
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 initializeropt
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-seqopt
noptr-declarator parameters-and-qualifiers
noptr-declarator [expressionopt ]attribute-specifier-seqopt
(ptr-declarator )
parameters-and-qualifiers:
(parameter-declaration-clause )cv-qualifier-seqopt
ref-qualifieropt exception-specificationopt attribute-specifier-seqopt
trailing-return-type:
-> trailing-type-specifier-seq abstract-declaratoropt
ptr-operator:
*attribute-specifier-seqopt cv-qualifier-seqopt
&attribute-specifier-seqopt
&& attribute-specifier-seqopt
nested-name-specifier *attribute-specifier-seqopt cv-qualifier-seqopt
cv-qualifier-seq:
cv-qualifier cv-qualifier-seqopt
cv-qualifier:
const
volatile
ref-qualifier:
&
&&
§ A.7 1220
c
ISO/IEC N????
declarator-id:
...opt id-expression
type-id:
type-specifier-seq abstract-declaratoropt
abstract-declarator:
ptr-abstract-declarator
noptr-abstract-declaratoropt parameters-and-qualifiers trailing-return-type
abstract-pack-declarator
ptr-abstract-declarator:
noptr-abstract-declarator
ptr-operator ptr-abstract-declaratoropt
noptr-abstract-declarator:
noptr-abstract-declaratoropt parameters-and-qualifiers
noptr-abstract-declaratoropt [constant-expressionopt ]attribute-specifier-seqopt
(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-expressionopt ]attribute-specifier-seqopt
...
parameter-declaration-clause:
parameter-declaration-listopt ...opt
parameter-declaration-list ,...
parameter-declaration-list:
parameter-declaration
parameter-declaration-list ,parameter-declaration
parameter-declaration:
attribute-specifier-seqopt decl-specifier-seq declarator
attribute-specifier-seqopt decl-specifier-seq declarator =initializer-clause
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt =initializer-clause
function-definition:
attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
function-body:
ctor-initializeropt 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 ...opt
initializer-list ,initializer-clause ...opt
§ A.7 1221
c
ISO/IEC N????
braced-init-list:
{initializer-list ,opt }
{ }
A.8 Classes [gram.class]
class-name:
identifier
simple-template-id
class-specifier:
class-head {member-specificationopt }
class-head:
class-key attribute-specifier-seqopt class-head-name class-virt-specifieropt base-clauseopt
class-key attribute-specifier-seqopt base-clauseopt
class-head-name:
nested-name-specifieropt class-name
class-virt-specifier:
final
class-key:
class
struct
union
member-specification:
member-declaration member-specificationopt
access-specifier :member-specificationopt
member-declaration:
attribute-specifier-seqopt decl-specifier-seqopt member-declarator-listopt ;
function-definition ;opt
using-declaration
static_assert-declaration
template-declaration
alias-declaration
member-declarator-list:
member-declarator
member-declarator-list ,member-declarator
member-declarator:
declarator virt-specifier-seqopt pure-specifieropt
declarator brace-or-equal-initializeropt
identifieropt attribute-specifier-seqopt :constant-expression
virt-specifier-seq:
virt-specifier
virt-specifier-seq virt-specifier
virt-specifier:
override
final
pure-specifier:
= 0
A.9 Derived classes [gram.derived]
base-clause:
:base-specifier-list
base-specifier-list:
base-specifier ...opt
base-specifier-list ,base-specifier ...opt
§ A.9 1222
c
ISO/IEC N????
base-specifier:
attribute-specifier-seqopt base-type-specifier
attribute-specifier-seqopt virtual access-specifieropt base-type-specifier
attribute-specifier-seqopt access-specifier virtualopt base-type-specifier
class-or-decltype:
nested-name-specifieropt class-name
decltype-specifier
base-type-specifier:
class-or-decltype
access-specifier:
private
protected
public
A.10 Special member functions [gram.special]
conversion-function-id:
operator conversion-type-id
conversion-type-id:
type-specifier-seq conversion-declaratoropt
conversion-declarator:
ptr-operator conversion-declaratoropt
ctor-initializer:
:mem-initializer-list
mem-initializer-list:
mem-initializer ...opt
mem-initializer ,mem-initializer-list ...opt
mem-initializer:
mem-initializer-id (expression-listopt )
mem-initializer-id braced-init-list
mem-initializer-id:
class-or-decltype
identifier
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.12 Templates [gram.temp]
template-declaration:
template < template-parameter-list >declaration
template-parameter-list:
template-parameter
template-parameter-list ,template-parameter
§ A.12 1223
c
ISO/IEC N????
template-parameter:
type-parameter
parameter-declaration
type-parameter:
class ...opt identifieropt
class identifieropt =type-id
typename ...opt identifieropt
typename identifieropt =type-id
template < template-parameter-list > class ...opt identifieropt
template < template-parameter-list > class identifieropt =id-expression
simple-template-id:
template-name <template-argument-listopt >
template-id:
simple-template-id
operator-function-id <template-argument-listopt >
literal-operator-id <template-argument-listopt >
template-name:
identifier
template-argument-list:
template-argument ...opt
template-argument-list ,template-argument ...opt
template-argument:
constant-expression
type-id
id-expression
typename-specifier:
typename nested-name-specifier identifier
typename nested-name-specifier templateopt simple-template-id
explicit-instantiation:
externopt template declaration
explicit-specialization:
template < > declaration
A.13 Exception handling [gram.except]
try-block:
try compound-statement handler-seq
function-try-block:
try ctor-initializeropt compound-statement handler-seq
handler-seq:
handler handler-seqopt
handler:
catch ( exception-declaration )compound-statement
exception-declaration:
attribute-specifier-seqopt type-specifier-seq declarator
attribute-specifier-seqopt type-specifier-seq abstract-declaratoropt
...
throw-expression:
throw assignment-expressionopt
exception-specification:
dynamic-exception-specification
noexcept-specification
§ A.13 1224
c
ISO/IEC N????
dynamic-exception-specification:
throw ( type-id-listopt )
type-id-list:
type-id ...opt
type-id-list ,type-id ...opt
noexcept-specification:
noexcept ( constant-expression )
noexcept
A.14 Preprocessing directives [gram.cpp]
preprocessing-file:
groupopt
group:
group-part
group group-part
group-part:
if-section
control-line
text-line
# non-directive
if-section:
if-group elif-groupsopt else-groupopt endif-line
if-group:
# if constant-expression new-line groupopt
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
elif-groups:
elif-group
elif-groups elif-group
elif-group:
# elif constant-expression new-line groupopt
else-group:
# else new-line groupopt
endif-line:
# endif new-line
control-line:
# include pp-tokens new-line
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt )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-tokensopt new-line
# pragma pp-tokensopt new-line
#new-line
text-line:
pp-tokensopt new-line
non-directive:
pp-tokens new-line
lparen:
a(character not immediately preceded by white-space
§ A.14 1225
c
ISO/IEC N????
identifier-list:
identifier
identifier-list ,identifier
replacement-list:
pp-tokensopt
pp-tokens:
preprocessing-token
pp-tokens preprocessing-token
new-line:
the new-line character
§ A.14 1226
c
ISO/IEC N????
Annex B (informative)
Implementation quantities [implimits]
1Because 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 docu-
mentation 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.
2The 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 incom-
plete 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 [1 024].
Number of characters in an external identifier [1 024].
External identifiers in one translation unit [65 536].
Identifiers with block scope declared in one block [1 024].
Macro identifiers simultaneously defined in one translation unit [65 536].
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 [65 536].
Characters in a string literal (after concatenation) [65 536].
Size of an object [262 144].
Nesting levels for #include files [256].
Case labels for a switch statement (excluding those for any nested switch statements) [16 384].
Data members in a single class [16 384].
Enumeration constants in a single enumeration [4 096].
Levels of nested class definitions in a single member-specification [256].
Implementation quantities 1227
c
ISO/IEC N????
Functions registered by atexit() [32].
Functions registered by at_quick_exit() [32].
Direct and indirect base classes [16 384].
Direct base classes for a single class [1 024].
Members declared in a single class [4 096].
Final overriding virtual functions in a class, accessible or not [16 384].
Direct and indirect virtual bases of a class [1 024].
Static members of a class [1 024].
Friend declarations in a class [4 096].
Access control declarations in a class [4 096].
Member initializers in a constructor definition [6 144].
Scope qualifications of one identifier [256].
Nested external specifications [1 024].
Recursive constexpr function invocations [512].
Full-expressions evaluated within a core constant expression [1 048 576].
Template arguments in a template declaration [1 024].
Recursively nested template instantiations, including substitution during template argument deduc-
tion (14.8.2) [1 024].
Handlers per try block [256].
Throw specifications on a single function declaration [256].
Number of placeholders (20.10.9.1.4) [10].
Implementation quantities 1228
c
ISO/IEC N????
Annex C (informative)
Compatibility [diff]
C.1 C++ and ISO C [diff.iso]
1This subclause lists the differences between C++ and ISO C, by the chapters of this document.
C.1.1 Clause 2: lexical conventions [diff.lex]
2.12
Change: New Keywords
New keywords are added to C++; see 2.12.
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.
2.14.3
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 2.14.5:
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);
§ C.1.1 1229
c
ISO/IEC N????
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 3: basic concepts [diff.basic]
3.1
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.
Rationale: 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.
3.3
Change: Astruct 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.
3.5 [also 7.1.6]
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 can be used as compile-time values in C++, this feature urges program-
mers to provide explicit initializer values for each const. This feature allows the user to put constobjects
in header files that are included in many compilation units.
Effect on original feature: Change to semantics of well-defined feature.
Difficulty of converting: Semantic transformation
How widely used: Seldom
3.6
Change: Main 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
3.9
Change: C allows “compatible types” in several places, C++ does not For example, otherwise-identical
§ C.1.2 1230
c
ISO/IEC N????
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 4: standard conversions [diff.conv]
4.10
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 5: expressions [diff.expr]
5.2.2
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.
5.3.3,5.4
Change: Types must be declared in declarations, not in expressions In C, a sizeof expression or cast
expression may create a new type. For example,
p = (void*)(struct x {int i;} *)0;
declares a new type, struct x .
Rationale: This prohibition helps to clarify the location of declarations in the source code.
Effect on original feature: Deletion of a semantically well-defined feature.
Difficulty of converting: Syntactic transformation.
How widely used: Seldom.
5.16,5.17,5.18
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,
§ C.1.4 1231
c
ISO/IEC N????
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 6: statements [diff.stat]
6.4.2,6.6.4
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 run-time 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.
6.6.3
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 7: declarations [diff.dcl]
7.1.1
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.
§ C.1.6 1232
c
ISO/IEC N????
7.1.3
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; // ihas 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.
7.1.6 [see also 3.5]
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.
7.1.6
Change: Banning implicit int
In C++ adecl-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.
7.1.6.4
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
§ C.1.6 1233
c
ISO/IEC N????
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.
7.2
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.
7.2
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 8: declarators [diff.decl]
8.3.5
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 decla-
ration 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.
8.3.5 [see 5.3.3]
Change: In C++, types may not be defined in return or parameter types. In C, these type definitions are
allowed
§ C.1.7 1234
c
ISO/IEC N????
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 compilation units, C++ relies on name equivalence when
C relies on structural equivalence. Regarding parameter types: since the type defined in an 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 definitions is seen as poor coding style.
8.4
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.
8.5.2
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 routines, there is po-
tential 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 9: classes [diff.class]
9.1 [see also 7.1.3]
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
§ C.1.8 1235
c
ISO/IEC N????
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.
9.6
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 choise is implementation-defined in C, but not so in C++.
Difficulty of converting: Syntactic transformation.
How widely used: Seldom.
9.7
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 of 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 3.3.
How widely used: Seldom.
9.9
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;
§ C.1.8 1236
c
ISO/IEC N????
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 12: special member functions [diff.special]
12.8
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. [ Note: This user-declared constructor may be
explicitly defaulted. — end note ] If non-volatile semantics are required, an explicit const_cast can be
used.
How widely used: Seldom.
C.1.10 Clause 16: preprocessing directives [diff.cpp]
16.8
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]
1This 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 2: lexical conventions [diff.cpp03.lex]
2.5
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
§ C.2.1 1237
c
ISO/IEC N????
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"
2.5
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 tokens, so the macro
is not expanded.
2.12
Change: New keywords
Rationale: Required for new features.
Effect on original feature: Added to Table 4, 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.
2.14.2
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 4: standard conversions [diff.cpp03.conv]
4.10
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 5: expressions [diff.cpp03.expr]
5.6
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.
C.2.4 Clause 7: declarations [diff.cpp03.dcl.dcl]
7.1
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
§ C.2.4 1238
c
ISO/IEC N????
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 8: declarators [diff.cpp03.dcl.decl]
8.5.4
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 12: special member functions [diff.cpp03.special]
12.1,12.4,12.8
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.
12.4 (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 noexcept or noexcept(true). For a throwing virtual destructor of a de-
rived class, std::terminate() can be avoided only if the base class virtual destructor has an exception
specification that is not noexcept and not noexcept(true).
C.2.7 Clause 14: templates [diff.cpp03.temp]
14.1
Change: Remove export
Rationale: No implementation consensus.
Effect on original feature: A valid C++ 2003 declaration containing export is ill-formed in this Interna-
tional Standard.
14.3
Change: Remove whitespace requirement for nested closing template right angle brackets
Rationale: Considered a persistent but minor annoyance. Template aliases representing nonclass 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;
14.6.4.2
Change: Allow dependent calls of functions with internal linkage
Rationale: Overly constrained, simplify overload resolution rules.
§ C.2.7 1239
c
ISO/IEC N????
Effect on original feature: A valid C++ 2003 program could get a different result than this International
Standard.
C.2.8 Clause 17: library introduction [diff.cpp03.library]
17 30
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.
17.6.1.2
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 Stan-
dard.
17.6.3.2
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>.
17.6.4.2.2
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.
17.6.5.3
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 18: language support library [diff.cpp03.language.support]
18.6.1.1
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) {
§ C.2.9 1240
c
ISO/IEC N????
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
return 0;
}
18.6.1.1
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 19: diagnostics library [diff.cpp03.diagnostics]
19.4
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 20: general utilities library [diff.cpp03.utilities]
20.8.4
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.
20.10.3,20.10.4,20.10.5,20.10.6,20.10.7,20.10.8
Change: Standard function object types no longer derived from std::unary_function or std::binary_-
function
Rationale: Superseded by new feature.
Effect on original feature: Valid C++ 2003 code that depends on function object types being derived
from unary_function or binary_function will execute differently in this International Standard.
C.2.12 Clause 21: strings library [diff.cpp03.strings]
21.3
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.
21.4.1
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.
§ C.2.12 1241
c
ISO/IEC N????
Some const member functions, such as data and c_str, no longer invalidate iterators.
C.2.13 Clause 23: containers library [diff.cpp03.containers]
23.2
Change: Complexity of size() member functions now constant
Rationale: Lack of specification of complexity of size() resulted in divergent implementations with in-
consistent 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.
23.2
Change: Requirements change: relaxation
Rationale: Clarification.
Effect on original feature: Valid C++ 2003 code that attempts to meet the specified container require-
ments 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).
23.2
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.
23.2.3,23.2.4
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.
23.2.3,23.2.4
Change: Signature changes: from iterator to const_iterator parameters
Rationale: Overspecification. Effects: 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(iter) for set,multiset,map,multimap
erase(begin, end) for set,multiset,map,multimap
all forms of list::splice
§ C.2.13 1242
c
ISO/IEC N????
all forms of list::merge
Valid C++ 2003 code that uses these functions may fail to compile with this International Standard.
23.2.3,23.2.4
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 25: algorithms library [diff.cpp03.algorithms]
25.1
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 26: numerics library [diff.cpp03.numerics]
26.4
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 27: Input/output library [diff.cpp03.input.output]
27.7.2.1.3,27.7.3.4,27.5.5.4
Change: Specify use of explicit in existing boolean conversion operators
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.
27.5.3.1.1
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.
27.5.3
Change: Flag types in std::ios_base are now bitmasks with values defined as constexpr static members
Rationale: Required for new features.
§ C.2.16 1243
c
ISO/IEC N????
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
return 0;
}
C.3 C++ and ISO C++ 2011 [diff.cpp11]
1This 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 7: declarations [diff.cpp11.dcl.dcl]
7.1.5
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.4 C standard library [diff.library]
1This subclause summarizes the contents of the C++ standard library included from the Standard C library.
It also summarizes the explicit changes in definitions, declarations, or behavior from the Standard C library
noted in other subclauses (17.6.1.2,18.2,21.8).
2The C++ standard library provides 57 standard macros from the C library, as shown in Table 149.
3The header names (enclosed in <and >) indicate that the macro may be defined in more than one header.
All such definitions are equivalent (3.2).
Table 149 — Standard macros
assert HUGE_VAL NULL <cstring> SIGINT va_end
BUFSIZ LC_ALL NULL <ctime> SIGSEGV va_start
CLOCKS_PER_SEC LC_COLLATE NULL <cwchar> SIGTERM WCHAR_MAX
EDOM LC_CTYPE offsetof SIG_DFL WCHAR_MIN
EILSEQ LC_MONETARY RAND_MAX SIG_ERR WEOF <cwchar>
EOF LC_NUMERIC SEEK_CUR SIG_IGN WEOF <cwctype>
ERANGE LC_TIME SEEK_END stderr _IOFBF
errno L_tmpnam SEEK_SET stdin _IOLBF
EXIT_FAILURE MB_CUR_MAX setjmp stdout _IONBF
EXIT_SUCCESS NULL <clocale> SIGABRT TMP_MAX
FILENAME_MAX NULL <cstddef> SIGFPE va_arg
FOPEN_MAX NULL <cstdlib> SIGILL va_copy
4The C++ standard library provides 57 standard values from the C library, as shown in Table 150.
§ C.4 1244
c
ISO/IEC N????
Table 150 — Standard values
CHAR_BIT FLT_DIG INT_MIN MB_LEN_MAX
CHAR_MAX FLT_EPSILON LDBL_DIG SCHAR_MAX
CHAR_MIN FLT_MANT_DIG LDBL_EPSILON SCHAR_MIN
DBL_DIG FLT_MAX LDBL_MANT_DIG SHRT_MAX
DBL_EPSILON FLT_MAX_10_EXP LDBL_MAX SHRT_MIN
DBL_MANT_DIG FLT_MAX_EXP LDBL_MAX_10_EXP UCHAR_MAX
DBL_MAX FLT_MIN LDBL_MAX_EXP UINT_MAX
DBL_MAX_10_EXP FLT_MIN_10_EXP LDBL_MIN ULONG_MAX
DBL_MAX_EXP FLT_MIN_EXP LDBL_MIN_10_EXP USHRT_MAX
DBL_MIN FLT_RADIX LDBL_MIN_EXP
DBL_MIN_10_EXP FLT_ROUNDS LONG_MAX
DBL_MIN_EXP INT_MAX LONG_MIN
Table 151 — Standard types
clock_t ldiv_t size_t <cstdio> va_list
div_t mbstate_t size_t <cstdlib> wctrans_t
FILE ptrdiff_t size_t <cstring> wctype_t
fpos_t sig_atomic_t size_t <ctime> wint_t <cwchar>
jmp_buf size_t <cstddef> time_t wint_t <cwctype>
5The C++ standard library provides 20 standard types from the C library, as shown in Table 151.
6The C++ standard library provides 2 standard structs from the C library, as shown in Table 152.
Table 152 — Standard structs
lconv tm
7The C++ standard library provides 209 standard functions from the C library, as shown in Table 153.
C.4.1 Modifications to headers [diff.mods.to.headers]
1For compatibility with the Standard C library, the C++ standard library provides the 18 C headers (D.5),
but their use is deprecated in C++.
C.4.2 Modifications to definitions [diff.mods.to.definitions]
C.4.2.1 Types char16_t and char32_t [diff.char16]
1The types char16_t and char32_t are distinct types rather than typedefs to existing integral types.
C.4.2.2 Type wchar_t [diff.wchar.t]
1wchar_t is a keyword in this International Standard (2.12). It does not appear as a type name defined in
any of <cstddef>,<cstdlib>, or <cwchar> (21.8).
C.4.2.3 Header <iso646.h> [diff.header.iso646.h]
1The tokens and,and_eq,bitand,bitor,compl,not_eq,not,or,or_eq,xor, and xor_eq are keywords in
this International Standard (2.12). They do not appear as macro names defined in <ciso646>.
C.4.2.4 Macro NULL [diff.null]
1The macro NULL, defined in any of <clocale>,<cstddef>,<cstdio>,<cstdlib>,<cstring>,<ctime>, or
§ C.4.2.4 1245
c
ISO/IEC N????
Table 153 — Standard functions
abort fmod isupper mktime strftime wcrtomb
abs fopen iswalnum modf strlen wcscat
acos fprintf iswalpha perror strncat wcschr
asctime fputc iswcntrl pow strncmp wcscmp
asin fputs iswctype printf strncpy wcscoll
atan fputwc iswdigit putc strpbrk wcscpy
atan2 fputws iswgraph putchar strrchr wcscspn
atexit fread iswlower puts strspn wcsftime
atof free iswprint putwc strstr wcslen
atoi freopen iswpunct putwchar strtod wcsncat
atol frexp iswspace qsort strtok wcsncmp
bsearch fscanf iswupper raise strtol wcsncpy
btowc fseek iswxdigit rand strtoul wcspbrk
calloc fsetpos isxdigit realloc strxfrm wcsrchr
ceil ftell labs remove swprintf wcsrtombs
clearerr fwide ldexp rename swscanf wcsspn
clock fwprintf ldiv rewind system wcsstr
cos fwrite localeconv scanf tan wcstod
cosh fwscanf localtime setbuf tanh wcstok
ctime getc log setlocale time wcstol
difftime getchar log10 setvbuf tmpfile wcstombs
div getenv longjmp signal tmpnam wcstoul
exit gets malloc sin tolower wcsxfrm
exp getwc mblen sinh toupper wctob
fabs getwchar mbrlen sprintf towctrans wctomb
fclose gmtime mbrtowc sqrt towlower wctrans
feof isalnum mbsinit srand towupper wctype
ferror isalpha mbsrtowcs sscanf ungetc wmemchr
fflush iscntrl mbstowcs strcat ungetwc wmemcmp
fgetc isdigit mbtowc strchr vfprintf wmemcpy
fgetpos isgraph memchr strcmp vfwprintf wmemmove
fgets islower memcmp strcoll vprintf wmemset
fgetwc isprint memcpy strcpy vsprintf wprintf
fgetws ispunct memmove strcspn vswprintf wscanf
floor isspace memset strerror vwprintf
§ C.4.2.4 1246
c
ISO/IEC N????
<cwchar>, is an implementation-defined C++ null pointer constant in this International Standard (18.2).
C.4.3 Modifications to declarations [diff.mods.to.declarations]
1Header <cstring>: The following functions have different declarations:
strchr
strpbrk
strrchr
strstr
memchr
21.8 describes the changes.
C.4.4 Modifications to behavior [diff.mods.to.behavior]
1Header <cstdlib>: The following functions have different behavior:
atexit
exit
abort
18.5 describes the changes.
2Header <csetjmp>: The following functions have different behavior:
longjmp
18.10 describes the changes.
C.4.4.1 Macro offsetof(type, member-designator) [diff.offsetof]
1The macro offsetof, defined in <cstddef>, accepts a restricted set of type arguments in this International
Standard. 18.2 describes the change.
C.4.4.2 Memory allocation functions [diff.malloc]
1The functions calloc,malloc, and realloc are restricted in this International Standard. 20.8.13 describes
the changes.
§ C.4.4.2 1247
c
ISO/IEC N????
Annex D (normative)
Compatibility features [depr]
1This Clause describes features of the C++ Standard that are specified for compatibility with existing imple-
mentations.
2These are deprecated features, where deprecated is defined as: Normative for the current edition of the
Standard, but having been identified as a candidate for removal from future revisions.
D.1 Increment operator with bool operand [depr.incr.bool]
1The use of an operand of type bool with the ++ operator is deprecated (see 5.3.2 and 5.2.6).
D.2 register keyword [depr.register]
1The use of the register keyword as a storage-class-specifier (7.1.1) is deprecated.
D.3 Implicit declaration of copy functions [depr.impldec]
1The 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
(12.4,12.8). In a future revision of this International Standard, these implicit definitions could become
deleted (8.4).
D.4 Dynamic exception specifications [depr.except.spec]
1The use of dynamic-exception-specifications is deprecated.
D.5 C standard library headers [depr.c.headers]
1For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides
the 25 C headers, as shown in Table 154.
Table 154 — 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>
2Every 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. It is
unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace
std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
3[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 Old iostreams members [depr.ios.members]
1The following member names are in addition to names specified in Clause 27:
§ D.6 1248
c
ISO/IEC N????
namespace std {
class ios_base {
public:
typedef T1 io_state;
typedef T2 open_mode;
typedef T3 seek_dir;
typedef implementation-defined streamoff;
typedef implementation-defined streampos;
// remainder unchanged
};
}
2The type io_state is a synonym for an integer type (indicated here as T1 ) that permits certain member
functions to overload others on parameters of type iostate and provide the same behavior.
3The type open_mode is a synonym for an integer type (indicated here as T2 ) that permits certain member
functions to overload others on parameters of type openmode and provide the same behavior.
4The type seek_dir is a synonym for an integer type (indicated here as T3 ) that permits certain member
functions to overload others on parameters of type seekdir and provide the same behavior.
5The type streamoff is an implementation-defined type that satisfies the requirements of off_type in 27.2.2.
6The type streampos is an implementation-defined type that satisfies the requirements of pos_type in 27.2.2.
7An implementation may provide the following additional member function, which has the effect of calling
sbumpc() (27.6.3.2.3):
namespace std {
template<class charT, class traits = char_traits<charT> >
class basic_streambuf {
public:
void stossc();
// remainder unchanged
};
}
8An implementation may provide the following member functions that overload signatures specified in Clause 27:
namespace std {
template<class charT, class traits> class basic_ios {
public:
void clear(io_state state);
void setstate(io_state state);
void exceptions(io_state);
// remainder unchanged
};
class ios_base {
public:
// remainder unchanged
};
template<class charT, class traits = char_traits<charT> >
class basic_streambuf {
public:
pos_type pubseekoff(off_type off, ios_base::seek_dir way,
ios_base::open_mode which = ios_base::in | ios_base::out);
pos_type pubseekpos(pos_type sp,
ios_base::open_mode which);
// remainder unchanged
§ D.6 1249
c
ISO/IEC N????
};
template <class charT, class traits = char_traits<charT> >
class basic_filebuf : public basic_streambuf<charT,traits> {
public:
basic_filebuf<charT,traits>* open
(const char* s, ios_base::open_mode mode);
// remainder unchanged
};
template <class charT, class traits = char_traits<charT> >
class basic_ifstream : public basic_istream<charT,traits> {
public:
void open(const char* s, ios_base::open_mode mode);
// remainder unchanged
};
template <class charT, class traits = char_traits<charT> >
class basic_ofstream : public basic_ostream<charT,traits> {
public:
void open(const char* s, ios_base::open_mode mode);
// remainder unchanged
};
}
9The effects of these functions is to call the corresponding member function specified in Clause 27.
D.7 char* streams [depr.str.strstreams]
1The header <strstream> defines three types that associate stream buffers with character array objects and
assist reading and writing such objects.
D.7.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:
virtual int_type overflow (int_type c = EOF);
virtual int_type pbackfail(int_type c = EOF);
§ D.7.1 1250
c
ISO/IEC N????
virtual int_type underflow();
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 streambuf* setbuf(char* s, streamsize n);
private:
typedef T1 strstate; // 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
};
}
1The 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.
2[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 ]
3[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 ]
4Each 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.7.1.1 strstreambuf constructors [depr.strstreambuf.cons]
explicit strstreambuf(streamsize alsize_arg = 0);
1Effects: Constructs an object of class strstreambuf, initializing the base class with streambuf().
The postconditions of this function are indicated in Table 155.
§ D.7.1.1 1251
c
ISO/IEC N????
Table 155 — strstreambuf(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*));
2Effects: Constructs an object of class strstreambuf, initializing the base class with streambuf().
The postconditions of this function are indicated in Table 156.
Table 156 — strstreambuf(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);
3Effects: Constructs an object of class strstreambuf, initializing the base class with streambuf().
The postconditions of this function are indicated in Table 157.
Table 157 — strstreambuf(charT*, streamsize, charT*) effects
Element Value
strmode 0
alsize an unspecified value
palloc a null pointer
pfree a null pointer
4gnext_arg shall point to the first element of an array object whose number of elements Nis determined
as follows:
If n>0,Nis n.
If n == 0,Nis std::strlen(gnext_arg).
If n<0,Nis INT_MAX.340
340) The function signature strlen(const char*) is declared in <cstring>. (21.8). The macro INT_MAX is defined in
<climits> (18.3).
§ D.7.1.1 1252
c
ISO/IEC N????
5If pbeg_arg is a null pointer, the function executes:
setg(gnext_arg, gnext_arg, gnext_arg + N);
6Otherwise, 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);
7Effects: Behaves the same as strstreambuf((char*)gnext_arg,n), except that the constructor also
sets constant in strmode.
virtual ~strstreambuf();
8Effects: Destroys an object of class strstreambuf. The function frees the dynamically allocated array
object only if strmode & allocated != 0 and strmode & frozen == 0. (D.7.1.3 describes how a
dynamically allocated array object is freed.)
D.7.1.2 Member functions [depr.strstreambuf.members]
void freeze(bool freezefl = true);
1Effects: If strmode &dynamic is non-zero, 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();
2Effects: Calls freeze(), then returns the beginning pointer for the input sequence, gbeg.
3Remarks: The return value can be a null pointer.
int pcount() const;
4Effects: 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.7.1.3 strstreambuf overridden virtual functions [depr.strstreambuf.virtuals]
int_type overflow(int_type c = EOF);
1Effects: Appends the character designated by cto 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 cto *pnext++.
2Returns (unsigned char)c.
If c == EOF, there is no character to append.
3Returns a value other than EOF.
§ D.7.1.3 1253
c
ISO/IEC N????
4Returns EOF to indicate failure.
5Remarks: The function can alter the number of write positions available as a result of any call.
6To make a write position available, the function reallocates (or initially allocates) an array object with
a sufficient number of elements nto 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.341
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.
7To 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.
8If 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);
9Puts back the character designated by cto 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.
10 Returns c.
If c != EOF, if the input sequence has a putback position available, and if strmode &constant
is zero, assigns cto *--gnext.
11 Returns c.
— If c == EOF and if the input sequence has a putback position available, assigns gnext - 1 to
gnext.
12 Returns a value other than EOF.
13 Returns EOF to indicate failure.
14 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();
15 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.
16 Returns (unsigned char*)gnext.
17 Returns EOF to indicate failure.
18 Remarks: The function can alter the number of read positions available as a result of any call.
341) An implementation should consider alsize in making this decision.
§ D.7.1.3 1254
c
ISO/IEC N????
pos_type seekoff(off_type off, seekdir way, openmode which = in | out);
19 Effects: Alters the stream position within one of the controlled sequences, if possible, as indicated in
Table 158.
Table 158 — seekoff 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.
20 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 159.
Table 159 — newoff values
Condition newoff Value
way == ios::beg 0
way == ios::cur the next pointer minus the begin-
ning 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
21 Otherwise, the function assigns xbeg +newoff +off to the next pointer xnext.
22 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);
23 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.
§ D.7.1.3 1255
c
ISO/IEC N????
If the function positions neither sequence, the positioning operation fails.
24 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.
25 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);
26 Effects: Implementation defined, except that setbuf(0, 0) has no effect.
D.7.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
};
}
1The 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.7.2.1 istrstream constructors [depr.istrstream.cons]
explicit istrstream(const char* s);
explicit istrstream(char* s);
1Effects: Constructs an object of class istrstream, initializing the base class with istream(&sb) and
initializing sb with strstreambuf(s,0)).sshall designate the first element of an ntbs.
istrstream(const char* s, streamsize n);
2Effects: Constructs an object of class istrstream, initializing the base class with istream(&sb) and
initializing sb with strstreambuf(s,n)).sshall designate the first element of an array whose length
is nelements, and nshall be greater than zero.
§ D.7.2.1 1256
c
ISO/IEC N????
D.7.2.2 Member functions [depr.istrstream.members]
strstreambuf* rdbuf() const;
1Returns: const_cast<strstreambuf*>(&sb).
char* str();
2Returns: rdbuf()->str().
D.7.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
};
}
1The 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.7.3.1 ostrstream constructors [depr.ostrstream.cons]
ostrstream();
1Effects: 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);
2Effects: 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 sshall designate the first element of an array of nelements.
The constructor is strstreambuf(s, n, s).
— If (mode & app) != 0, then sshall designate the first element of an array of nelements that
contains an ntbs whose first element is designated by s. The constructor is strstreambuf(s,
n, s + std::strlen(s)).342
342) The function signature strlen(const char*) is declared in <cstring> (21.8).
§ D.7.3.1 1257
c
ISO/IEC N????
D.7.3.2 Member functions [depr.ostrstream.members]
strstreambuf* rdbuf() const;
1Returns: (strstreambuf*)&sb .
void freeze(bool freezefl = true);
2Effects: Calls rdbuf()->freeze(freezefl).
char* str();
3Returns: rdbuf()->str().
int pcount() const;
4Returns: rdbuf()->pcount().
D.7.4 Class strstream [depr.strstream]
namespace std {
class strstream
: public basic_iostream<char> {
public:
// Types
typedef char char_type;
typedef typename char_traits<char>::int_type int_type;
typedef typename char_traits<char>::pos_type pos_type;
typedef typename char_traits<char>::off_type 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
};
}
1The class strstream supports reading and writing from objects of classs 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.7.4 1258
c
ISO/IEC N????
D.7.4.1 strstream constructors [depr.strstream.cons]
strstream();
1Effects: 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);
2Effects: 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 sshall designate the first element of an array of nelements. The
constructor is strstreambuf(s,n,s).
— If (mode & app) != 0, then sshall designate the first element of an array of nelements that
contains an ntbs whose first element is designated by s. The constructor is strstreambuf(s,n,s
+ std::strlen(s)).
D.7.4.2 strstream destructor [depr.strstream.dest]
virtual ~strstream()
1Effects: Destroys an object of class strstream.
strstreambuf* rdbuf() const;
2Returns: &sb.
D.7.4.3 strstream operations [depr.strstream.oper]
void freeze(bool freezefl = true);
1Effects: Calls rdbuf()->freeze(freezefl).
char* str();
2Returns: rdbuf()->str().
int pcount() const;
3Returns: rdbuf()->pcount().
D.8 Function objects [depr.function.objects]
D.8.1 Base [depr.base]
1The class templates unary_function and binary_function are deprecated. A program shall not declare
specializations of these templates.
namespace std {
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
}
§ D.8.1 1259
c
ISO/IEC N????
namespace std {
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
}
D.8.2 Function adaptors [depr.adaptors]
1The adaptors ptr_fun, mem_fun, mem_fun_ref, and their corresponding return types are deprecated.
[Note: The function template bind 20.10.9.1 provides a better solution. — end note ]
D.8.2.1 Adaptors for pointers to functions [depr.function.pointer.adaptors]
1To allow pointers to (unary and binary) functions to work with function adaptors the library provides:
template <class Arg, class Result>
class pointer_to_unary_function : public unary_function<Arg, Result> {
public:
explicit pointer_to_unary_function(Result (*f)(Arg));
Result operator()(Arg x) const;
};
2operator() returns f(x).
template <class Arg, class Result>
pointer_to_unary_function<Arg, Result> ptr_fun(Result (*f)(Arg));
3Returns: pointer_to_unary_function<Arg, Result>(f).
template <class Arg1, class Arg2, class Result>
class pointer_to_binary_function :
public binary_function<Arg1,Arg2,Result> {
public:
explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2));
Result operator()(Arg1 x, Arg2 y) const;
};
4operator() returns f(x,y).
template <class Arg1, class Arg2, class Result>
pointer_to_binary_function<Arg1,Arg2,Result>
ptr_fun(Result (*f)(Arg1, Arg2));
5Returns: pointer_to_binary_function<Arg1,Arg2,Result>(f).
6[Example:
int compare(const char*, const char*);
replace_if(v.begin(), v.end(),
not1(bind2nd(ptr_fun(compare), "abc")), "def");
replaces each abc with def in sequence v.— end example ]
§ D.8.2.1 1260
c
ISO/IEC N????
D.8.2.2 Adaptors for pointers to members [depr.member.pointer.adaptors]
1The purpose of the following is to provide the same facilities for pointer to members as those provided for
pointers to functions in D.8.2.1.
template <class S, class T> class mem_fun_t
: public unary_function<T*, S> {
public:
explicit mem_fun_t(S (T::*p)());
S operator()(T* p) const;
};
2mem_fun_t calls the member function it is initialized with given a pointer argument.
template <class S, class T, class A> class mem_fun1_t
: public binary_function<T*, A, S> {
public:
explicit mem_fun1_t(S (T::*p)(A));
S operator()(T* p, A x) const;
};
3mem_fun1_t calls the member function it is initialized with given a pointer argument and an additional
argument of the appropriate type.
template<class S, class T> mem_fun_t<S,T>
mem_fun(S (T::*f)());
template<class S, class T, class A> mem_fun1_t<S,T,A>
mem_fun(S (T::*f)(A));
4mem_fun(&X::f) returns an object through which X::f can be called given a pointer to an Xfollowed
by the argument required for f(if any).
template <class S, class T> class mem_fun_ref_t
: public unary_function<T, S> {
public:
explicit mem_fun_ref_t(S (T::*p)());
S operator()(T& p) const;
};
5mem_fun_ref_t calls the member function it is initialized with given a reference argument.
template <class S, class T, class A> class mem_fun1_ref_t
: public binary_function<T, A, S> {
public:
explicit mem_fun1_ref_t(S (T::*p)(A));
S operator()(T& p, A x) const;
};
6mem_fun1_ref_t calls the member function it is initialized with given a reference argument and an
additional argument of the appropriate type.
§ D.8.2.2 1261
c
ISO/IEC N????
template<class S, class T> mem_fun_ref_t<S,T>
mem_fun_ref(S (T::*f)());
template<class S, class T, class A> mem_fun1_ref_t<S,T,A>
mem_fun_ref(S (T::*f)(A));
7mem_fun_ref(&X::f) returns an object through which X::f can be called given a reference to an X
followed by the argument required for f(if any).
template <class S, class T> class const_mem_fun_t
: public unary_function<const T*, S> {
public:
explicit const_mem_fun_t(S (T::*p)() const);
S operator()(const T* p) const;
};
8const_mem_fun_t calls the member function it is initialized with given a pointer argument.
template <class S, class T, class A> class const_mem_fun1_t
: public binary_function<const T*, A, S> {
public:
explicit const_mem_fun1_t(S (T::*p)(A) const);
S operator()(const T* p, A x) const;
};
9const_mem_fun1_t calls the member function it is initialized with given a pointer argument and an
additional argument of the appropriate type.
template<class S, class T> const_mem_fun_t<S,T>
mem_fun(S (T::*f)() const);
template<class S, class T, class A> const_mem_fun1_t<S,T,A>
mem_fun(S (T::*f)(A) const);
10 mem_fun(&X::f) returns an object through which X::f can be called given a pointer to an Xfollowed
by the argument required for f(if any).
template <class S, class T> class const_mem_fun_ref_t
: public unary_function<T, S> {
public:
explicit const_mem_fun_ref_t(S (T::*p)() const);
S operator()(const T& p) const;
};
11 const_mem_fun_ref_t calls the member function it is initialized with given a reference argument.
template <class S, class T, class A> class const_mem_fun1_ref_t
: public binary_function<T, A, S> {
public:
explicit const_mem_fun1_ref_t(S (T::*p)(A) const);
S operator()(const T& p, A x) const;
};
§ D.8.2.2 1262
c
ISO/IEC N????
12 const_mem_fun1_ref_t calls the member function it is initialized with given a reference argument and
an additional argument of the appropriate type.
template<class S, class T> const_mem_fun_ref_t<S,T>
mem_fun_ref(S (T::*f)() const);
template<class S, class T, class A> const_mem_fun1_ref_t<S,T,A>
mem_fun_ref(S (T::*f)(A) const);
13 mem_fun_ref(&X::f) returns an object through which X::f can be called given a reference to an X
followed by the argument required for f(if any).
D.9 Binders [depr.lib.binders]
The binders binder1st,bind1st,binder2nd, and bind2nd are deprecated. [ Note: The function tem-
plate bind (20.10.9) provides a better solution. — end note ]
D.9.1 Class template binder1st [depr.lib.binder.1st]
template <class Fn>
class binder1st
: public unary_function<typename Fn::second_argument_type,
typename Fn::result_type> {
protected:
Fn op;
typename Fn::first_argument_type value;
public:
binder1st(const Fn& x,
const typename Fn::first_argument_type& y);
typename Fn::result_type
operator()(const typename Fn::second_argument_type& x) const;
typename Fn::result_type
operator()(typename Fn::second_argument_type& x) const;
};
1The constructor initializes op with xand value with y.
2operator() returns op(value,x).
D.9.2 bind1st [depr.lib.bind.1st]
template <class Fn, class T>
binder1st<Fn> bind1st(const Fn& fn, const T& x);
1Returns: binder1st<Fn>(fn, typename Fn::first_argument_type(x)).
D.9.3 Class template binder2nd [depr.lib.binder.2nd]
template <class Fn>
class binder2nd
: public unary_function<typename Fn::first_argument_type,
typename Fn::result_type> {
protected:
Fn op;
typename Fn::second_argument_type value;
public:
binder2nd(const Fn& x,
const typename Fn::second_argument_type& y);
§ D.9.3 1263
c
ISO/IEC N????
typename Fn::result_type
operator()(const typename Fn::first_argument_type& x) const;
typename Fn::result_type
operator()(typename Fn::first_argument_type& x) const;
};
1The constructor initializes op with xand value with y.
2operator() returns op(x,value).
D.9.4 bind2nd [depr.lib.bind.2nd]
template <class Fn, class T>
binder2nd<Fn> bind2nd(const Fn& op, const T& x);
1Returns: binder2nd<Fn>(op, typename Fn::second_argument_type(x)).
2[Example:
find_if(v.begin(), v.end(), bind2nd(greater<int>(), 5));
finds the first integer in vector vgreater than 5;
find_if(v.begin(), v.end(), bind1st(greater<int>(), 5));
finds the first integer in vless than 5. — end example ]
D.10 auto_ptr [depr.auto.ptr]
The class template auto_ptr is deprecated. [ Note: The class template unique_ptr (20.9.1) provides a
better solution. — end note ]
D.10.1 Class template auto_ptr [auto.ptr]
1The class template auto_ptr stores a pointer to an object obtained via new and deletes that object when it
itself is destroyed (such as when leaving block scope 6.7).
2The class template auto_ptr_ref is for exposition only. An implementation is permitted to provide equiv-
alent functionality without providing a template with this name. The template holds a reference to an
auto_ptr. It is used by the auto_ptr conversions to allow auto_ptr objects to be passed to and returned
from functions.
namespace std {
template <class Y> struct auto_ptr_ref; // exposition only
template <class X> class auto_ptr {
public:
typedef X element_type;
// D.10.1.1 construct/copy/destroy:
explicit auto_ptr(X* p =0) throw();
auto_ptr(auto_ptr&) throw();
template<class Y> auto_ptr(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr&) throw();
template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr_ref<X> r) throw();
~auto_ptr() throw();
// D.10.1.2 members:
X& operator*() const throw();
X* operator->() const throw();
X* get() const throw();
§ D.10.1 1264
c
ISO/IEC N????
X* release() throw();
void reset(X* p =0) throw();
// D.10.1.3 conversions:
auto_ptr(auto_ptr_ref<X>) throw();
template<class Y> operator auto_ptr_ref<Y>() throw();
template<class Y> operator auto_ptr<Y>() throw();
};
template <> class auto_ptr<void>
{
public:
typedef void element_type;
};
}
3The class template auto_ptr provides a semantics of strict ownership. An auto_ptr owns the object it holds
a pointer to. Copying an auto_ptr copies the pointer and transfers ownership to the destination. If more than
one auto_ptr owns the same object at the same time the behavior of the program is undefined. [ Note: The
uses of auto_ptr include providing temporary exception-safety for dynamically allocated memory, passing
ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from
a function. Instances of auto_ptr meet the requirements of MoveConstructible and MoveAssignable, but
do not meet the requirements of CopyConstructible and CopyAssignable.— end note ]
D.10.1.1 auto_ptr constructors [auto.ptr.cons]
explicit auto_ptr(X* p =0) throw();
1Postconditions: *this holds the pointer p.
auto_ptr(auto_ptr& a) throw();
2Effects: Calls a.release().
3Postconditions: *this holds the pointer returned from a.release().
template<class Y> auto_ptr(auto_ptr<Y>& a) throw();
4Requires: Y* can be implicitly converted to X*.
5Effects: Calls a.release().
6Postconditions: *this holds the pointer returned from a.release().
auto_ptr& operator=(auto_ptr& a) throw();
7Requires: The expression delete get() is well formed.
8Effects: reset(a.release()).
9Returns: *this.
template<class Y> auto_ptr& operator=(auto_ptr<Y>& a) throw();
10 Requires: Y* can be implicitly converted to X*. The expression delete get() is well formed.
11 Effects: reset(a.release()).
12 Returns: *this.
§ D.10.1.1 1265
c
ISO/IEC N????
~auto_ptr() throw();
13 Requires: The expression delete get() is well formed.
14 Effects: delete get().
D.10.1.2 auto_ptr members [auto.ptr.members]
X& operator*() const throw();
1Requires: get() != 0
2Returns: *get()
X* operator->() const throw();
3Returns: get()
X* get() const throw();
4Returns: The pointer *this holds.
X* release() throw();
5Returns: get()
6Postcondition: *this holds the null pointer.
void reset(X* p=0) throw();
7Effects: If get() != p then delete get().
8Postconditions: *this holds the pointer p.
D.10.1.3 auto_ptr conversions [auto.ptr.conv]
auto_ptr(auto_ptr_ref<X> r) throw();
1Effects: Calls p.release() for the auto_ptr p that rholds.
2Postconditions: *this holds the pointer returned from release().
template<class Y> operator auto_ptr_ref<Y>() throw();
3Returns: An auto_ptr_ref<Y> that holds *this.
template<class Y> operator auto_ptr<Y>() throw();
4Effects: Calls release().
5Returns: An auto_ptr<Y> that holds the pointer returned from release().
auto_ptr& operator=(auto_ptr_ref<X> r) throw()
6Effects: Calls reset(p.release()) for the auto_ptr p that rholds a reference to.
7Returns: *this
§ D.10.1.3 1266
c
ISO/IEC N????
D.11 Violating exception-specifications [exception.unexpected]
D.11.1 Type unexpected_handler [unexpected.handler]
typedef void (*unexpected_handler)();
1The type of a handler function to be called by unexpected() when a function attempts to throw an
exception not listed in its dynamic-exception-specification.
2Required behavior: An unexpected_handler shall not return. See also 15.5.2.
3Default behavior: The implementation’s default unexpected_handler calls std::terminate().
D.11.2 set_unexpected [set.unexpected]
unexpected_handler set_unexpected(unexpected_handler f) noexcept;
1Effects: Establishes the function designated by fas the current unexpected_handler.
2Remark: It is unspecified whether a null pointer value designates the default unexpected_handler.
3Returns: The previous unexpected_handler.
D.11.3 get_unexpected [get.unexpected]
unexpected_handler get_unexpected() noexcept;
1Returns: The current unexpected_handler. [ Note: This may be a null pointer value. — end note ]
D.11.4 unexpected [unexpected]
[[noreturn]] void unexpected();
1Remarks: Called by the implementation when a function exits via an exception not allowed by its
exception-specification (15.5.2), in effect after evaluating the throw-expression (D.11.1). May also be
called directly by the program.
2Effects: Calls the current unexpected_handler function. [ Note: A default unexpected_handler is
always considered a callable handler in this context. — end note ]
§ D.11.4 1267
c
ISO/IEC N????
Annex E (normative)
Universal character names for identifier
characters [charname]
E.1 Ranges of characters allowed [charname.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-303F
3040-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
E.2 Ranges of characters disallowed initially [charname.disallowed]
0300-036F, 1DC0-1DFF, 20D0-20FF, FE20-FE2F
§ E.2 1268
c
ISO/IEC N????
Annex F (informative)
Cross references [xref]
This annex lists each section label and the corresponding section number, in alphabetical order by label. All
of the section labels are the same as in the 2003 standard, except:
labels that begin with lib. in the 2003 standard have had the lib. removed so that they do not all
appear in the same part of this list. For example, in the 2003 standard, the non-modifying sequence
algorithms were found in a section with the label [lib.alg.nonmodifying]. The label for that section
is now [alg.nonmodifying].
the label for Annex Bhas been changed from [limits] to [implimits]. The label [limits] refers
to section 18.3.2.
A
accumulate 26.7.2
adjacent.difference 26.7.5
adjustfield.manip 27.5.6.2
alg.adjacent.find 25.2.8
alg.all_of 25.2.1
alg.any_of 25.2.2
alg.binary.search 25.4.3
alg.c.library 25.5
alg.copy 25.3.1
alg.count 25.2.9
alg.equal 25.2.11
alg.fill 25.3.6
alg.find 25.2.5
alg.find.end 25.2.6
alg.find.first.of 25.2.7
alg.foreach 25.2.4
alg.generate 25.3.7
alg.heap.operations 25.4.6
alg.is_permutation 25.2.12
alg.lex.comparison 25.4.8
alg.merge 25.4.4
alg.min.max 25.4.7
alg.modifying.operations 25.3
alg.move 25.3.2
alg.none_of 25.2.3
alg.nonmodifying 25.2
alg.nth.element 25.4.2
alg.partitions 25.3.13
alg.permutation.generators 25.4.9
alg.random.shuffle 25.3.12
alg.remove 25.3.8
alg.replace 25.3.5
alg.reverse 25.3.10
alg.rotate 25.3.11
alg.search 25.2.13
alg.set.operations 25.4.5
alg.sort 25.4.1
alg.sorting 25.4
alg.swap 25.3.3
alg.transform 25.3.4
alg.unique 25.3.9
algorithm.stable 17.6.5.7
algorithms 25
algorithms.general 25.1
alloc.errors 18.6.2
allocator.adaptor 20.14
allocator.adaptor.cnstr 20.14.3
allocator.adaptor.members 20.14.4
allocator.adaptor.syn 20.14.1
allocator.adaptor.types 20.14.2
allocator.globals 20.8.9.2
allocator.members 20.8.9.1
allocator.requirements 17.6.3.5
allocator.tag 20.8.6
allocator.traits 20.8.8
allocator.traits.members 20.8.8.2
allocator.traits.types 20.8.8.1
allocator.uses 20.8.7
allocator.uses.construction 20.8.7.2
allocator.uses.trait 20.8.7.1
alt.headers 17.6.4.4
arithmetic.operations 20.10.4
array 23.3.2
array.cons 23.3.2.2
array.data 23.3.2.5
Cross references 1269
c
ISO/IEC N????
array.fill 23.3.2.6
array.overview 23.3.2.1
array.size 23.3.2.4
array.special 23.3.2.3
array.swap 23.3.2.7
array.tuple 23.3.2.9
array.zero 23.3.2.8
assertions 19.3
associative 23.4
associative.general 23.4.1
associative.map.syn 23.4.2
associative.reqmts 23.2.4
associative.reqmts.except 23.2.4.1
associative.set.syn 23.4.3
atomics 29
atomics.fences 29.8
atomics.flag 29.7
atomics.general 29.1
atomics.lockfree 29.4
atomics.order 29.3
atomics.syn 29.2
atomics.types.generic 29.5
atomics.types.operations 29.6
atomics.types.operations.arith 29.6.3
atomics.types.operations.general 29.6.1
atomics.types.operations.pointer 29.6.4
atomics.types.operations.req 29.6.5
atomics.types.operations.templ 29.6.2
auto.ptr D.10.1
auto.ptr.cons D.10.1.1
auto.ptr.conv D.10.1.3
auto.ptr.members D.10.1.2
B
back.insert.iter.cons 24.5.2.2.1
back.insert.iter.op* 24.5.2.2.3
back.insert.iter.op++ 24.5.2.2.4
back.insert.iter.op= 24.5.2.2.2
back.insert.iter.ops 24.5.2.2
back.insert.iterator 24.5.2.1
back.inserter 24.5.2.2.5
bad.alloc 18.6.2.1
bad.array.length 18.6.2.2
bad.cast 18.7.2
bad.exception 18.8.2
bad.typeid 18.7.3
basefield.manip 27.5.6.3
basic 3
basic.align 3.11
basic.compound 3.9.2
basic.def 3.1
basic.def.odr 3.2
basic.fundamental 3.9.1
basic.funscope 3.3.5
basic.ios.cons 27.5.5.2
basic.ios.members 27.5.5.3
basic.life 3.8
basic.link 3.5
basic.lookup 3.4
basic.lookup.argdep 3.4.2
basic.lookup.classref 3.4.5
basic.lookup.elab 3.4.4
basic.lookup.qual 3.4.3
basic.lookup.udir 3.4.6
basic.lookup.unqual 3.4.1
basic.lval 3.10
basic.namespace 7.3
basic.scope 3.3
basic.scope.block 3.3.3
basic.scope.class 3.3.7
basic.scope.declarative 3.3.1
basic.scope.enum 3.3.8
basic.scope.hiding 3.3.10
basic.scope.namespace 3.3.6
basic.scope.pdecl 3.3.2
basic.scope.proto 3.3.4
basic.scope.temp 3.3.9
basic.start 3.6
basic.start.init 3.6.2
basic.start.main 3.6.1
basic.start.term 3.6.3
basic.stc 3.7
basic.stc.auto 3.7.3
basic.stc.dynamic 3.7.4
basic.stc.dynamic.allocation 3.7.4.1
basic.stc.dynamic.deallocation 3.7.4.2
basic.stc.dynamic.safety 3.7.4.3
basic.stc.inherit 3.7.5
basic.stc.static 3.7.1
basic.stc.thread 3.7.2
basic.string 21.4
basic.string.hash 21.6
basic.string.literals 21.7
basic.type.qualifier 3.9.3
basic.types 3.9
bidirectional.iterators 24.2.6
binary.search 25.4.3.4
bind 20.10.9
bitmask.types 17.5.2.1.3
bitset.cons 20.7.1
bitset.hash 20.7.3
bitset.members 20.7.2
Cross references 1270
c
ISO/IEC N????
bitset.operators 20.7.4
bitwise.operations 20.10.7
byte.strings 17.5.2.1.4.1
C
c.files 27.9.2
c.limits 18.3.3
c.locales 22.6
c.malloc 20.8.13
c.math 26.8
c.strings 21.8
category.collate 22.4.4
category.ctype 22.4.1
category.messages 22.4.7
category.monetary 22.4.6
category.numeric 22.4.2
category.time 22.4.5
ccmplx 26.4.10
cfenv 26.3
cfenv.syn 26.3.1
char.traits 21.2
char.traits.require 21.2.1
char.traits.specializations 21.2.3
char.traits.specializations.char 21.2.3.1
char.traits.specializations.char16_t 21.2.3.2
char.traits.specializations.char32_t 21.2.3.3
char.traits.specializations.wchar.t 21.2.3.4
char.traits.typedefs 21.2.2
character.seq 17.5.2.1.4
charname E
charname.allowed E.1
charname.disallowed E.2
class 9
class.abstract 10.4
class.access 11
class.access.base 11.2
class.access.nest 11.7
class.access.spec 11.1
class.access.virt 11.5
class.base.init 12.6.2
class.bit 9.6
class.cdtor 12.7
class.conv 12.3
class.conv.ctor 12.3.1
class.conv.fct 12.3.2
class.copy 12.8
class.ctor 12.1
class.derived 10
class.dtor 12.4
class.expl.init 12.6.1
class.free 12.5
class.friend 11.3
class.gslice 26.6.6
class.gslice.overview 26.6.6.1
class.inhctor 12.9
class.init 12.6
class.local 9.8
class.mem 9.2
class.member.lookup 10.2
class.mfct 9.3
class.mfct.non-static 9.3.1
class.mi 10.1
class.name 9.1
class.nest 9.7
class.nested.type 9.9
class.paths 11.6
class.protected 11.4
class.qual 3.4.3.1
class.slice 26.6.4
class.slice.overview 26.6.4.1
class.static 9.4
class.static.data 9.4.2
class.static.mfct 9.4.1
class.temporary 12.2
class.this 9.3.2
class.union 9.5
class.virtual 10.3
classification 22.3.3.1
cmplx.over 26.4.9
comparisons 20.10.5
complex 26.4.2
complex.member.ops 26.4.5
complex.members 26.4.4
complex.numbers 26.4
complex.ops 26.4.6
complex.special 26.4.3
complex.syn 26.4.1
complex.transcendentals 26.4.8
complex.value.ops 26.4.7
compliance 17.6.1.3
conforming 17.6.5
conforming.overview 17.6.5.1
cons.slice 26.6.4.2
constexpr.functions 17.6.5.6
constraints 17.6.4
constraints.overview 17.6.4.1
container.adaptors 23.6
container.adaptors.general 23.6.1
container.requirements 23.2
container.requirements.dataraces 23.2.2
container.requirements.general 23.2.1
containers 23
Cross references 1271
c
ISO/IEC N????
containers.general 23.1
contents 17.6.1.1
conv 4
conv.array 4.2
conv.bool 4.12
conv.double 4.8
conv.fpint 4.9
conv.fpprom 4.6
conv.func 4.3
conv.integral 4.7
conv.lval 4.1
conv.mem 4.11
conv.prom 4.5
conv.ptr 4.10
conv.qual 4.4
conv.rank 4.13
conventions 17.5.2
conversions 22.3.3.2
conversions.buffer 22.3.3.2.3
conversions.character 22.3.3.2.1
conversions.string 22.3.3.2.2
cpp 16
cpp.concat 16.3.3
cpp.cond 16.1
cpp.error 16.5
cpp.include 16.2
cpp.line 16.4
cpp.null 16.7
cpp.pragma 16.6
cpp.pragma.op 16.9
cpp.predefined 16.8
cpp.replace 16.3
cpp.rescan 16.3.4
cpp.scope 16.3.5
cpp.stringize 16.3.2
cpp.subst 16.3.1
cstdint 18.4
cstdint.syn 18.4.1
D
date.time 20.13.8
dcl.align 7.6.2
dcl.ambig.res 8.2
dcl.array 8.3.4
dcl.asm 7.4
dcl.attr 7.6
dcl.attr.depend 7.6.4
dcl.attr.grammar 7.6.1
dcl.attr.noreturn 7.6.3
dcl.constexpr 7.1.5
dcl.dcl 7
dcl.decl 8
dcl.enum 7.2
dcl.fct 8.3.5
dcl.fct.def 8.4
dcl.fct.def.default 8.4.2
dcl.fct.def.delete 8.4.3
dcl.fct.def.general 8.4.1
dcl.fct.default 8.3.6
dcl.fct.spec 7.1.2
dcl.friend 7.1.4
dcl.init 8.5
dcl.init.aggr 8.5.1
dcl.init.list 8.5.4
dcl.init.ref 8.5.3
dcl.init.string 8.5.2
dcl.link 7.5
dcl.meaning 8.3
dcl.mptr 8.3.3
dcl.name 8.1
dcl.ptr 8.3.1
dcl.ref 8.3.2
dcl.spec 7.1
dcl.spec.auto 7.1.6.4
dcl.stc 7.1.1
dcl.type 7.1.6
dcl.type.cv 7.1.6.1
dcl.type.elab 7.1.6.3
dcl.type.simple 7.1.6.2
dcl.typedef 7.1.3
declval 20.2.5
default.allocator 20.8.9
definitions 17.3
defns.additional 17.4
defns.arbitrary.stream
defns.argument
defns.argument.macro
defns.argument.templ
defns.argument.throw
defns.block
defns.blocked
defns.character
defns.character.container
defns.comparison
defns.component
defns.cond.supp
defns.deadlock
defns.default.behavior.func
defns.default.behavior.impl
defns.diagnostic
defns.direct-non-list-init
defns.dynamic.type
Cross references 1272
c
ISO/IEC N????
defns.dynamic.type.prvalue
defns.handler
defns.ill.formed
defns.impl.defined
defns.impl.limits
defns.iostream.templates
defns.locale.specific
defns.modifier
defns.move.assign
defns.move.constr
defns.multibyte
defns.ntcts
defns.obj.state
defns.observer
defns.parameter
defns.parameter.macro
defns.parameter.templ
defns.referenceable
defns.regex.collating.element
defns.regex.finite.state.machine
defns.regex.format.specifier
defns.regex.matched
defns.regex.primary.equivalence.class
defns.regex.regular.expression
defns.regex.subexpression
defns.replacement
defns.repositional.stream
defns.required.behavior
defns.reserved.function
defns.signature
defns.signature.member
defns.signature.member.spec
defns.signature.member.templ
defns.signature.spec
defns.signature.templ
defns.stable
defns.static.type
defns.traits
defns.unblock
defns.undefined
defns.unspecified
defns.valid
defns.well.formed
denorm.style 18.3.2.6
depr D
depr.adaptors D.8.2
depr.auto.ptr D.10
depr.base D.8.1
depr.c.headers D.5
depr.except.spec D.4
depr.function.objects D.8
depr.function.pointer.adaptors D.8.2.1
depr.impldec D.3
depr.incr.bool D.1
depr.ios.members D.6
depr.istrstream D.7.2
depr.istrstream.cons D.7.2.1
depr.istrstream.members D.7.2.2
depr.lib.bind.1st D.9.2
depr.lib.bind.2nd D.9.4
depr.lib.binder.1st D.9.1
depr.lib.binder.2nd D.9.3
depr.lib.binders D.9
depr.member.pointer.adaptors D.8.2.2
depr.ostrstream D.7.3
depr.ostrstream.cons D.7.3.1
depr.ostrstream.members D.7.3.2
depr.register D.2
depr.str.strstreams D.7
depr.strstream D.7.4
depr.strstream.cons D.7.4.1
depr.strstream.dest D.7.4.2
depr.strstream.oper D.7.4.3
depr.strstreambuf D.7.1
depr.strstreambuf.cons D.7.1.1
depr.strstreambuf.members D.7.1.2
depr.strstreambuf.virtuals D.7.1.3
deque 23.3.3
deque.capacity 23.3.3.3
deque.cons 23.3.3.2
deque.modifiers 23.3.3.4
deque.overview 23.3.3.1
deque.special 23.3.3.5
derivation 17.6.5.11
derived.classes 17.6.4.5
description 17.5
diagnostics 19
diagnostics.general 19.1
diff C
diff.basic C.1.2
diff.char16 C.4.2.1
diff.class C.1.8
diff.conv C.1.3
diff.cpp C.1.10
diff.cpp03 C.2
diff.cpp03.algorithms C.2.14
diff.cpp03.containers C.2.13
diff.cpp03.conv C.2.2
diff.cpp03.dcl.dcl C.2.4
diff.cpp03.dcl.decl C.2.5
diff.cpp03.diagnostics C.2.10
diff.cpp03.expr C.2.3
Cross references 1273
c
ISO/IEC N????
diff.cpp03.input.output C.2.16
diff.cpp03.language.support C.2.9
diff.cpp03.lex C.2.1
diff.cpp03.library C.2.8
diff.cpp03.numerics C.2.15
diff.cpp03.special C.2.6
diff.cpp03.strings C.2.12
diff.cpp03.temp C.2.7
diff.cpp03.utilities C.2.11
diff.cpp11 C.3
diff.cpp11.dcl.dcl C.3.1
diff.dcl C.1.6
diff.decl C.1.7
diff.expr C.1.4
diff.header.iso646.h C.4.2.3
diff.iso C.1
diff.lex C.1.1
diff.library C.4
diff.malloc C.4.4.2
diff.mods.to.behavior C.4.4
diff.mods.to.declarations C.4.3
diff.mods.to.definitions C.4.2
diff.mods.to.headers C.4.1
diff.null C.4.2.4
diff.offsetof C.4.4.1
diff.special C.1.9
diff.stat C.1.5
diff.wchar.t C.4.2.2
domain.error 19.2.2
dynarray 23.3.4
dynarray.cons 23.3.4.2
dynarray.data 23.3.4.3
dynarray.mutate 23.3.4.4
dynarray.overview 23.3.4.1
dynarray.traits 23.3.4.6
dynarray.zero 23.3.4.5
E
enumerated.types 17.5.2.1.2
equal.range 25.4.3.3
errno 19.4
error.reporting 27.5.6.5
except 15
except.ctor 15.2
except.handle 15.3
except.nested 18.8.6
except.spec 15.4
except.special 15.5
except.terminate 15.5.1
except.throw 15.1
except.uncaught 15.5.3
except.unexpected 15.5.2
exception 18.8.1
exception.terminate 18.8.3
exception.unexpected D.11
expr 5
expr.add 5.7
expr.alignof 5.3.6
expr.ass 5.17
expr.bit.and 5.11
expr.call 5.2.2
expr.cast 5.4
expr.comma 5.18
expr.cond 5.16
expr.const 5.19
expr.const.cast 5.2.11
expr.delete 5.3.5
expr.dynamic.cast 5.2.7
expr.eq 5.10
expr.log.and 5.14
expr.log.or 5.15
expr.mptr.oper 5.5
expr.mul 5.6
expr.new 5.3.4
expr.or 5.13
expr.post 5.2
expr.post.incr 5.2.6
expr.pre.incr 5.3.2
expr.prim 5.1
expr.prim.general 5.1.1
expr.prim.lambda 5.1.2
expr.pseudo 5.2.4
expr.ref 5.2.5
expr.reinterpret.cast 5.2.10
expr.rel 5.9
expr.shift 5.8
expr.sizeof 5.3.3
expr.static.cast 5.2.9
expr.sub 5.2.1
expr.type.conv 5.2.3
expr.typeid 5.2.8
expr.unary 5.3
expr.unary.noexcept 5.3.7
expr.unary.op 5.3.1
expr.xor 5.12
ext.manip 27.7.5
extern.names 17.6.4.3.3
extern.types 17.6.4.3.4
F
facet.ctype.char.dtor 22.4.1.3.1
facet.ctype.char.members 22.4.1.3.2
Cross references 1274
c
ISO/IEC N????
facet.ctype.char.statics 22.4.1.3.3
facet.ctype.char.virtuals 22.4.1.3.4
facet.ctype.special 22.4.1.3
facet.num.get.members 22.4.2.1.1
facet.num.get.virtuals 22.4.2.1.2
facet.num.put.members 22.4.2.2.1
facet.num.put.virtuals 22.4.2.2.2
facet.numpunct 22.4.3
facet.numpunct.members 22.4.3.1.1
facet.numpunct.virtuals 22.4.3.1.2
facets.examples 22.4.8
file.streams 27.9
filebuf 27.9.1.1
filebuf.assign 27.9.1.3
filebuf.cons 27.9.1.2
filebuf.members 27.9.1.4
filebuf.virtuals 27.9.1.5
floatfield.manip 27.5.6.4
fmtflags.manip 27.5.6.1
fmtflags.state 27.5.3.2
forward 20.2.4
forward.iterators 24.2.5
forwardlist 23.3.5
forwardlist.access 23.3.5.4
forwardlist.cons 23.3.5.2
forwardlist.iter 23.3.5.3
forwardlist.modifiers 23.3.5.5
forwardlist.ops 23.3.5.6
forwardlist.overview 23.3.5.1
forwardlist.spec 23.3.5.7
fpos 27.5.4
fpos.members 27.5.4.1
fpos.operations 27.5.4.2
front.insert.iter.cons 24.5.2.4.1
front.insert.iter.op* 24.5.2.4.3
front.insert.iter.op++ 24.5.2.4.4
front.insert.iter.op= 24.5.2.4.2
front.insert.iter.ops 24.5.2.4
front.insert.iterator 24.5.2.3
front.inserter 24.5.2.4.5
fstream 27.9.1.14
fstream.assign 27.9.1.16
fstream.cons 27.9.1.15
fstream.members 27.9.1.17
fstreams 27.9.1
func.bind 20.10.9.1
func.bind.bind 20.10.9.1.3
func.bind.isbind 20.10.9.1.1
func.bind.isplace 20.10.9.1.2
func.bind.place 20.10.9.1.4
func.def 20.10.1
func.memfn 20.10.10
func.require 20.10.2
func.wrap 20.10.11
func.wrap.badcall 20.10.11.1
func.wrap.badcall.const 20.10.11.1.1
func.wrap.func 20.10.11.2
func.wrap.func.alg 20.10.11.2.7
func.wrap.func.cap 20.10.11.2.3
func.wrap.func.con 20.10.11.2.1
func.wrap.func.inv 20.10.11.2.4
func.wrap.func.mod 20.10.11.2.2
func.wrap.func.nullptr 20.10.11.2.6
func.wrap.func.targ 20.10.11.2.5
function.objects 20.10
functions.within.classes 17.5.2.2
futures 30.6
futures.async 30.6.8
futures.errors 30.6.2
futures.future_error 30.6.3
futures.overview 30.6.1
futures.promise 30.6.5
futures.shared_future 30.6.7
futures.state 30.6.4
futures.task 30.6.9
futures.task.members 30.6.9.1
futures.task.nonmembers 30.6.9.2
futures.unique_future 30.6.6
G
get.new.handler 18.6.2.6
get.terminate 18.8.3.3
get.unexpected D.11.3
global.functions 17.6.5.4
global.names 17.6.4.3.2
gram A
gram.basic A.3
gram.class A.8
gram.cpp A.14
gram.dcl A.6
gram.decl A.7
gram.derived A.9
gram.except A.13
gram.expr A.4
gram.key A.1
gram.lex A.2
gram.over A.11
gram.special A.10
gram.stmt A.5
gram.temp A.12
gslice.access 26.6.6.3
gslice.array.assign 26.6.7.2
Cross references 1275
c
ISO/IEC N????
gslice.array.comp.assign 26.6.7.3
gslice.array.fill 26.6.7.4
gslice.cons 26.6.6.2
H
handler.functions 17.6.4.7
hash.requirements 17.6.3.4
headers 17.6.1.2
I
ifstream 27.9.1.6
ifstream.assign 27.9.1.8
ifstream.cons 27.9.1.7
ifstream.members 27.9.1.9
implimits B
includes 25.4.5.1
indirect.array.assign 26.6.9.2
indirect.array.comp.assign 26.6.9.3
indirect.array.fill 26.6.9.4
inner.product 26.7.3
input.iterators 24.2.3
input.output 27
input.output.general 27.1
input.streams 27.7.2
insert.iter.cons 24.5.2.6.1
insert.iter.op* 24.5.2.6.3
insert.iter.op++ 24.5.2.6.4
insert.iter.op= 24.5.2.6.2
insert.iter.ops 24.5.2.6
insert.iterator 24.5.2.5
insert.iterators 24.5.2
inserter 24.5.2.6.5
intro 1
intro.ack 1.11
intro.compliance 1.4
intro.defs 1.3
intro.execution 1.9
intro.memory 1.7
intro.multithread 1.10
intro.object 1.8
intro.refs 1.2
intro.scope 1.1
intro.structure 1.5
intseq 20.5
intseq.general 20.5.1
intseq.intseq 20.5.2
intseq.make 20.5.3
invalid.argument 19.2.3
ios 27.5.5
ios.base 27.5.3
ios.base.callback 27.5.3.6
ios.base.cons 27.5.3.7
ios.base.locales 27.5.3.3
ios.base.storage 27.5.3.5
ios.members.static 27.5.3.4
ios.overview 27.5.5.1
ios.types 27.5.3.1
ios::failure 27.5.3.1.1
ios::fmtflags 27.5.3.1.2
ios::Init 27.5.3.1.6
ios::iostate 27.5.3.1.3
ios::openmode 27.5.3.1.4
ios::seekdir 27.5.3.1.5
iostate.flags 27.5.5.4
iostream.assign 27.7.2.5.3
iostream.cons 27.7.2.5.1
iostream.dest 27.7.2.5.2
iostream.format 27.7
iostream.format.overview 27.7.1
iostream.forward 27.3
iostream.limits.imbue 27.2.1
iostream.objects 27.4
iostream.objects.overview 27.4.1
iostreamclass 27.7.2.5
iostreams.base 27.5
iostreams.base.overview 27.5.1
iostreams.limits.pos 27.2.2
iostreams.requirements 27.2
iostreams.threadsafety 27.2.3
is.heap 25.4.6.5
is.sorted 25.4.1.5
istream 27.7.2.1
istream.assign 27.7.2.1.2
istream.cons 27.7.2.1.1
istream.formatted 27.7.2.2
istream.formatted.arithmetic 27.7.2.2.2
istream.formatted.reqmts 27.7.2.2.1
istream.iterator 24.6.1
istream.iterator.cons 24.6.1.1
istream.iterator.ops 24.6.1.2
istream.manip 27.7.2.4
istream.rvalue 27.7.2.6
istream.unformatted 27.7.2.3
istream::extractors 27.7.2.2.3
istream::sentry 27.7.2.1.3
istreambuf.iterator 24.6.3
istreambuf.iterator.cons 24.6.3.2
istreambuf.iterator::equal 24.6.3.5
istreambuf.iterator::op!= 24.6.3.7
istreambuf.iterator::op* 24.6.3.3
istreambuf.iterator::op++ 24.6.3.4
istreambuf.iterator::op== 24.6.3.6
Cross references 1276
c
ISO/IEC N????
istreambuf.iterator::proxy 24.6.3.1
istringstream 27.8.3
istringstream.assign 27.8.3.2
istringstream.cons 27.8.3.1
istringstream.members 27.8.3.3
iterator.basic 24.4.2
iterator.iterators 24.2.2
iterator.operations 24.4.4
iterator.primitives 24.4
iterator.range 24.7
iterator.requirements 24.2
iterator.requirements.general 24.2.1
iterator.synopsis 24.3
iterator.traits 24.4.1
iterators 24
iterators.general 24.1
J
K
L
language.support 18
length.error 19.2.4
lex 2
lex.bool 2.14.6
lex.ccon 2.14.3
lex.charset 2.3
lex.comment 2.8
lex.digraph 2.6
lex.ext 2.14.8
lex.fcon 2.14.4
lex.header 2.9
lex.icon 2.14.2
lex.key 2.12
lex.literal 2.14
lex.literal.kinds 2.14.1
lex.name 2.11
lex.nullptr 2.14.7
lex.operators 2.13
lex.phases 2.2
lex.ppnumber 2.10
lex.pptoken 2.5
lex.separate 2.1
lex.string 2.14.5
lex.token 2.7
lex.trigraph 2.4
lib.types.movedfrom 17.6.5.15
library 17
library.c 17.2
library.general 17.1
limits 18.3.2
limits.numeric 18.3.2.1
limits.syn 18.3.2.2
list 23.3.6
list.capacity 23.3.6.3
list.cons 23.3.6.2
list.modifiers 23.3.6.4
list.ops 23.3.6.5
list.overview 23.3.6.1
list.special 23.3.6.6
locale 22.3.1
locale.categories 22.4
locale.category 22.3.1.1.1
locale.codecvt 22.4.1.4
locale.codecvt.byname 22.4.1.5
locale.codecvt.members 22.4.1.4.1
locale.codecvt.virtuals 22.4.1.4.2
locale.collate 22.4.4.1
locale.collate.byname 22.4.4.2
locale.collate.members 22.4.4.1.1
locale.collate.virtuals 22.4.4.1.2
locale.cons 22.3.1.2
locale.convenience 22.3.3
locale.ctype 22.4.1.1
locale.ctype.byname 22.4.1.2
locale.ctype.members 22.4.1.1.1
locale.ctype.virtuals 22.4.1.1.2
locale.facet 22.3.1.1.2
locale.global.templates 22.3.2
locale.id 22.3.1.1.3
locale.members 22.3.1.3
locale.messages 22.4.7.1
locale.messages.byname 22.4.7.2
locale.messages.members 22.4.7.1.1
locale.messages.virtuals 22.4.7.1.2
locale.money.get 22.4.6.1
locale.money.get.members 22.4.6.1.1
locale.money.get.virtuals 22.4.6.1.2
locale.money.put 22.4.6.2
locale.money.put.members 22.4.6.2.1
locale.money.put.virtuals 22.4.6.2.2
locale.moneypunct 22.4.6.3
locale.moneypunct.byname 22.4.6.4
locale.moneypunct.members 22.4.6.3.1
locale.moneypunct.virtuals 22.4.6.3.2
locale.nm.put 22.4.2.2
locale.num.get 22.4.2.1
locale.numpunct 22.4.3.1
locale.numpunct.byname 22.4.3.2
locale.operators 22.3.1.4
locale.statics 22.3.1.5
locale.stdcvt 22.5
locale.syn 22.2
Cross references 1277
c
ISO/IEC N????
locale.time.get 22.4.5.1
locale.time.get.byname 22.4.5.2
locale.time.get.members 22.4.5.1.1
locale.time.get.virtuals 22.4.5.1.2
locale.time.put 22.4.5.3
locale.time.put.byname 22.4.5.4
locale.time.put.members 22.4.5.3.1
locale.time.put.virtuals 22.4.5.3.2
locale.types 22.3.1.1
locales 22.3
localization 22
localization.general 22.1
logic.error 19.2.1
logical.operations 20.10.6
lower.bound 25.4.3.1
M
macro.names 17.6.4.3.1
make.heap 25.4.6.3
map 23.4.4
map.access 23.4.4.3
map.cons 23.4.4.2
map.modifiers 23.4.4.4
map.ops 23.4.4.5
map.overview 23.4.4.1
map.special 23.4.4.6
mask.array.assign 26.6.8.2
mask.array.comp.assign 26.6.8.3
mask.array.fill 26.6.8.4
member.functions 17.6.5.5
memory 20.8
memory.general 20.8.1
memory.syn 20.8.2
meta 20.11
meta.help 20.11.3
meta.rel 20.11.6
meta.rqmts 20.11.1
meta.trans 20.11.7
meta.trans.arr 20.11.7.4
meta.trans.cv 20.11.7.1
meta.trans.other 20.11.7.6
meta.trans.ptr 20.11.7.5
meta.trans.ref 20.11.7.2
meta.trans.sign 20.11.7.3
meta.type.synop 20.11.2
meta.unary 20.11.4
meta.unary.cat 20.11.4.1
meta.unary.comp 20.11.4.2
meta.unary.prop 20.11.4.3
meta.unary.prop.query 20.11.5
mismatch 25.2.10
move.iter.nonmember 24.5.3.3.14
move.iter.op.+ 24.5.3.3.8
move.iter.op.+= 24.5.3.3.9
move.iter.op.- 24.5.3.3.10
move.iter.op.-= 24.5.3.3.11
move.iter.op.comp 24.5.3.3.13
move.iter.op.const 24.5.3.3.1
move.iter.op.conv 24.5.3.3.3
move.iter.op.decr 24.5.3.3.7
move.iter.op.incr 24.5.3.3.6
move.iter.op.index 24.5.3.3.12
move.iter.op.ref 24.5.3.3.5
move.iter.op.star 24.5.3.3.4
move.iter.op= 24.5.3.3.2
move.iter.ops 24.5.3.3
move.iter.requirements 24.5.3.2
move.iterator 24.5.3.1
move.iterators 24.5.3
multibyte.strings 17.5.2.1.4.2
multimap 23.4.5
multimap.cons 23.4.5.2
multimap.modifiers 23.4.5.3
multimap.ops 23.4.5.4
multimap.overview 23.4.5.1
multimap.special 23.4.5.5
multiset 23.4.7
multiset.cons 23.4.7.2
multiset.overview 23.4.7.1
multiset.special 23.4.7.3
N
namespace.alias 7.3.2
namespace.constraints 17.6.4.2
namespace.def 7.3.1
namespace.memdef 7.3.1.2
namespace.posix 17.6.4.2.2
namespace.qual 3.4.3.2
namespace.std 17.6.4.2.1
namespace.udecl 7.3.3
namespace.udir 7.3.4
namespace.unnamed 7.3.1.1
narrow.stream.objects 27.4.2
negators 20.10.8
new.badlength 18.6.2.3
new.delete 18.6.1
new.delete.array 18.6.1.2
new.delete.dataraces 18.6.1.4
new.delete.placement 18.6.1.3
new.delete.single 18.6.1.1
new.handler 18.6.2.4
nullablepointer.requirements 17.6.3.3
Cross references 1278
c
ISO/IEC N????
numarray 26.6
numeric.iota 26.7.6
numeric.limits 18.3.2.3
numeric.limits.members 18.3.2.4
numeric.ops 26.7
numeric.ops.overview 26.7.1
numeric.requirements 26.2
numeric.special 18.3.2.7
numerics 26
numerics.general 26.1
O
objects.within.classes 17.5.2.3
ofstream 27.9.1.10
ofstream.assign 27.9.1.12
ofstream.cons 27.9.1.11
ofstream.members 27.9.1.13
operators 20.2.1
optional 20.6
optional.bad_optional_access 20.6.7
optional.comp_with_t 20.6.10
optional.defs 20.6.3
optional.general 20.6.1
optional.hash 20.6.12
optional.inplace 20.6.5
optional.nullops 20.6.9
optional.nullopt 20.6.6
optional.object 20.6.4
optional.object.assign 20.6.4.3
optional.object.ctor 20.6.4.1
optional.object.dtor 20.6.4.2
optional.object.observe 20.6.4.5
optional.object.swap 20.6.4.4
optional.relops 20.6.8
optional.specalg 20.6.11
optional.syn 20.6.2
organization 17.6.1
ostream 27.7.3.1
ostream.assign 27.7.3.3
ostream.cons 27.7.3.2
ostream.formatted 27.7.3.6
ostream.formatted.reqmts 27.7.3.6.1
ostream.inserters 27.7.3.6.3
ostream.inserters.arithmetic 27.7.3.6.2
ostream.inserters.character 27.7.3.6.4
ostream.iterator 24.6.2
ostream.iterator.cons.des 24.6.2.1
ostream.iterator.ops 24.6.2.2
ostream.manip 27.7.3.8
ostream.rvalue 27.7.3.9
ostream.seeks 27.7.3.5
ostream.unformatted 27.7.3.7
ostream::sentry 27.7.3.4
ostreambuf.iter.cons 24.6.4.1
ostreambuf.iter.ops 24.6.4.2
ostreambuf.iterator 24.6.4
ostringstream 27.8.4
ostringstream.assign 27.8.4.2
ostringstream.cons 27.8.4.1
ostringstream.members 27.8.4.3
out.of.range 19.2.5
output.iterators 24.2.4
output.streams 27.7.3
over 13
over.ass 13.5.3
over.best.ics 13.3.3.1
over.binary 13.5.2
over.built 13.6
over.call 13.5.4
over.call.func 13.3.1.1.1
over.call.object 13.3.1.1.2
over.dcl 13.2
over.ics.ellipsis 13.3.3.1.3
over.ics.list 13.3.3.1.5
over.ics.rank 13.3.3.2
over.ics.ref 13.3.3.1.4
over.ics.scs 13.3.3.1.1
over.ics.user 13.3.3.1.2
over.inc 13.5.7
over.literal 13.5.8
over.load 13.1
over.match 13.3
over.match.best 13.3.3
over.match.call 13.3.1.1
over.match.conv 13.3.1.5
over.match.copy 13.3.1.4
over.match.ctor 13.3.1.3
over.match.funcs 13.3.1
over.match.list 13.3.1.7
over.match.oper 13.3.1.2
over.match.ref 13.3.1.6
over.match.viable 13.3.2
over.oper 13.5
over.over 13.4
over.ref 13.5.6
over.sub 13.5.5
over.unary 13.5.1
overflow.error 19.2.8
P
pair.astuple 20.3.4
pair.piecewise 20.3.5
Cross references 1279
c
ISO/IEC N????
pairs 20.3
pairs.general 20.3.1
pairs.pair 20.3.2
pairs.spec 20.3.3
partial.sort 25.4.1.3
partial.sort.copy 25.4.1.4
partial.sum 26.7.4
pointer.traits 20.8.3
pointer.traits.functions 20.8.3.2
pointer.traits.types 20.8.3.1
pop.heap 25.4.6.2
predef.iterators 24.5
priority.queue 23.6.4
priqueue.cons 23.6.4.1
priqueue.cons.alloc 23.6.4.2
priqueue.members 23.6.4.3
priqueue.special 23.6.4.4
propagation 18.8.5
protection.within.classes 17.6.5.10
ptr.align 20.8.5
push.heap 25.4.6.1
Q
queue 23.6.3
queue.cons 23.6.3.2
queue.cons.alloc 23.6.3.3
queue.defn 23.6.3.1
queue.ops 23.6.3.4
queue.special 23.6.3.5
queue.syn 23.6.2
quoted.manip 27.7.6
R
rand 26.5
rand.adapt 26.5.4
rand.adapt.disc 26.5.4.2
rand.adapt.general 26.5.4.1
rand.adapt.ibits 26.5.4.3
rand.adapt.shuf 26.5.4.4
rand.device 26.5.6
rand.dist 26.5.8
rand.dist.bern 26.5.8.3
rand.dist.bern.bernoulli 26.5.8.3.1
rand.dist.bern.bin 26.5.8.3.2
rand.dist.bern.geo 26.5.8.3.3
rand.dist.bern.negbin 26.5.8.3.4
rand.dist.general 26.5.8.1
rand.dist.norm 26.5.8.5
rand.dist.norm.cauchy 26.5.8.5.4
rand.dist.norm.chisq 26.5.8.5.3
rand.dist.norm.f 26.5.8.5.5
rand.dist.norm.lognormal 26.5.8.5.2
rand.dist.norm.normal 26.5.8.5.1
rand.dist.norm.t 26.5.8.5.6
rand.dist.pois 26.5.8.4
rand.dist.pois.exp 26.5.8.4.2
rand.dist.pois.extreme 26.5.8.4.5
rand.dist.pois.gamma 26.5.8.4.3
rand.dist.pois.poisson 26.5.8.4.1
rand.dist.pois.weibull 26.5.8.4.4
rand.dist.samp 26.5.8.6
rand.dist.samp.discrete 26.5.8.6.1
rand.dist.samp.pconst 26.5.8.6.2
rand.dist.samp.plinear 26.5.8.6.3
rand.dist.uni 26.5.8.2
rand.dist.uni.int 26.5.8.2.1
rand.dist.uni.real 26.5.8.2.2
rand.eng 26.5.3
rand.eng.lcong 26.5.3.1
rand.eng.mers 26.5.3.2
rand.eng.sub 26.5.3.3
rand.predef 26.5.5
rand.req 26.5.1
rand.req.adapt 26.5.1.5
rand.req.dist 26.5.1.6
rand.req.eng 26.5.1.4
rand.req.genl 26.5.1.1
rand.req.seedseq 26.5.1.2
rand.req.urng 26.5.1.3
rand.synopsis 26.5.2
rand.util 26.5.7
rand.util.canonical 26.5.7.2
rand.util.seedseq 26.5.7.1
random.access.iterators 24.2.7
range.error 19.2.7
ratio 20.12
ratio.arithmetic 20.12.4
ratio.comparison 20.12.5
ratio.general 20.12.1
ratio.ratio 20.12.3
ratio.si 20.12.6
ratio.syn 20.12.2
re 28
re.alg 28.11
re.alg.match 28.11.2
re.alg.replace 28.11.4
re.alg.search 28.11.3
re.badexp 28.6
re.const 28.5
re.def 28.2
re.err 28.5.3
re.except 28.11.1
Cross references 1280
c
ISO/IEC N????
re.general 28.1
re.grammar 28.13
re.iter 28.12
re.matchflag 28.5.2
re.regex 28.8
re.regex.assign 28.8.3
re.regex.const 28.8.1
re.regex.construct 28.8.2
re.regex.locale 28.8.5
re.regex.nmswap 28.8.7.1
re.regex.nonmemb 28.8.7
re.regex.operations 28.8.4
re.regex.swap 28.8.6
re.regiter 28.12.1
re.regiter.cnstr 28.12.1.1
re.regiter.comp 28.12.1.2
re.regiter.deref 28.12.1.3
re.regiter.incr 28.12.1.4
re.req 28.3
re.results 28.10
re.results.acc 28.10.4
re.results.all 28.10.6
re.results.const 28.10.1
re.results.form 28.10.5
re.results.nonmember 28.10.8
re.results.size 28.10.3
re.results.state 28.10.2
re.results.swap 28.10.7
re.submatch 28.9
re.submatch.members 28.9.1
re.submatch.op 28.9.2
re.syn 28.4
re.synopt 28.5.1
re.tokiter 28.12.2
re.tokiter.cnstr 28.12.2.1
re.tokiter.comp 28.12.2.2
re.tokiter.deref 28.12.2.3
re.tokiter.incr 28.12.2.4
re.traits 28.7
reentrancy 17.6.5.8
refwrap 20.10.3
refwrap.access 20.10.3.3
refwrap.assign 20.10.3.2
refwrap.const 20.10.3.1
refwrap.helpers 20.10.3.5
refwrap.invoke 20.10.3.4
replacement.functions 17.6.4.6
requirements 17.6
res.on.arguments 17.6.4.9
res.on.data.races 17.6.5.9
res.on.exception.handling 17.6.5.12
res.on.functions 17.6.4.8
res.on.headers 17.6.5.2
res.on.macro.definitions 17.6.5.3
res.on.objects 17.6.4.10
res.on.pointer.storage 17.6.5.13
res.on.required 17.6.4.11
reserved.names 17.6.4.3
reverse.iter.cons 24.5.1.3.1
reverse.iter.conv 24.5.1.3.3
reverse.iter.op!= 24.5.1.3.15
reverse.iter.op+ 24.5.1.3.8
reverse.iter.op++ 24.5.1.3.6
reverse.iter.op+= 24.5.1.3.9
reverse.iter.op- 24.5.1.3.10
reverse.iter.op-= 24.5.1.3.11
reverse.iter.op.star 24.5.1.3.4
reverse.iter.op< 24.5.1.3.14
reverse.iter.op<= 24.5.1.3.18
reverse.iter.op= 24.5.1.3.2
reverse.iter.op== 24.5.1.3.13
reverse.iter.op> 24.5.1.3.16
reverse.iter.op>= 24.5.1.3.17
reverse.iter.opdiff 24.5.1.3.19
reverse.iter.opindex 24.5.1.3.12
reverse.iter.opref 24.5.1.3.5
reverse.iter.ops 24.5.1.3
reverse.iter.opsum 24.5.1.3.20
reverse.iter.op-- 24.5.1.3.7
reverse.iter.requirements 24.5.1.2
reverse.iterator 24.5.1.1
reverse.iterators 24.5.1
round.style 18.3.2.5
runtime.error 19.2.6
S
scoped.adaptor.operators 20.14.5
sequence.reqmts 23.2.3
sequences 23.3
sequences.general 23.3.1
set 23.4.6
set.cons 23.4.6.2
set.difference 25.4.5.4
set.intersection 25.4.5.3
set.new.handler 18.6.2.5
set.overview 23.4.6.1
set.special 23.4.6.3
set.symmetric.difference 25.4.5.5
set.terminate 18.8.3.2
set.unexpected D.11.2
set.union 25.4.5.2
slice.access 26.6.4.3
Cross references 1281
c
ISO/IEC N????
slice.arr.assign 26.6.5.2
slice.arr.comp.assign 26.6.5.3
slice.arr.fill 26.6.5.4
smartptr 20.9
sort 25.4.1.1
sort.heap 25.4.6.4
special 12
specialized.addressof 20.8.12.1
specialized.algorithms 20.8.12
stable.sort 25.4.1.2
stack 23.6.5
stack.cons 23.6.5.3
stack.cons.alloc 23.6.5.4
stack.defn 23.6.5.2
stack.ops 23.6.5.5
stack.special 23.6.5.6
stack.syn 23.6.5.1
std.exceptions 19.2
std.ios.manip 27.5.6
std.iterator.tags 24.4.3
std.manip 27.7.4
stmt.ambig 6.8
stmt.block 6.3
stmt.break 6.6.1
stmt.cont 6.6.2
stmt.dcl 6.7
stmt.do 6.5.2
stmt.expr 6.2
stmt.for 6.5.3
stmt.goto 6.6.4
stmt.if 6.4.1
stmt.iter 6.5
stmt.jump 6.6
stmt.label 6.1
stmt.ranged 6.5.4
stmt.return 6.6.3
stmt.select 6.4
stmt.stmt 6
stmt.switch 6.4.2
stmt.while 6.5.1
storage.iterator 20.8.10
stream.buffers 27.6
stream.buffers.overview 27.6.1
stream.iterators 24.6
stream.types 27.5.2
streambuf 27.6.3
streambuf.assign 27.6.3.3.1
streambuf.buffer 27.6.3.2.2
streambuf.cons 27.6.3.1
streambuf.get.area 27.6.3.3.2
streambuf.locales 27.6.3.2.1
streambuf.members 27.6.3.2
streambuf.protected 27.6.3.3
streambuf.pub.get 27.6.3.2.3
streambuf.pub.pback 27.6.3.2.4
streambuf.pub.put 27.6.3.2.5
streambuf.put.area 27.6.3.3.3
streambuf.reqts 27.6.2
streambuf.virt.buffer 27.6.3.4.2
streambuf.virt.get 27.6.3.4.3
streambuf.virt.locales 27.6.3.4.1
streambuf.virt.pback 27.6.3.4.4
streambuf.virt.put 27.6.3.4.5
streambuf.virtuals 27.6.3.4
string.access 21.4.5
string.accessors 21.4.7.1
string.capacity 21.4.4
string.classes 21.3
string.cons 21.4.2
string.conversions 21.5
string.io 21.4.8.9
string.iterators 21.4.3
string.modifiers 21.4.6
string.nonmembers 21.4.8
string.ops 21.4.7
string.require 21.4.1
string.special 21.4.8.8
string.streams 27.8
string.streams.overview 27.8.1
string::append 21.4.6.2
string::assign 21.4.6.3
string::compare 21.4.7.9
string::copy 21.4.6.7
string::erase 21.4.6.5
string::find 21.4.7.2
string::find.first.not.of 21.4.7.6
string::find.first.of 21.4.7.4
string::find.last.not.of 21.4.7.7
string::find.last.of 21.4.7.5
string::insert 21.4.6.4
string::op!= 21.4.8.3
string::op+ 21.4.8.1
string::op+= 21.4.6.1
string::op< 21.4.8.4
string::op<= 21.4.8.6
string::op> 21.4.8.5
string::op>= 21.4.8.7
string::operator== 21.4.8.2
string::replace 21.4.6.6
string::rfind 21.4.7.3
string::substr 21.4.7.8
string::swap 21.4.6.8
Cross references 1282
c
ISO/IEC N????
stringbuf 27.8.2
stringbuf.assign 27.8.2.2
stringbuf.cons 27.8.2.1
stringbuf.members 27.8.2.3
stringbuf.virtuals 27.8.2.4
strings 21
strings.general 21.1
stringstream 27.8.5
stringstream.assign 27.8.6.1
stringstream.cons 27.8.6
stringstream.members 27.8.7
structure 17.5.1
structure.elements 17.5.1.1
structure.requirements 17.5.1.3
structure.see.also 17.5.1.5
structure.specifications 17.5.1.4
structure.summary 17.5.1.2
support.dynamic 18.6
support.exception 18.8
support.general 18.1
support.initlist 18.9
support.initlist.access 18.9.2
support.initlist.cons 18.9.1
support.initlist.range 18.9.3
support.limits 18.3
support.limits.general 18.3.1
support.rtti 18.7
support.runtime 18.10
support.start.term 18.5
support.types 18.2
swappable.requirements 17.6.3.2
syntax 1.6
syserr 19.5
syserr.compare 19.5.4
syserr.errcat 19.5.1
syserr.errcat.derived 19.5.1.4
syserr.errcat.nonvirtuals 19.5.1.3
syserr.errcat.objects 19.5.1.5
syserr.errcat.overview 19.5.1.1
syserr.errcat.virtuals 19.5.1.2
syserr.errcode 19.5.2
syserr.errcode.constructors 19.5.2.2
syserr.errcode.modifiers 19.5.2.3
syserr.errcode.nonmembers 19.5.2.5
syserr.errcode.observers 19.5.2.4
syserr.errcode.overview 19.5.2.1
syserr.errcondition 19.5.3
syserr.errcondition.constructors 19.5.3.2
syserr.errcondition.modifiers 19.5.3.3
syserr.errcondition.nonmembers 19.5.3.5
syserr.errcondition.observers 19.5.3.4
syserr.errcondition.overview 19.5.3.1
syserr.hash 19.5.5
syserr.syserr 19.5.6
syserr.syserr.members 19.5.6.2
syserr.syserr.overview 19.5.6.1
T
temp 14
temp.alias 14.5.7
temp.arg 14.3
temp.arg.explicit 14.8.1
temp.arg.nontype 14.3.2
temp.arg.template 14.3.3
temp.arg.type 14.3.1
temp.class 14.5.1
temp.class.order 14.5.5.2
temp.class.spec 14.5.5
temp.class.spec.match 14.5.5.1
temp.class.spec.mfunc 14.5.5.3
temp.decls 14.5
temp.deduct 14.8.2
temp.deduct.call 14.8.2.1
temp.deduct.conv 14.8.2.3
temp.deduct.decl 14.8.2.6
temp.deduct.funcaddr 14.8.2.2
temp.deduct.partial 14.8.2.4
temp.deduct.type 14.8.2.5
temp.dep 14.6.2
temp.dep.candidate 14.6.4.2
temp.dep.constexpr 14.6.2.3
temp.dep.expr 14.6.2.2
temp.dep.res 14.6.4
temp.dep.temp 14.6.2.4
temp.dep.type 14.6.2.1
temp.expl.spec 14.7.3
temp.explicit 14.7.2
temp.fct 14.5.6
temp.fct.spec 14.8
temp.friend 14.5.4
temp.func.order 14.5.6.2
temp.inject 14.6.5
temp.inst 14.7.1
temp.local 14.6.1
temp.mem 14.5.2
temp.mem.class 14.5.1.2
temp.mem.enum 14.5.1.4
temp.mem.func 14.5.1.1
temp.names 14.2
temp.nondep 14.6.3
temp.over 14.8.3
temp.over.link 14.5.6.1
Cross references 1283
c
ISO/IEC N????
temp.param 14.1
temp.point 14.6.4.1
temp.res 14.6
temp.spec 14.7
temp.static 14.5.1.3
temp.type 14.4
temp.variadic 14.5.3
template.bitset 20.7
template.gslice.array 26.6.7
template.gslice.array.overview 26.6.7.1
template.indirect.array 26.6.9
template.indirect.array.overview 26.6.9.1
template.mask.array 26.6.8
template.mask.array.overview 26.6.8.1
template.slice.array 26.6.5
template.slice.array.overview 26.6.5.1
template.valarray 26.6.2
template.valarray.overview 26.6.2.1
temporary.buffer 20.8.11
terminate 18.8.3.4
terminate.handler 18.8.3.1
thread 30
thread.condition 30.5
thread.condition.condvar 30.5.1
thread.condition.condvarany 30.5.2
thread.decaycopy 30.2.6
thread.general 30.1
thread.lock 30.4.2
thread.lock.algorithm 30.4.3
thread.lock.guard 30.4.2.1
thread.lock.shared 30.4.2.3
thread.lock.shared.cons 30.4.2.3.1
thread.lock.shared.locking 30.4.2.3.2
thread.lock.shared.mod 30.4.2.3.3
thread.lock.shared.obs 30.4.2.3.4
thread.lock.unique 30.4.2.2
thread.lock.unique.cons 30.4.2.2.1
thread.lock.unique.locking 30.4.2.2.2
thread.lock.unique.mod 30.4.2.2.3
thread.lock.unique.obs 30.4.2.2.4
thread.mutex 30.4
thread.mutex.class 30.4.1.2.1
thread.mutex.recursive 30.4.1.2.2
thread.mutex.requirements 30.4.1
thread.mutex.requirements.general 30.4.1.1
thread.mutex.requirements.mutex 30.4.1.2
thread.once 30.4.4
thread.once.callonce 30.4.4.2
thread.once.onceflag 30.4.4.1
thread.req 30.2
thread.req.exception 30.2.2
thread.req.lockable 30.2.5
thread.req.lockable.basic 30.2.5.2
thread.req.lockable.general 30.2.5.1
thread.req.lockable.req 30.2.5.3
thread.req.lockable.timed 30.2.5.4
thread.req.native 30.2.3
thread.req.paramname 30.2.1
thread.req.timing 30.2.4
thread.sharedmutex.class 30.4.1.4.1
thread.sharedmutex.requirements 30.4.1.4
thread.thread.algorithm 30.3.1.7
thread.thread.assign 30.3.1.4
thread.thread.class 30.3.1
thread.thread.constr 30.3.1.2
thread.thread.destr 30.3.1.3
thread.thread.id 30.3.1.1
thread.thread.member 30.3.1.5
thread.thread.static 30.3.1.6
thread.thread.this 30.3.2
thread.threads 30.3
thread.timedmutex.class 30.4.1.3.1
thread.timedmutex.recursive 30.4.1.3.2
thread.timedmutex.requirements 30.4.1.3
time 20.13
time.clock 20.13.7
time.clock.hires 20.13.7.3
time.clock.req 20.13.3
time.clock.steady 20.13.7.2
time.clock.system 20.13.7.1
time.duration 20.13.5
time.duration.arithmetic 20.13.5.3
time.duration.cast 20.13.5.7
time.duration.comparisons 20.13.5.6
time.duration.cons 20.13.5.1
time.duration.literals 20.13.5.8
time.duration.nonmember 20.13.5.5
time.duration.observer 20.13.5.2
time.duration.special 20.13.5.4
time.general 20.13.1
time.point 20.13.6
time.point.arithmetic 20.13.6.3
time.point.cast 20.13.6.7
time.point.comparisons 20.13.6.6
time.point.cons 20.13.6.1
time.point.nonmember 20.13.6.5
time.point.observer 20.13.6.2
time.point.special 20.13.6.4
time.syn 20.13.2
time.traits 20.13.4
time.traits.duration_values 20.13.4.2
time.traits.is_fp 20.13.4.1
Cross references 1284
c
ISO/IEC N????
time.traits.specializations 20.13.4.3
tuple 20.4
tuple.assign 20.4.2.2
tuple.cnstr 20.4.2.1
tuple.creation 20.4.2.4
tuple.elem 20.4.2.6
tuple.general 20.4.1
tuple.helper 20.4.2.5
tuple.rel 20.4.2.7
tuple.special 20.4.2.9
tuple.swap 20.4.2.3
tuple.traits 20.4.2.8
tuple.tuple 20.4.2
type.descriptions 17.5.2.1
type.descriptions.general 17.5.2.1.1
type.index 20.15
type.index.hash 20.15.4
type.index.members 20.15.3
type.index.overview 20.15.2
type.index.synopsis 20.15.1
type.info 18.7.1
U
uncaught 18.8.4
underflow.error 19.2.9
unexpected D.11.4
unexpected.handler D.11.1
uninitialized.copy 20.8.12.2
uninitialized.fill 20.8.12.3
uninitialized.fill.n 20.8.12.4
unique.ptr 20.9.1
unique.ptr.create 20.9.1.4
unique.ptr.dltr 20.9.1.1
unique.ptr.dltr.dflt 20.9.1.1.2
unique.ptr.dltr.dflt1 20.9.1.1.3
unique.ptr.dltr.general 20.9.1.1.1
unique.ptr.runtime 20.9.1.3
unique.ptr.runtime.ctor 20.9.1.3.1
unique.ptr.runtime.modifiers 20.9.1.3.3
unique.ptr.runtime.observers 20.9.1.3.2
unique.ptr.single 20.9.1.2
unique.ptr.single.asgn 20.9.1.2.3
unique.ptr.single.ctor 20.9.1.2.1
unique.ptr.single.dtor 20.9.1.2.2
unique.ptr.single.modifiers 20.9.1.2.5
unique.ptr.single.observers 20.9.1.2.4
unique.ptr.special 20.9.1.5
unord 23.5
unord.general 23.5.1
unord.hash 20.10.12
unord.map 23.5.4
unord.map.cnstr 23.5.4.2
unord.map.elem 23.5.4.3
unord.map.modifiers 23.5.4.4
unord.map.overview 23.5.4.1
unord.map.swap 23.5.4.5
unord.map.syn 23.5.2
unord.multimap 23.5.5
unord.multimap.cnstr 23.5.5.2
unord.multimap.modifiers 23.5.5.3
unord.multimap.overview 23.5.5.1
unord.multimap.swap 23.5.5.4
unord.multiset 23.5.7
unord.multiset.cnstr 23.5.7.2
unord.multiset.overview 23.5.7.1
unord.multiset.swap 23.5.7.3
unord.req 23.2.5
unord.req.except 23.2.5.1
unord.set 23.5.6
unord.set.cnstr 23.5.6.2
unord.set.overview 23.5.6.1
unord.set.swap 23.5.6.3
unord.set.syn 23.5.3
upper.bound 25.4.3.2
using 17.6.2
using.headers 17.6.2.2
using.linkage 17.6.2.3
using.overview 17.6.2.1
usrlit.suffix 17.6.4.3.5
util.dynamic.safety 20.8.4
util.smartptr 20.9.2
util.smartptr.enab 20.9.2.4
util.smartptr.getdeleter 20.9.2.2.10
util.smartptr.hash 20.9.2.6
util.smartptr.ownerless 20.9.2.3.7
util.smartptr.shared 20.9.2.2
util.smartptr.shared.assign 20.9.2.2.3
util.smartptr.shared.atomic 20.9.2.5
util.smartptr.shared.cast 20.9.2.2.9
util.smartptr.shared.cmp 20.9.2.2.7
util.smartptr.shared.const 20.9.2.2.1
util.smartptr.shared.create 20.9.2.2.6
util.smartptr.shared.dest 20.9.2.2.2
util.smartptr.shared.io 20.9.2.2.11
util.smartptr.shared.mod 20.9.2.2.4
util.smartptr.shared.obs 20.9.2.2.5
util.smartptr.shared.spec 20.9.2.2.8
util.smartptr.weak 20.9.2.3
util.smartptr.weak.assign 20.9.2.3.3
util.smartptr.weak.const 20.9.2.3.1
util.smartptr.weak.dest 20.9.2.3.2
util.smartptr.weak.mod 20.9.2.3.4
Cross references 1285
c
ISO/IEC N????
util.smartptr.weak.obs 20.9.2.3.5
util.smartptr.weak.spec 20.9.2.3.6
util.smartptr.weakptr 20.9.2.1
utilities 20
utilities.general 20.1
utility 20.2
utility.arg.requirements 17.6.3.1
utility.exchange 20.2.3
utility.requirements 17.6.3
utility.swap 20.2.2
V
valarray.access 26.6.2.4
valarray.assign 26.6.2.3
valarray.binary 26.6.3.1
valarray.cassign 26.6.2.7
valarray.comparison 26.6.3.2
valarray.cons 26.6.2.2
valarray.members 26.6.2.8
valarray.nonmembers 26.6.3
valarray.range 26.6.10
valarray.special 26.6.3.4
valarray.sub 26.6.2.5
valarray.syn 26.6.1
valarray.transcend 26.6.3.3
valarray.unary 26.6.2.6
value.error.codes 17.6.5.14
vector 23.3.7
vector.bool 23.3.8
vector.capacity 23.3.7.3
vector.cons 23.3.7.2
vector.data 23.3.7.4
vector.modifiers 23.3.7.5
vector.overview 23.3.7.1
vector.special 23.3.7.6
W
wide.stream.objects 27.4.3
X
xref F
Y
Z
Cross references 1286
c
ISO/IEC N????
Index
!,see operator, logical negation
!=,see inequality operator
(),see operator, function call, see declarator, func-
tion
*,see operator, indirection, see multiplication op-
erator, see declarator, pointer
+,see operator, unary plus, see addition operator
++,see operator, increment
,,see comma operator
-,see operator, unary minus, see subtraction op-
erator
->,see operator, class member access
->*,see pointer to member operator
--,see operator, decrement
.,see operator, class member access
.*,see pointer to member operator
...,see ellipsis
/,see division operator
:
field declaration, 222
label specifier, 127
::,see scope resolution operator
::*,see declarator, pointer to member
<,see less than operator
template and, 313,315
<...>,see preprocessing directive, header
<=,see less than or equal to operator
<<,see left shift operator
=,see assignment operator
==,see equality operator
>,see greater than operator
>=,see greater than or equal operator
>>,see right shift operator
?:,see conditional expression operator
[],see operator, subscripting, see declarator, ar-
ray
¨...¨,see preprocessing directives, source-file in-
clusion
#operator, 401,402
## operator, 402
#define,401
#elif,398
#else,399
#endif,399
#error,see preprocessing directives, error
#if,398,433
#ifdef,399
#ifndef,399
#include,399,419
#line,see preprocessing directives, line control
#pragma,see preprocessing directives, pragma
#undef,403,429
%,see remainder operator
&,see operator, address-of, see bitwise AND oper-
ator, see declarator, reference
&&,see logical AND operator
ˆ,see bitwise exclusive OR operator
_ _ DATE _ _,406
_ _ FILE _ _,406
_ _ LINE _ _,406
_ _ STDC _ _,406
implementation-defined, 406
_ _ STDCPP_STRICT_POINTER_SAFETY _ _,407
implementation-defined, 407
_ _ STDCPP_THREADS _ _,407
implementation-defined, 407
_ _ STDC_HOSTED _ _,406
implementation-defined, 406
_ _ STDC_ISO_10646 _ _,407
implementation-defined, 407
_ _ STDC_MB_MIGHT_NEQ_WC _ _,406
implementation-defined, 406
_ _ STDC_VERSION _ _,407
implementation-defined, 407
_ _ TIME _ _,406
_ _ VA_ARGS _ _,401
_ _cplusplus,406
\,see backslash
{}
block statement, 127
class declaration, 210
class definition, 210
enum declaration, 154
initializer list, 199
~,see destructor
_,see character, underscore
|,see bitwise inclusive OR operator
||,see logical OR operator
~,see operator, one’s complement
0,see also zero, null
Cross references 1287
c
ISO/IEC N????
null character, 29
string terminator, 29
abort,62,132
abstract-declarator,178,1221
abstract-pack-declarator,178,1221
access control, 237247
base class, 239
base class member, 225
class member, 99
default, 237
default argument, 238
friend function, 242
member name, 237
multiple access, 246
nested class, 246
overloading and, 282
private,237
protected,237,245
public,237
union default member, 211
using-declaration and, 166
virtual function, 246
access-specifier,225,1223
access control
anonymous union,221
member function and, 248
overloading resolution and, 229
access specifier, 238,239
addition operator, 117
additive-expression,117,1214
address, 73,119
address of member function
unspecified, 433
aggregate, 199
aggregate initialization, 199
algorithm
stable, 411,433
alias
namespace, 161
alias template, 339
alias-declaration,136,1216
alignment
extended, 76
fundamental, 76
alignment-specifier,173,1219
alignment requirement
implementation-defined, 76
allocation
alignment storage, 111
implementation defined bit-field, 222
unspecified, 215
allocation functions, 63
allowing an exception, see exception handling, al-
lowing an exception
alternative token, see token, alternative
ambiguity
base class member, 228
class conversion, 230
declaration type, 138
declaration versus cast, 179
declaration versus expression, 134
function declaration, 197
member access, 228
overloaded function, 282
parentheses and, 110
Amendment 1, 430
and-expression,120,1214
appertain, 173
argc,59
argument, 2,432,433,468
access checking and default, 238
binding of default, 190
evaluation of default, 190,191
example of default, 189,190
function call expression, 2
function-like macro, 2
overloaded operator and default, 303
reference, 97
scope of default, 191
template, 316
template instantiation, 2
throw expression, 2
type checking of default, 190
arguments
implementation-defined order of evaluation of
function, 191
argument and name hiding
default, 191
argument and virtual function
default, 192
argument list
empty, 186
variable, 187
argument passing, 97
reference and, 202
argument substitution, see macro, argument sub-
stitution
argument type
unknown, 187
argv,59
arithmetic
Cross references 1288
c
ISO/IEC N????
pointer, 117
unsigned,71
array, 187
const,74
delete,113
multidimensional, 186
new,110
overloading and pointer versus, 280
sizeof,109
storage of, 186
array
as aggregate, 762
contiguous storage, 762
initialization, 762,764
tuple interface to, 765
zero sized, 765
array of runtime bound, 184
array size
default, 185
arrow operator, see operator, class member access
as-if rule, 8
asm
implementation-defined, 170
asm-definition,170,1219
assembler, 170
<assert.h>,419
assignment
and lvalue, 122
conversion by, 122
copy, see assignment operator, copy
move, see assignment operator, move, 410
reference, 202
assignment operator
copy, 248,271274
hidden, 273
implicitly declared, 271
implicitly defined, 273
inaccessible, 274
trivial, 273
virtual bases and, 274
move, 248,271274
hidden, 273
implicitly declared, 272
implicitly defined, 273
inaccessible, 274
trivial, 273
virtual bases and, 274
overloaded, 303
assignment-expression,122,1215
assignment-operator,122,1215
associative containers
exception safety, 750
requirements, 750
unordered, see unordered associative contain-
ers
asynchronous provider, 1192
asynchronous return object, 1192
atexit,61
atomic operations, see operation, atomic
attribute, 173176
alignment, 174
carries dependency, 175
noreturn, 175
syntax and semantics, 173
attribute,173,1219
attribute-argument-clause,173,1220
attribute-declaration,136,1217
attribute-list,173,1219
attribute-namespace,173,1220
attribute-scoped-token,173,1220
attribute-specifier,173,1219
attribute-specifier-seq,173,1219
attribute-token,173,1220
automatic storage duration, 63
awk,1098
backslash character, 26
bad_alloc,112
bad_cast,101
bad_exception,395
bad_typeid,102
bad_typeid::what
implementation-defined, 457
balanced-token,173,1220
balanced-token-seq,173,1220
base class
overloading and, 281
base class subobject, 7
base-clause,225,1222
base-specifier,225,1223
base-specifier-list,225,1222
base-type-specifier,225,1223
BaseCharacteristic, 585
base class, 225,226
direct, 225
indirect, 225
private,239
protected,239
public,239
base class virtual, see virtual base class
basic_ios::failure argument
implementation-defined, 1018
Cross references 1289
c
ISO/IEC N????
begin
unordered associative containers, 758
behavior
conditionally-supported, 2,5
default, 410,414
implementation-defined, 3,8
locale-specific, 3
observable, 8,9
on receipt of signal, 8
required, 411,414
undefined, 4,5,8
unspecified, 4,8
Ben, 282
Bernoulli distributions, 950953
bernoulli_distribution
discrete probability function, 950
binary function, 567
binary operator
overloaded, 303
binary-digit,24,1209
binary-literal,23,1209
BinaryTypeTrait, 585
binary operator
interpretation of, 303
bind directly, 204
binding
reference, 202
binomial_distribution
discrete probability function, 951
bit-field, 222
address of, 222
alignment of, 222
implementation-defined sign of, 1236
implementation defined alignment of, 222
type of, 222
unnamed, 222
zero width of, 222
block, 409
initialization in, 133
block scope, 39
block statement, see statement, compound
block-declaration,136,1216
block structure, 133
body
function, 192
Boolean, 222
Boolean literal, 29
boolean literal, see literal, boolean
boolean-literal,29,1211
Boolean type, 72
bound arguments, 578
brace-or-equal-initializer,196,1221
braced-init-list,196,1222
bucket
unordered associative containers, 758
bucket_count
unordered associative containers, 757
bucket_size
unordered associative containers, 758
buckets, 750
byte, 6,108
C
linkage to, 170
standard, 1
standard library, 1
Unicode TR, 1
c-char,25,1210
c-char-sequence,25,1210
call
operator function, 302
pseudo destructor, 99
call signature, 566
call wrapper, 566,567
forwarding, 567
simple, 567
type, 566
Callable, 581
callable object, 566,581
callable type, 566
capture,89,1212
capture-default,89,1212
capture-list,89,1212
captured, 93
by copy, 94
by reference, 94
carries a dependency, 12
carry
subtract_with_carry_engine,938
<cassert>,419
cast
base class, 104
const, 105,115
derived class, 104
dynamic, 100,456
construction and, 267
destruction and, 267
integer to pointer, 104
lvalue, 102,104
pointer-to-function, 105
pointer-to-member, 104,105
pointer to integer, 104
Cross references 1290
c
ISO/IEC N????
reference, 102,105
reinterpret, 104,115
integer to pointer, 104
lvalue, 104
pointer to integer, 104
pointer-to-function, 105
pointer-to-member, 105
reference, 105
static, 102,115
lvalue, 102
reference, 102
undefined pointer-to-function, 105
cast-expression,115,1214
casting, 98
catch,386
cauchy_distribution
probability density function, 960
cbegin
unordered associative containers, 758
cend
unordered associative containers, 758
<cerrno>,429
char
implementation-defined sign of, 71
char-like object, 631
char-like type, 631
char16_t,25
char16_t character, 25
char32_t,25
char32_t character, 25
char_class_type
regular expression traits, 1089
character, 409
decimal-point, 416
multibyte, 3
signed,71
source file, 16
underscore, 429
in identifier, 22
character literal, see literal, character
character set, 1718
basic execution, 6
basic source, 16,17
character string literal, 402
character-literal,25,1209
character string, 28
checking
point of error, 341
syntax, 341
chi_squared_distribution
probability density function, 960
class, 72,210224
abstract, 235
base, 430,434
cast to incomplete, 115
constructor and abstract, 236
definition, 34
derived, 434
linkage of, 56
linkage specification, 171
member function, see member function, class
pointer to abstract, 236
polymorphic, 231
scope of enumerator, 157
standard-layout, 211
trivial, 211
unnamed, 142
class-head,210,1222
class-head-name,210,1222
class-key,210,1222
class-name,210,1222
class-or-decltype,225,1223
class-specifier,210,1222
class-virt-specifier,210,1222
class local, see local class
class name
elaborated, 151,213
point of declaration, 213
scope of, 212
typedef,142,214
class nested, see nested class
class object
assignment to, 122
member, 215
sizeof,109
class object copy, see copy constructor
class object initialization, see constructor
clear
unordered associative containers, 757
<clocale>,416
closure object, 89
closure type, 89
collating element, 1088
comment, 1920
/* */,20
//,20
comparison
pointer, 119
pointer to function, 119
undefined pointer, 117
compatible, see exception specification, compati-
ble
Cross references 1291
c
ISO/IEC N????
compilation
separate, 16
compiler control line, see preprocessing directives
complete object, 7
complete object of, 7
completely defined, 214
component, 409
compound-statement,127,1215
concatenation
macro argument, see ##
string, 29
condition,128,1215
conditions
rules for, 128
conditional-expression
throw-expression in, 121
conditional-expression,121,1215
conditionally-supported behavior
seebehavior, conditionally-supported, 1
conflict, 11
conformance requirements, 5,8
class templates, 5
classes, 5
general, 5
library, 5
method of description, 5
consistency
linkage, 139
linkage specification, 171
type declaration, 58
const,73
constructor and, 219,249
destructor and, 219,256
linkage of, 56
overloading and, 281
const_cast,see cast, const
const_local_iterator,752
unordered associative containers, 752
constant, 23,86
enumeration, 155
null pointer, 81
constant iterator, 839
constant-expression,124,1215
constexpr function, 143
construction, 265268
dynamic cast and, 267
member access, 265
move, 410
pointer to member or base, 266
typeid operator, 267
virtual function call, 266
constructor, 248
address of, 250
array of class objects and, 260
converting, 253
copy, 248,251,268271,417
elision, 274
implicitly declared, 269
implicitly defined, 270
inaccessible, 274
trivial, 270
default, 248,249
exception handling, see exception handling,
constructors and destructors
explicit call, 250
implicitly called, 250
implicitly defined, 249
inheritance of, 249
inheriting, 275278
move, 248,268271
elision, 274
implicitly declared, 269
implicitly defined, 270
inaccessible, 274
trivial, 270
non-trivial, 249
random number distribution requirement, 931
random number engine requirement, 928
union,221
unspecified argument to, 112
constructor, conversion by, see conversion, user-
defined
constructor, default, see default constructor
const-object
undefined change to, 146
contained value, 505
context
non-deduced, 377
contextually converted to bool, see conversion, con-
textual
continue
and handler, 386
and try block, 386
control line, see preprocessing directives
control-line,397,1225
conventions, 414
lexical, 1631
conversion
argument, 186
array-to-pointer, 78
bool,80
boolean, 82
Cross references 1292
c
ISO/IEC N????
class, 252
contextual, 77
contextual to bool,77
derived-to-base, 293
floating point, 80
floating to integral, 81
function-to-pointer, 78
implementation defined pointer integer, 104
implicit, 77,252
implicit user-defined, 253
inheritance of user-defined, 255
integer rank, 82
integral, 80
integral to floating, 81
lvalue-to-rvalue, 78,1231
narrowing, 208
overload resolution and pointer, 302
overload resolution and, 291
pointer, 81
pointer to member, 81
void*,82
qualification, 7879
return type, 133
standard, 7782
static user-defined, 255
to signed, 80
to unsigned, 80
type of, 254
user-defined, 252254
usual arithmetic, 84
virtual user-defined, 255
conversion operator, see conversion, user defined
conversion rank, 294
conversion-declarator,254,1223
conversion-function-id,254,1223
conversion-type-id,254,1223
conversion explicit type, see casting
conversion function, see conversion, user-defined
copy
class object, see constructor, copy; assignment,
copy
copy constructor
random number engine requirement, 928
copy elision, see constructor, copy, elision; con-
structor, move, elision
copy-initialization, 197
CopyInsertable into X,737
count
unordered associative containers, 757
<cstdarg>,187
<cstddef>,109,117
<cstdint>,446
<cstdlib>,62,419
<cstring>,416
ctor-initializer,261,1223
<cuchar>,430
cv-qualifier, 73
cv-qualifier,178,1220
cv-qualifier-seq,178,1220
<cwchar>,430
<cwctype>,430
d-char,28,1211
d-char-sequence,27,1211
DAG
multiple inheritance, 227,228
non-virtual base class, 228
virtual base class, 227,228
data race, 14
data member, see member
deadlock, 410
deallocation, see delete
deallocation functions, 63
decay, see conversion, array to pointer; conversion,
function to pointer
DECAY_COPY, 1156
decimal-literal,23,1209
decl-specifier,137,1217
decl-specifier-seq,138,1217
declaration, 32,136176
array, 184
asm,170
bit-field, 222
class name, 33
constant pointer, 181
default argument, 189192
definition versus, 32
ellipsis in function, 97,187
enumerator point of, 38
extern,33
extern reference, 202
forward, 139
forward class, 213
function, 33,186
local class, 224
member, 214
multiple, 58
name, 32
opaque enum, 33
overloaded, 279
overloaded name and friend,243
parameter, 33,186
Cross references 1293
c
ISO/IEC N????
parentheses in, 179,181
pointer, 181
reference, 182
register,138
static member,33
storage class, 138
type, 180
typedef,33
typedef as type, 141
declaration,136,1216
declaration-seq,136,1216
declaration-statement,133,1216
declaration hiding, see name hiding
declarative region, 37
declarator, 33,137,177209
array, 184
function, 186189
meaning of, 180192
multidimensional array, 185
pointer, 181
pointer to member, 183
reference, 182
declarator,177,1220
declarator-id,178,1221
decltype-specifier,148,1218
decrement operator
overloaded, see overloading, decrement oper-
ator
default access control, see access control, default
default constructor
random number distribution requirement, 931
seed sequence requirement, 926
default-initialization, 196
default-inserted, 736
defaulted, 194
DefaultInsertable into X,736
default argument
overload resolution and, 290
default initializers
overloading and, 281
deferred function, 1202
definition, 33
alternate, 430
class, 210,214
class name as type, 212
constructor, 193
declaration as, 137
function, 192195
deleted, 194
explicitly-defaulted, 193
local class, 224
member function, 216
namespace, 158
nested class, 222
pure virtual function, 235
scope of class, 212
static member, 220
virtual function, 234
definitions, 25
delete,63,113,114,258
array, 113
destructor and, 114,257
object, 113
operator,430
overloading and, 64
type of, 259
undefined, 113
delete-expression,113,1214
deleter, 535
dependency-ordered before, 12
deprecated features, 100,108
dereferencing, see also indirection
derivation, see inheritance
derived class
most, see most derived class
derived object
most, see most derived object
derived class, 225236
destruction, 265268
dynamic cast and, 267
member access, 265
pointer to member or base, 266
typeid operator, 267
virtual function call, 266
destructor, 255,417
default, 256
exception handling, see exception handling,
constructors and destructors
explicit call, 257
implicit call, 256
implicitly defined, 256
non-trivial, 256
program termination and, 256
pure virtual, 256
union,221
virtual, 256
diagnosable rules, 5
diagnostic message, see message, diagnostic
digit,21,1208
digit-sequence,27,1210
digraph, see token, alternative, 20
direct-non-list-initialization, 410
Cross references 1294
c
ISO/IEC N????
directed acyclic graph, see DAG
directive, preprocessing, see preprocessing direc-
tives
discard
random number engine requirement, 928
discard_block_engine
generation algorithm, 940
state, 940
textual representation, 941
transition algorithm, 940
discarded-value expression, 84
discrete probability function
bernoulli_distribution,950
binomial_distribution,951
discrete_distribution,963
geometric_distribution,952
negative_binomial_distribution,952
poisson_distribution,953
uniform_int_distribution,948
discrete_distribution
discrete probability function, 963
weights, 963
disengaged, 504
distribution, see random number distribution
dominance
virtual base class, 230
dot operator, see operator, class member access
dynamic binding, see virtual function
dynamic initialization, 59
dynamic type, see type, dynamic
dynamic-exception-specification,391,1225
dynamic_cast,see cast, dynamic
dynarray
contiguous storage, 770
zero sized, 772
ECMA-262, 1
ECMAScript, 1098,1132
egrep,1098
elaborated-type-specifier,151,1218
elaborated type specifier, see class name, elabo-
rated
elif-group,397,1225
elif-groups,397,1225
elision
copy, see constructor, copy, elision; construc-
tor, move, elision
copy constructor, see constructor, copy, eli-
sion
move constructor, see constructor, move, eli-
sion
ellipsis
conversion sequence, 98,295
overload resolution and, 290
else-group,397,1225
EmplaceConstructible into Xfrom args,737
empty future object, 1196
empty shared_future object, 1199
empty-declaration,136,1216
encoding
multibyte, 29
encoding-prefix,27,1210
end
unordered associative containers, 758
end-of-file, 519
endif-line,397,1225
engaged, 504
engine, see random number engine
engine adaptor, see random number engine adap-
tor
engines with predefined parameters
default_random_engine,944
knuth_b,944
minstd_rand,943
minstd_rand0,943
mt19937,943
mt19937_64,943
ranlux24,944
ranlux24_base,943
ranlux48,944
ranlux48_base,943
entity, 32
enum,73
overloading and, 280
type of, 154,155
underlying type, 155
enum-base,155,1218
enum-head,155,1218
enum-key,155,1218
enum-name,154,1218
enum-specifier,154,1218
enumeration, 154,155
linkage of, 56
scoped, 155
unscoped, 155
enumeration scope, 41
enumeration type
conversion to, 103
static_cast
conversion to, 103
enumerator
definition, 34
Cross references 1295
c
ISO/IEC N????
value of, 155
enumerator,155,1219
enumerator-definition,155,1218
enumerator-list,155,1218
enum name
typedef,142
environment
program, 59
epoch, 609
equal_range
unordered associative containers, 757
equality-expression,119,1214
equivalence
template type, 322
type, 141,212
equivalent-key group, 750
equivalent parameter declarations, 280
overloading and, 280
Erasable from X,737
erase
unordered associative containers, 757
escape-sequence,25,1210
escape character, see backslash
escape sequence
undefined, 26
Evaluation, 10
evaluation
order of argument, 98
unspecified order of, 10,60
unspecified order of argument, 98
unspecified order of function call, 98
example
array, 185
class definition, 215
const,181
constant pointer, 181
constructor, 250
constructor and initialization, 260
declaration, 33,188
declarator, 178
definition, 33
delete,259
derived class, 225
destructor and delete,259
ellipsis, 187
enumeration, 156
explicit destructor call, 257
explicit qualification, 229
friend, 213
friend function, 242
function declaration, 187
function definition, 193
linkage consistency, 139
local class, 224
member function, 217,242
nested type name, 224
nested class, 223
nested class definition, 223,246
nested class forward declaration, 223
pointer to member, 183
pure virtual function, 236
scope of delete,259
scope resolution operator, 229
static member, 220
subscripting, 185
typedef,141
type name, 178
unnamed parameter, 193
variable parameter list, 187
virtual function, 233,234
exception
arithmetic, 83
undefined arithmetic, 83
<exception>,457
exception handling, 386396
allowing an exception, 392
constructors and destructors, 389
exception object, 388
constructor, 388
destructor, 388
function try block, 387
goto,386
handler, 386,388391,434
array in, 389
incomplete type in, 389
match, 389391
pointer to function in, 389
rvalue reference in, 389
memory, 388
nearest handler, 388
rethrow, 388,389
rethrowing, 388
switch,386
terminate() called, 388,389,392
throwing, 387,388
try block, 386
unexpected() called, 392
exception object, see exception handling, excep-
tion object
exception specification, 391394
compatible, 391
incomplete type and, 391
Cross references 1296
c
ISO/IEC N????
noexcept
constant expression and, 391
virtual function and, 392
exception-declaration,386,1224
exception-specification,391,1224
exception::what message
implementation-defined, 459
exclusive-or-expression,120,1214
execution agent, 1154
exit,59,61,132
explicit-instantiation,357,1224
explicit-specialization,360,1224
explicitly captured, 92
explicit type conversion, see casting
exponent-part,27,1210
exponential_distribution
probability density function, 954
expression, 83126
additive operators, 117
alignof,114
assignment and compound assignment, 122
bitwise AND, 120
bitwise exclusive OR, 120
bitwise inclusive OR, 120
cast, 98,115116
class member access, 99
comma, 123
conditional operator, 121
constant, 123
const cast, 105
decrement, 100,108
delete,113
dynamic cast, 100
equality operators, 119
function call, 96
increment, 100,108
lambda, 8896
left-shift-operator, 118
logical AND, 120
logical OR, 120
multiplicative operators, 116
new,109
noexcept,114
order of evaluation of, 9
parenthesized, 87
pointer-to-member, 116
pointer to member constant, 107
postfix, 96107
primary, 8696
pseudo-destructor call, 99
reference, 83
reinterpret cast, 104
relational operators, 118
right-shift-operator, 118
rvalue reference, 83
sizeof,108
static cast, 102
type identification, 102
unary, 107114
unary operator, 107
expression,123,1215
expression-list,96,1213
expression-statement,127,1215
extended alignment, 76
extended integer type, 71
extended signed integer type, 71
extended unsigned integer type, 71
extension-namespace-definition,158,1219
extern,138
linkage of, 139
extern "C",420,430
extern "C++",420,430
external linkage, 56
extreme_value_distribution
probability density function, 957
file, source, see source file
final overrider, 231
find
unordered associative containers, 757
finite state machine, 1088
fisher_f_distribution
probability density function, 961
floating literal, see literal, floating
floating-literal,26,1210
floating-point literal, see literal, floating
floating-suffix,27,1210
floating point type, 72
implementation-defined, 72
for
scope of declaration in, 131
for-init-statement,129,1216
for-range-declaration,129,1216
for-range-initializer,129,1216
formal argument, see parameter
format specifier, 1088
forwarding call wrapper, 567
fractional-constant,26,1210
free store, 258
freestanding implementation, 5
free store, see also new,delete
friend
Cross references 1297
c
ISO/IEC N????
virtual and, 234
access specifier and, 244
class access and, 242
inheritance and, 244
local class and, 244
template and, 329
friend function
access and, 242
inline, 243
linkage of, 243
member function and, 242
friend function
nested class, 224
full-expression, 9
function, see also friend function; member func-
tion; inline function; virtual function, 187
allocation, 63,110
comparison, 409
conversion, 254
deallocation, 64,114,258
definition, 34
global, 430,432,433
handler, 410
linkage specification overloaded, 172
modifier, 410
observer, 411
operator, 302
overload resolution and, 283
plain old, 464
pointer to member, 116
replacement, 411
reserved, 411
viable, 283
virtual member, 430,433
function object, 562
binders, 576578
mem_fn,578579
reference_wrapper,567
type, 562
wrapper, 579583
function pointer type, 73
function try block, see exception handling, func-
tion try block
function, overloaded, see overloading
function, virtual, see virtual function
function-definition,192,1221
function-like macro, see macro, function-like
function-specifier,140,1217
function-try-block,386,1224
functions
candidate, 352
function argument, see argument
function call, 97
recursive, 98
undefined, 105
function call operator
overloaded, 304
function parameter, see parameter
function prototype, 39
function return, see return
function return type, see return type
fundamental alignment, 76
fundamental type
destructor and, 258
fundamental type conversion, see conversion, user-
defined
future
shared state, 1192
gamma_distribution
probability density function, 955
generate
seed sequence requirement, 926
generated destructor, see destructor, default
generation algorithm
discard_block_engine,940
independent_bits_engine,941
linear_congruential_engine,936
mersenne_twister_engine,937
shuffle_order_engine,942
subtract_with_carry_engine,938
generic lambda
definition of, 152
geometric_distribution
discrete probability function, 952
global, 40
global namespace, 40
global namespace scope, 40
global scope, 40
glvalue, 75
goto
and handler, 386
and try block, 386
initialization and, 133
grammar
regular expression, 1132
grep,1098
group,397,1225
group-part,397,1225
h-char,20,1208
h-char-sequence,20,1208
Cross references 1298
c
ISO/IEC N????
handler, see exception handling, handler
handler,386,1224
handler-seq,386,1224
happens before, 13
hash
instantiation restrictions, 584
hash code, 750
hash function, 750
hash tables, see unordered associative containers
hash_function
unordered associative containers, 754
hasher
unordered associative containers, 751
header
C, 430,432,1248
C library, 420
C++ library, 418
name, 2021
header-name,20,1208
hex-quad,17,1207
hexadecimal-digit,23,1209
hexadecimal-escape-sequence,25,1210
hexadecimal-literal,23,1209
hiding, see name hiding
high-order bit, 6
hosted implementation, 5
id
qualified, 88
id-expression, 87
id-expression,86,1212
identifier, 2122,87,137
identifier,21,1208
identifier-list,398,1226
identifier-nondigit,21,1208
if-group,397,1225
if-section,397,1225
ill-formed program, see program, ill-formed
immolation
self, 362
implementation
freestanding, 419
hosted, 419
implementation limits, see limits, implementation
implementation-defined, 430,437,449,454,456
459,682,1011,1066,1247
implementation-defined behavior, see behavior, implemen-
tation-defined
implementation-dependent, 1037
implementation-generated, 33
implicit capture
definition of, 92
implicit object parameter, 283
implicitly-declared default constructor, see con-
structor, default, 249
implicit conversion, see conversion, implicit
implied object argument, 283
implicit conversion sequences, 284
non-static member function and, 284
inclusion
conditional, see preprocessing directive, con-
ditional inclusion
source file, see preprocessing directives, source-
file inclusion
inclusive-or-expression,120,1214
incomplete, 117
increment
bool,100,108
increment operator
overloaded, see overloading, increment oper-
ator
independent_bits_engine
generation algorithm, 941
state, 941
textual representation, 942
transition algorithm, 941
indeterminately sequenced, 10
indirection, 107
inheritance, 225
init-capture,89,1212
init-declarator,177,1220
init-declarator-list,177,1220
initialization, 59,195209
aggregate, 199
array, 199
array of class objects, 201,260
automatic, 133,134
automatic object, 196
base class, 261,262
character array, 201
character array, 201
class member, 197
class object, see also constructor, 199,260
265
const,146,198
const member, 263
constant, 59
constructor and, 260
copy, 197
default, 196
default constructor and, 260
definition and, 137
Cross references 1299
c
ISO/IEC N????
direct, 197
dynamic, 59
explicit, 260
jump past, 133
list-initialization, 204209
local static,134
member, 261
member function call during, 264
member object, 262
order of, 59,226
order of base class, 263
order of member, 263
order of virtual base class, 263
overloaded assignment and, 260
parameter, 97
reference, 183,202
reference member, 263
run-time, 59
static and thread, 59
static member, 220
static object,59
static object, 196
union,201,221
virtual base class, 271
initializer
base class, 193
member, 193
pack expansion, 265
scope of member, 264
temporary and declarator, 251
initializer,195,1221
initializer-clause,196,1221
initializer-list,196,1221
initializer-list constructor
seed sequence requirement, 926
<initializer_list>,462
injected-class-name,210
inline, 432
inline
linkage of, 56
inline function, 140
insert
unordered associative containers, 756
instantiation
dependent member of the current, 348
explicit, 357
member of the current, 347
point of, 351
template implicit, 354
instantiation units, 17
integer literal, see literal, integer
integer representation, 65
integer-literal,23,1209
integer-suffix,24,1209
integer type, 72
integral type, 72
sizeof,71
inter-thread happens before, 12
internal linkage, 56
interval boundaries
piecewise_constant_distribution,965
piecewise_linear_distribution,967
invocation
macro, 401
isctype
regular expression traits, 1090
iteration-statement,129,132,1216
Jessie, 253
jump-statement,132,1216
key_eq
unordered associative containers, 754
key_equal
unordered associative containers, 751
key_type
unordered associative containers, 751
keyword, 22
label, 133
case,127,129
default,127,129
scope of, 39,127
labeled-statement,127,1215
lambda-capture,89,1212
lambda-declarator,89,1213
lambda-expression,89,1212
lambda-introducer,89,148,1212
lattice, see DAG, subobject
layout
bit-field, 222
class object, 215,226
layout-compatible type, 156
layout-compatible type, 71
left shift
undefined, 118
left shift operator, 118
lexical conventions, see conventions, lexical
library
C standard, 409,416,418,420,1244,1245,
1248
C++ standard, 408,430,432,434
Cross references 1300
c
ISO/IEC N????
library clauses, 6
lifetime, 66
limits
implementation, 3
<limits>,437
line splicing, 16
linear_congruential_engine
generation algorithm, 936
modulus, 936
state, 936
textual representation, 936
transition algorithm, 936
linkage, 32,5658
const and, 56
external, 56,420,429,430
implementation-defined object, 172
inline and, 56
internal, 56
no, 56,57
static and, 56
linkage specification, see specification, linkage
linkage-specification,170,1219
literal, 2331,86
base of integer, 24
binary, 24
boolean, 29
char16_t,25
char32_t,25
character, 25
constant, 23
decimal, 24
double,27
float,27
floating, 26,27
hexadecimal, 24
char,26
integer, 23,24
long,24
long double,27
multicharacter, 25
implementation-defined value of, 25
narrow-character, 25
octal, 24
pointer, 29
string, 27,28
char16_t,28
char32_t,28
implementation-defined, 29
narrow, 28
type of, 28
undefined change to, 29
wide, 28
type of character, 25
type of floating point, 27
type of integer, 24
unsigned,24
user defined, 30
literal,23,1209
literal type, 70
literal-operator-id,305,1223
load_factor
unordered associative containers, 758
local lambda expression, 92
local variable, 39
local_iterator,751
unordered associative containers, 751
locale, 1088,1089,1091,1098
locale-specific behavior, see behavior, locale-specific
local class
friend, 244
member function in, 217
scope of, 224
local scope, see block scope
local variable
destruction of, 132,133
logical-and-expression,120,1215
logical-or-expression,120,1215
lognormal_distribution
probability density function, 959
long
typedef and, 138
long-long-suffix,24,1209
long-suffix,24,1209
lookup
argument-dependent, 46
class member, 54
class member, 49
elaborated type specifier, 54
member name, 228
name, 32,4256
namespace aliases and, 56
namespace member, 50
qualified name, 4854
template name, 339
unqualified name, 43
using-directives and, 56
lookup_classname
regular expression traits, 1134
lookup_classname
regular expression traits, 1090
lookup_collatename
regular expression traits, 1090
Cross references 1301
c
ISO/IEC N????
low-order bit, 6
lowercase, 416
lparen,398,1225
lvalue, 74,1231
lvalue reference, 72,182
macro
argument substitution, 401
function-like, 400,401
arguments, 401
masking, 432
name, 401
object-like, 400,401
pragma operator, 407
predefined, 406
replacement, 400405
replacement list, 400
rescanning and replacement, 403
scope of definition, 403
main(),58
implementation-defined linkage of, 59
implementation-defined parameters to, 59
parameters to, 59
return from, 59,61
match_results
as sequence, 1116
matched, 1088
max
random number distribution requirement, 931
uniform random number generator require-
ment, 927
max_bucket_count
unordered associative containers, 757
max_load_factor
unordered associative containers, 758
mean
normal_distribution,958
poisson_distribution,953
mem-initializer,261,1223
mem-initializer-id,261,1223
mem-initializer-list,261,1223
member
class static,62
enumerator, 157
static, 219
template and static,324
member access operator
overloaded, 304
member function
call undefined, 217
class, 216
const,218
constructor and, 250
destructor and, 256
friend, 243
inline, 216
local class, 224
nested class, 246
nonstatic, 217
overload resolution and, 283
static, 219
this,218
union,221
volatile,218
member names, 39
member subobject, 7
member-declaration,214,1222
member-declarator,214,1222
member-declarator-list,214,1222
member-specification,214,1222
members, 39
member data
static, 220
member pointer to, see pointer to member
memory location, 6
memory model, 67
memory management, see also new,delete
mersenne_twister_engine
generation algorithm, 937
state, 937
textual representation, 938
transition algorithm, 937
message
diagnostic, 2,5
min
random number distribution requirement, 931
uniform random number generator require-
ment, 927
modification order, 12
most derived class, 7
most derived object, 7
bit-field, 7
zero size subobject, 7
move
class object, see constructor, move; assign-
ment, move
MoveInsertable into X,737
multi-pass guarantee, 842
multibyte character, see character, multibyte
multicharacter literal, see literal, multicharacter
multiple threads, see threads, multiple
multiple inheritance, 225,226
Cross references 1302
c
ISO/IEC N????
virtual and, 234
multiplicative-expression,116,1214
mutable,138
mutable iterator, 839
mutex types, 1162
name, 21,32,87
address of cv-qualified, 107
dependent, 345,351
elaborated
enum,151
global, 40
length of, 21
macro, see macro, name
point of declaration, 37
predefined macro, see macro, predefined
qualified, 48
reserved, 429
scope of, 37
unqualified, 43
name hiding
function, 282
overloading versus, 282
using-declaration and, 165
named-namespace-definition,158,1219
namespace, 417,1248
alias, 161
definition, 158
global, 429
member definition, 160
unnamed, 159
namespace-alias,161,1219
namespace-alias-definition,161,1219
namespace-body,158,1219
namespace-definition,158,1219
namespace-name,158,1219
namespaces, 157170
name class, see class name
name hiding, 37,42,88,133
class definition, 212
user-defined conversion and, 253
name space
label, 127
narrowing conversion, 208
NDEBUG,419
negative_binomial_distribution
discrete probability function, 952
nested-name-specifier,88,1212
nested class
local class, 224
scope of, 222
<new>,449
new,63,109,110
array of class objects and, 112
constructor and, 112
default constructor and, 112
exception and, 112
initialization and, 112
operator,430
scoping and, 109
storage allocation, 109
type of, 258
unspecified constructor and, 112
unspecified order of evaluation, 112
new-declarator,109,1214
new-expression,109,1213
new-initializer,109,1214
new-line,398,1226
new-placement,109,1213
new-type-id,109,1213
new_handler,64
no linkage, 56
noexcept-expression,114,1214
noexcept-specification,391,1225
non-directive,398,1225
non-throwing, 393
nondigit,21,1208
nonzero-digit,23,1209
noptr-abstract-declarator,178,1221
noptr-abstract-pack-declarator,178,1221
noptr-declarator,177,1220
noptr-new-declarator,109,1214
normal distributions, 958963
normal_distribution
mean, 958
probability density function, 958
standard deviation, 958
normative references, see references, normative
notation
syntax, 6
notify_all_at_thread_exit,1182
NTBS, 416,417,1075,1256,1257
static, 417
NTCTS, 411
NTMBS, 417
static, 417
number
hex, 26
octal, 26
numeric_limits,437
specializations for arithmetic types, 72
Cross references 1303
c
ISO/IEC N????
object, see also object model, 7,32
byte copying and, 69
complete, 7
definition, 34
delete, 113
destructor static, 61
destructor and placement of, 257
linkage specification, 172
local static,62
undefined deleted, 64
unnamed, 250
object expression, 99
object model, 7
object pointer type, 73
object representation, 69
object type, 7,70
object, exception, see exception handling, excep-
tion object
object-like macro, see macro, object-like
object class, see also class object
object lifetime, 6669
object temporary, see temporary
object type, 70
observable behavior, see behavior, observable
octal-digit,23,1209
octal-escape-sequence,25,1210
octal-literal,23,1209
odr-used, 34
one-definition rule, 3436
opaque-enum-declaration,155,1218
operation
atomic, 1114
operator, 2223,303
*=,122
+=,108,122
-=,122
/=,122
<<=,122
>>=,122
%=,122
&=,122
ˆ=,122
|=,122
additive, 117
address-of, 107
assignment, 122,417
bitwise, 120
bitwise AND, 120
bitwise exclusive OR, 120
bitwise inclusive OR, 120
cast, 107,178
class member access, 99
comma, 123
conditional expression, 121
copy assignment, see assignment, copy
decrement, 100,107,108
division, 116
equality, 119
function call, 96,302
greater than, 118
greater than or equal to, 118
increment, 100,107,108
indirection, 107
inequality, 119
less than, 118
less than or equal to, 118
logical AND, 120
logical negation, 107,108
logical OR, 120
move assignment, see assignment, move
multiplication, 116
multiplicative, 116
one’s complement, 107,108
overloaded, 83,302
pointer to member, 116
pragma, see macro, pragma operator
precedence of, 9
relational, 118
remainder, 116
scope resolution, 88,111,216,225,235
side effects and comma, 123
side effects and logical AND, 120
side effects and logical OR, 121
sizeof,107,108
subscripting, 96,302
unary, 107
unary minus, 107,108
unary plus, 107,108
operator,302,1223
operator delete,see also delete,111,114,258
operator new,see also new,111
operator overloading, see overloading, operator
operator!=
random number distribution requirement, 932
random number engine requirement, 928
operator()
random number distribution requirement, 931
random number engine requirement, 928
uniform random number generator require-
ment, 927
operator-function-id,302,1223
operator<<
Cross references 1304
c
ISO/IEC N????
random number distribution requirement, 932
random number engine requirement, 928
operator==
random number distribution requirement, 932
random number engine requirement, 928
operator>>
random number distribution requirement, 932
random number engine requirement, 929
operator , see delete
operator left shift, see left shift operator
operator right shift, see right shift operator
operator use
scope resolution, 220
optimization of temporary, see elimination of tem-
porary
optional object for object types, 503
optional objects, 503
order of evaluation in expression, see expression,
order of evaluation of
ordering
function template partial, 337
order of execution
base class constructor, 250
base class destructor, 256
constructor and static objects, 261
constructor and array, 260
destructor, 256
destructor and array, 256
member constructor, 250
member destructor, 256
original-namespace-definition,158,1219
original-namespace-name,158,1219
over-aligned type, 76
overflow, 83
undefined, 83
overloaded function, see overloading
overloaded operator, see overloading, operator
overloadedfunction
address of, 301
overloaded function
address of, 108
overloaded operator
inheritance of, 303
overloading, 187,212,279309,335
access control and, 282
address of overloaded function, 301
argument lists, 283290
assignment operator, 303
binary operator, 303
built-in operators and, 306
candidate functions, 283290
declaration matching, 281
declarations, 279
example of, 279
function call operator, 304
member access operator, 304
operator, 302306
prohibited, 279
resolution, 282300
best viable function, 291303
contexts, 283
function call syntax, 285286
function template, 383
implicit conversions and, 292300
initialization, 288290
operators, 286
scoping ambiguity, 229
template, 337
template name, 339
viable functions, 290303
subscripting operator, 304
unary operator, 303
user-defined literal, 305
using directive and, 169
using-declaration and, 166
overloads
floating point, 924
overrider
final, 231
own, 535
pair
tuple interface to, 487
param
random number distribution requirement, 931
seed sequence requirement, 926
param_type
random number distribution requirement, 931
parameter, 3
catch clause, 3
function, 3
function-like macro, 3
reference, 182
scope of, 39
template, 3,33
void,187
parameter declaration, 33
parameter-declaration,186,1221
parameter-declaration-clause,186,1221
parameter-declaration-list,186,1221
parameterized type, see template
parameters
Cross references 1305
c
ISO/IEC N????
macro, 401
parameters-and-qualifiers,177,1220
parameter list
variable, 97,187
period, 416
phases of translation, see translation, phases
piecewise construction, 489
piecewise_constant_distribution
interval boundaries, 965
probability density function, 965
weights, 965
piecewise_linear_distribution
interval boundaries, 967
probability density function, 967
weights at boundaries, 967
placement syntax
new,111
pm-expression,116,1214
POD class, 211
POD struct, 211
POD union, 211
POF, 464
point of declaration, 37
pointer, see also void*
safely-derived, 65
to traceable object, 435
to traceable object, 65
zero, 81
pointer literal, see literal, pointer
pointer, integer representation of safely-derived,
65
pointer-literal,29,1211
pointer to member, 73,116
Poisson distributions, 953958
poisson_distribution
discrete probability function, 953
mean, 953
POSIX, 1
extended regular expressions, 1098
regular expressions, 1098
postfix-expression,96,1213
postfix ++ and --
overloading, 304
postfix ++,100
postfix --,100
potential results, 34
potential scope, 37
potentially evaluated, 34
pp-number,21,1208
pp-tokens,398,1226
precedence of operator, see operator, precedence
of
prefix
L,25,28
prefix ++ and --
overloading, 304
prefix ++,108
prefix --,108
preprocessing directive, 397
conditional inclusion, 398
preprocessing directives, 397407
error, 406
header inclusion, 399
line control, 405
macro replacement, see macro, replacement
null, 406
pragma, 406
source-file inclusion, 399
preprocessing-file,397,1225
preprocessing-op-or-punc,23,1208
preprocessing-token,19,1207
primary equivalence class, 1089
primary-expression,86,1212
private,see access control, private
probability density function
cauchy_distribution,960
chi_squared_distribution,960
exponential_distribution,954
extreme_value_distribution,957
fisher_f_distribution,961
gamma_distribution,955
lognormal_distribution,959
normal_distribution,958
piecewise_constant_distribution,965
piecewise_linear_distribution,967
student_t_distribution,962
uniform_real_distribution,949
weibull_distribution,956
program, 56
ill-formed, 3
start, 5861
termination, 6162
well-formed, 5,8
program execution, 811
abstract machine, 8
as-if rule, see as-if rule
promotion
bool to int, 80
floating point, 80
integral, 80
protected,see access control, protected
Cross references 1306
c
ISO/IEC N????
protection, see access control, 434
prvalue, 75
pseudo-destructor-name, 99
pseudo-destructor-name,96,1213
ptr-abstract-declarator,178,1221
ptr-declarator,177,1220
ptr-operator,178,1220
ptrdiff_t,117
implementation defined type of, 117
public,see access control, public
punctuator, 2223
pure-specifier,214,1222
q-char,21,1208
q-char-sequence,21,1208
qualification
explicit, 48
qualified-id,88,1212
qualified-namespace-specifier,161,1219
r-char,27,1211
r-char-sequence,27,1211
random number distribution
bernoulli_distribution,950
binomial_distribution,951
chi_squared_distribution,960
discrete_distribution,963
exponential_distribution,954
extreme_value_distribution,957
fisher_f_distribution,961
gamma_distribution,955
geometric_distribution,952
lognormal_distribution,959
negative_binomial_distribution,952
normal_distribution,958
piecewise_constant_distribution,965
piecewise_linear_distribution,967
poisson_distribution,953
requirements, 930933
student_t_distribution,962
uniform_int_distribution,948
uniform_real_distribution,949
random number distributions
Bernoulli, 950953
normal, 958963
Poisson, 953958
sampling, 963968
uniform, 948950
random number engine
linear_congruential_engine,936
mersenne_twister_engine,937
requirements, 927929
subtract_with_carry_engine,938
with predefined parameters, 943944
random number engine adaptor
discard_block_engine,940
independent_bits_engine,941
shuffle_order_engine,942
with predefined parameters, 943944
random number generation, 924968
distributions, 948968
engines, 935943
predefined engines and adaptors, 943944
requirements, 925933
synopsis, 933935
utilities, 945948
random number generator, see uniform random
number generator
random_device
implementation leeway, 944
raw string literal, 28
raw-string,27,1211
reaching scope, 92
ready, 1116,1192
redefinition
typedef,141
ref-qualifier,178,1220
reference, 72
assignment to, 123
call by, 97
lvalue, 72
null, 183
rvalue, 72
sizeof,109
reference collapsing, 183
reference-compatible, 202
reference-related, 202
references
normative, 1
regex_iterator
end-of-sequence, 1127
regex_token_iterator
end-of-sequence, 1129
regex_traits
specializations, 1102
region
declarative, 32,37
register,138
regular expression, 10881134
grammar, 1132
matched, 1088
requirements, 1089
Cross references 1307
c
ISO/IEC N????
regular expression traits, 1132
char_class_type,1089
isctype,1090
lookup_classname,1134
lookup_classname,1090
lookup_collatename,1090
requirements, 1089,1102
transform,1134
transform,1090
transform_primary,1134
transform_primary,1090
translate,1134
translate,1089
translate_nocase,1134
translate_nocase,1090
rehash
unordered associative containers, 759
reinterpret_cast,see cast, reinterpret
relational-expression,118,1214
relaxed pointer safety, 65
release sequence, 12
remainder operator, see remainder operator
replacement
macro, see macro, replacement
replacement-list,398,1226
representation
object, 69
value, 69
requirements, 413
Allocator,424
container, 732,751,763,764,1116
not required for unordered associated con-
tainers, 750
CopyAssignable,420
CopyConstructible,420
DefaultConstructible,420
Destructible,420
EqualityComparable,420
Hash,424
iterator, 839
LessThanComparable,420
MoveAssignable,420
MoveConstructible,420
NullablePointer,423
numeric type, 912
random number distribution, 930933
random number engine, 927929
regular expression traits, 1089,1102
seed sequence, 925926
sequence, 1116
uniform random number generator, 926927
unordered associative container, 751
reraise, see exception handling, rethrow
rescanning and replacement, see macro, rescan-
ning and replacement
reserved identifier, 22
reset, 535
reset
random number distribution requirement, 931
resolution, see overloading, resolution
restriction, 432,434
address of bit-field, 222
anonymous union,221
bit-field, 222
constructor, 249,250
destructor, 256
extern,139
local class, 224
operator overloading, 302
overloading, 303
pointer to bit-field, 222
reference, 183
register,138
static,139
static member local class, 220
union,221
result_type
entity characterization based on, 924
result_type
random number distribution requirement, 931
seed sequence requirement, 926
uniform random number generator require-
ment, 927
rethrow, see exception handling, rethrow
return,132,133
and handler, 386
and try block, 386
constructor and, 133
reference and, 202
return statement, see return
return type, 188
overloading and, 279
right shift
implementation defined, 118
right shift operator, 118
rounding, 81
runtime bound
array of, see array of runtime bound
rvalue, 75
lvalue conversion to, see conversion, lvalue to
rvalue
lvalue conversion to, 1231
Cross references 1308
c
ISO/IEC N????
rvalue reference, 72,182
s-char,27,1210
s-char-sequence,27,1210
safely-derived pointer, 65
integer representation, 65
sampling distributions, 963968
scalar type, 70
scope, 1,32,3742,137
anonymous union at namespace, 221
block, 39
class, 40
declarations and, 3739
destructor and exit from, 132
enumeration, 41
exception declaration, 39
function, 39
function prototype, 39
global, 40
global namespace, 40
iteration-statement,130
macro definition, see macro, scope of defini-
tion
namespace, 39
name lookup and, 4256
overloading and, 281
potential, 37
selection-statement,128
template parameter, 41
scope name hiding and, 42
scope resolution operator, 49
seed
random number engine requirement, 928
seed sequence, 925
requirements, 925926
selection-statement,128,1215
semantics
class member, 99
separate compilation, see compilation, separate
separate translation, see compilation, separate
sequence
ambiguous conversion, 293
implicit conversion, 292
standard conversion, 77
sequence constructor
seed sequence requirement, 926
Sequenced before, 10
sequencing operator, see comma operator
setlocale,416
shared state, see future, shared state
shift-expression,118,1214
shift operator, see left shift operator, right shift op-
erator
short
typedef and, 138
shuffle_order_engine
generation algorithm, 942
state, 942
textual representation, 943
transition algorithm, 942
side effects, 8,1014,120,121,127,251,263,274,
403,434
visible, 13
visible sequence of, 13
sign,27,1210
signal, 8
signature, 3,4
signed
typedef and, 138
signed integer type, 71
simple call wrapper, 567
simple-capture,89,1212
simple-declaration,136,1216
simple-escape-sequence,25,1210
simple-template-id,314,1224
simple-type-specifier,148,1218
size
seed sequence requirement, 926
size_t,109
smart pointers, 546562
source file, 16,419,430
source file character, see character, source file
space
white, 19
specialization
class template, 316
class template partial, 331
template, 353
template explicit, 360
special member function, see constructor, destruc-
tor, inline function, user-defined conver-
sion, virtual function
specification
linkage, 170173
extern,170
implementation-defined, 170
nesting, 170
template argument, 365
specifications
C standard library exception, 435
C++, 435
implementation-defined exception, 435
Cross references 1309
c
ISO/IEC N????
specifier, 137153
friend,434
constexpr,142
constructor, 143,144
function, 143
cv-qualifier, 146
declaration, 137
explicit,140
friend,142
function, 140
inline,140
static,138
storage class, 138
type, see type specifier
typedef,140
virtual,140
specifier access, see access specifier
stable algorithm, 411,433
stack unwinding
see exception handling, constructors and de-
structors, 389
standard
structure of, 56
standard deviation
normal_distribution,958
standard-layout types, 70
standard-layout class, 211
standard-layout struct, 211
standard-layout union, 211
standard integer type, 71
standard signed integer type, 71
standard unsigned integer type, 71
start
program, 59
startup
program, 420,430
state
discard_block_engine,940
independent_bits_engine,941
linear_congruential_engine,936
mersenne_twister_engine,937
object, 411
shuffle_order_engine,942
subtract_with_carry_engine,938
statement, 127135
continue in for,131
break,132
compound, 127
continue,132
declaration, 133
declaration in if,128
declaration in switch,128
declaration in for,131
declaration in switch,129
declaration in while,130
do,129,130
empty, 127
expression, 127
for,129,131
goto,127,132,133
if,128,129
iteration, 129132
jump, 132
labeled, 127
null, 127
for,131
selection, 128129
switch,128,129,132
while,129,130
statement,127,1215
statement-seq,127,1215
static,138
destruction of local, 134
linkage of, 56,139
overloading and, 279
static initialization, 59
static storage duration, 62
static type, see type, static
static_assert,137
static_assert-declaration,136,1216
static_cast,see cast, static
<stddef.h>,25,28
<stdexcept>,466
storage-class-specifier,138,1217
storage class, 32
storage duration, 6266
automatic, 62,63
class member, 66
dynamic, 6265,109
local object, 63
register,63
static, 62
thread, 62
storage management, see new,delete
stream
arbitrary-positional, 409
repositional, 411
streambuf
implementation-defined, 999
strict pointer safety, 65
string
distinct, 29
Cross references 1310
c
ISO/IEC N????
null-terminated byte, 416
null-terminated character type, 411
null-terminated multibyte, 417
sizeof,29
type of, 28
string literal, see literal, string
string-literal,27,1210
stringize, see #
struct
standard-layout, 211
struct
class versus, 211
structure, 211
structure tag, see class name
student_t_distribution
probability density function, 962
sub-expression, 1089
subobject, see also object model, 7
subscripting operator
overloaded, 304
subsequence rule
overloading, 298
subtract_with_carry_engine
carry, 938
generation algorithm, 938
state, 938
textual representation, 939
transition algorithm, 938
subtraction
implementation defined pointer, 117
subtraction operator, 117
suffix
E,27
e,27
F,27
f,27
L,24,27
l,24,27
U,24
u,24
summary
x C++ 2003, 1237
x C++ 2011, 1244
compatibility with ISO C, 1229
swappable, 422
swappable with, 422
switch
and handler, 386
and try block, 386
synchronize with, 12
synonym, 161
type name as, 141
syntax
class member, 99
target object, 566
template, 310385
definition of, 310
function, 365
member function, 324
primary, 331
static data member, 310
variable, 310
template,310
template parameter, 33
template-argument,314,1224
template-argument-list,314,1224
template-declaration,310,1223
template-id,314,1224
template-name,314,1224
template-parameter,311,1224
template-parameter-list,310,1223
template name
linkage of, 311
template parameter scope, 41
temporary, 250
constructor for, 251
destruction of, 251
destructor for, 251
elimination of, 250,274
implementation-defined generation of, 250
order of destruction of, 251
terminate(),394,395
called, 388,389,392,394
termination
program, 59,62
terminology
pointer, 73
text-line,397,1225
textual representation
discard_block_engine,941
independent_bits_engine,942
shuffle_order_engine,943
subtract_with_carry_engine,939
this,86,218
type of, 218
this pointer, see this
thread, 11
thread of execution, 11
thread storage duration, 62
thread, blocked, 409
thread_local,138
Cross references 1311
c
ISO/IEC N????
threads
multiple, 1114
throw,386
throw-expression,386,1224
throwing, see exception handling, throwing
timed mutex types, 1165
token, 20
alternative, 20
preprocessing, 19,1207
token,20,1208
traceable pointer object, 65,435
trailing-return-type,177,1220
trailing-type-specifier,145,1217
trailing-type-specifier-seq,146,1217
traits, 411
transfer ownership, 536
transform
regular expression traits, 1134
transform
regular expression traits, 1090
transform_primaryl
regular expression traits, 1134
transform_primary
regular expression traits, 1133
transform_primaryl
regular expression traits, 1090
TransformationTrait, 585
transition algorithm
discard_block_engine,940
independent_bits_engine,941
linear_congruential_engine,936
mersenne_twister_engine,937
shuffle_order_engine,942
subtract_with_carry_engine,938
translate
regular expression traits, 1134
translate
regular expression traits, 1089
translate_nocase
regular expression traits, 1134
translate_nocase
regular expression traits, 1090
translation
phases, 1617
separate, see compilation, separate
translation unit, 16
translation units, 56
translation-unit,56,1211
translation unit, 56
name and, 32
trigraph sequence, 16,18
trivial types, 70
trivially copyable class, 211
trivially copyable types, 70
trivial class, 211
trivial class type, 112
trivial type, 112
truncation, 81
try,386
try block, see exception handling, try block
try-block,386,1224
tuple
and pair,487
type, 32,6974
arithmetic, 72
array, 72,187
bitmask, 415,416
Boolean, 71
char,71
char16_t,71
char32_t,71
character, 71
character container, 409
class and, 210
compound, 72
const,145
destination, 197
double,72
dynamic, 2
enumerated, 73,415
enumeration underlying, 156
example of incomplete, 70
extended integer, 71
extended signed integer, 71
extended unsigned integer, 71
float,72
floating point, 71
function, 72,186,187
fundamental, 71
sizeof,71
incomplete, 34,35,38,69,78,96100,102,
107109,113,122,225
int,71
integral, 71
long,71
long double,72
long long,71
multi-level mixed pointer and pointer to mem-
ber, 79
multi-level pointer to member, 79
narrow character, 71
over-aligned, 76
Cross references 1312
c
ISO/IEC N????
POD, 70
pointer, 72
polymorphic, 231
referenceable, 411
short,71
signed char,71
signed integer, 71
standard integer, 71
standard signed integer, 71
standard unsigned integer, 71
static, 4
trivially copyable, 69
underlying wchar_t,71
unsigned,71
unsigned char,71
unsigned int,71
unsigned long,71
unsigned long long,71
unsigned short,71
unsigned integer, 71
void,72
volatile,145
wchar_t,71
type generator, see template
type specifier
auto,151
const,146
elaborated, 151
simple, 147
volatile,146
type-id,178,1221
type-id-list,391,1225
type-name,148,1218
type-parameter,311,1224
type-specifier
bool,148
wchar_t,148
type-specifier,145,1217
type-specifier-seq,146,1217
type_info,102
typedef
function, 188
typedef
overloading and, 280
typedef-name,141,1217
typeid,102
construction and, 267
destruction and, 267
<typeinfo>,455
typename,151
typename-specifier,340,1224
types
implementation-defined, 415
implementation-defined exception, 435
type checking
argument, 97
type conversion, explicit, see casting
type name, 178
nested, 224
scope of, 224
type pun, 105
type specifier
auto,148
char,148
char16_t,148
char32_t,148
decltype,148,150
double,148
elaborated, 54
enum,151
float,148
int,148
long,148
short,148
signed,148
unsigned,148
void,148
volatile,147
ud-suffix,30,1211
unary function, 567
unary operator
overloaded, 303
unary-expression,107,1213
unary-operator,107,1213
UnaryTypeTrait, 584
unary operator
interpretation of, 303
unblock, 412
uncaught_exception(),396
undefined, 411,429,430,432,973,975,978981,
985,989,1013
undefined behavior, see behavior, undefined, 868
underlying type, 72
unevaluated operand, 84
unexpected(),393,395
called, 392
Unicode required set, 407
uniform distributions, 948950
uniform random number generator
requirements, 926927
uniform_int_distribution
Cross references 1313
c
ISO/IEC N????
discrete probability function, 948
uniform_real_distribution
probability density function, 949
union
standard-layout, 211
union,72,220
class versus, 211
anonymous, 221
global anonymous, 221
unique pointer, 535
unit
translation, 419,429
universal character name, 16
universal-character-name,18,1207
unnamed-namespace-definition,158,1219
unordered associative containers, 750829
begin,758
bucket,758
bucket_count,757
bucket_size,758
cbegin,758
cend,758
clear,757
complexity, 750
const_local_iterator,752
count,757
end,758
equal_range,757
equality function, 750
equivalent keys, 750,751,818,825
erase,757
exception safety, 759,760
find,757
hash function, 750
hash_function,754
hasher,751
insert,756
iterator invalidation, 759
iterators, 759
key_eq,754
key_equal,751
key_type,751
lack of comparison operators, 750
load_factor,758
local_iterator,751
max_bucket_count,757
max_load_factor,758
rehash,759
requirements, 750,751,759,760
unique keys, 750,751,814,822
unordered_map
element access, 817
unique keys, 814
unordered_multimap
equivalent keys, 818
unordered_multiset
equivalent keys, 825
unordered_set
unique keys, 822
unqualified-id,86,1212
unsequenced, 10
unsigned
typedef and, 138
unsigned-suffix,24,1209
unsigned integer type, 71
unspecified, 450,451,456,899,1064,1252,1254
unspecified behavior, see behavior, unspecified, 979
unwinding
stack, 389
uppercase, 416,429
user-defined literal, see literal, user defined
overloaded, 305
user-defined-character-literal,30,1211
user-defined-floating-literal,30,1211
user-defined-integer-literal,30,1211
user-defined-literal,30,1211
user-defined-string-literal,30,1211
user-provided, 194
Uses-allocator construction, 527
using-declaration, 161167
using-declaration,161,1219
using-directive, 167170
using-directive,167,1219
usual arithmetic conversions, see conversion, usual
arithmetic
valid, 37
valid but unspecified state, 412
value, 69
call by, 97
null member pointer, 81
null pointer, 81
undefined unrepresentable integral, 81
value category, 75
value computation, 1011,13,14,100,112,120
123,251
value representation, 69
value-initialization, 196
variable, 32
indeterminate uninitialized, 196
variable template
definition of, 310
Cross references 1314
c
ISO/IEC N????
virt-specifier,214,1222
virt-specifier-seq,214,1222
virtual base class, 227
virtual function, 231235
pure, 235,236
virtual function call, 235
constructor and, 266
destructor and, 266
undefined pure, 236
visibility, 42
visible, 42
void*
type, 73
void&,182
volatile,73
constructor and, 219,249
destructor and, 219,256
implementation-defined, 147
overloading and, 281
waiting function, 1192
wchar_t,25,28,671
implementation-defined, 71
weak result type, 566
weibull_distribution
probability density function, 956
weights
discrete_distribution,963
piecewise_constant_distribution,965
weights at boundaries
piecewise_linear_distribution,967
well-formed program, see program, well-formed
white space, 20
wide-character, 25
X(X&),see copy constructor
xvalue, 74
zero
division by undefined, 83
remainder undefined, 83
undefined division by, 117
zero-initialization, 196
Cross references 1315
c
ISO/IEC N????
Index of grammar productions
The first page number for each entry is the page in the general text where the grammar production is
defined. The second page number is the corresponding page in the Grammar summary (Annex A).
abstract-declarator,178,1221
abstract-pack-declarator,178,1221
access-specifier,225,1223
additive-expression,117,1214
alias-declaration,136,1216
alignment-specifier,173,1219
and-expression,120,1214
asm-definition,170,1219
assignment-expression,122,1215
assignment-operator,122,1215
attribute,173,1219
attribute-argument-clause,173,1220
attribute-declaration,136,1217
attribute-list,173,1219
attribute-namespace,173,1220
attribute-scoped-token,173,1220
attribute-specifier,173,1219
attribute-specifier-seq,173,1219
attribute-token,173,1220
balanced-token,173,1220
balanced-token-seq,173,1220
base-clause,225,1222
base-specifier,225,1223
base-specifier-list,225,1222
base-type-specifier,225,1223
binary-digit,24,1209
binary-literal,23,1209
block-declaration,136,1216
boolean-literal,29,1211
brace-or-equal-initializer,196,1221
braced-init-list,196,1222
c-char,25,1210
c-char-sequence,25,1210
capture,89,1212
capture-default,89,1212
capture-list,89,1212
cast-expression,115,1214
character-literal,25,1209
class-head,210,1222
class-head-name,210,1222
class-key,210,1222
class-name,210,1222
class-or-decltype,225,1223
class-specifier,210,1222
class-virt-specifier,210,1222
compound-statement,127,1215
condition,128,1215
conditional-expression,121,1215
constant-expression,124,1215
control-line,397,1225
conversion-declarator,254,1223
conversion-function-id,254,1223
conversion-type-id,254,1223
ctor-initializer,261,1223
cv-qualifier,178,1220
cv-qualifier-seq,178,1220
d-char,28,1211
d-char-sequence,27,1211
decimal-literal,23,1209
decl-specifier,137,1217
decl-specifier-seq,138,1217
declaration,136,1216
declaration-seq,136,1216
declaration-statement,133,1216
declarator,177,1220
declarator-id,178,1221
decltype-specifier,148,1218
delete-expression,113,1214
digit,21,1208
digit-sequence,27,1210
dynamic-exception-specification,391,1225
elaborated-type-specifier,151,1218
elif-group,397,1225
elif-groups,397,1225
else-group,397,1225
empty-declaration,136,1216
encoding-prefix,27,1210
endif-line,397,1225
enum-base,155,1218
enum-head,155,1218
enum-key,155,1218
enum-name,154,1218
Cross references 1316
c
ISO/IEC N????
enum-specifier,154,1218
enumerator,155,1219
enumerator-definition,155,1218
enumerator-list,155,1218
equality-expression,119,1214
escape-sequence,25,1210
exception-declaration,386,1224
exception-specification,391,1224
exclusive-or-expression,120,1214
explicit-instantiation,357,1224
explicit-specialization,360,1224
exponent-part,27,1210
expression,123,1215
expression-list,96,1213
expression-statement,127,1215
extension-namespace-definition,158,1219
floating-literal,26,1210
floating-suffix,27,1210
for-init-statement,129,1216
for-range-declaration,129,1216
for-range-initializer,129,1216
fractional-constant,26,1210
function-definition,192,1221
function-specifier,140,1217
function-try-block,386,1224
group,397,1225
group-part,397,1225
h-char,20,1208
h-char-sequence,20,1208
handler,386,1224
handler-seq,386,1224
header-name,20,1208
hex-quad,17,1207
hexadecimal-digit,23,1209
hexadecimal-escape-sequence,25,1210
hexadecimal-literal,23,1209
id-expression,86,1212
identifier,21,1208
identifier-list,398,1226
identifier-nondigit,21,1208
if-group,397,1225
if-section,397,1225
inclusive-or-expression,120,1214
init-capture,89,1212
init-declarator,177,1220
init-declarator-list,177,1220
initializer,195,1221
initializer-clause,196,1221
initializer-list,196,1221
integer-literal,23,1209
integer-suffix,24,1209
iteration-statement,129,1216
jump-statement,132,1216
labeled-statement,127,1215
lambda-capture,89,1212
lambda-declarator,89,1213
lambda-expression,89,1212
lambda-introducer,89,1212
linkage-specification,170,1219
literal,23,1209
literal-operator-id,305,1223
logical-and-expression,120,1215
logical-or-expression,120,1215
long-long-suffix,24,1209
long-suffix,24,1209
lparen,398,1225
mem-initializer,261,1223
mem-initializer-id,261,1223
mem-initializer-list,261,1223
member-declaration,214,1222
member-declarator,214,1222
member-declarator-list,214,1222
member-specification,214,1222
multiplicative-expression,116,1214
named-namespace-definition,158,1219
namespace-alias,161,1219
namespace-alias-definition,161,1219
namespace-body,158,1219
namespace-definition,158,1219
namespace-name,158,1219
nested-name-specifier,88,1212
new-declarator,109,1214
new-expression,109,1213
new-initializer,109,1214
new-line,398,1226
new-placement,109,1213
new-type-id,109,1213
noexcept-expression,114,1214
noexcept-specification,391,1225
non-directive,398,1225
nondigit,21,1208
nonzero-digit,23,1209
noptr-abstract-declarator,178,1221
noptr-abstract-pack-declarator,178,1221
Cross references 1317
c
ISO/IEC N????
noptr-declarator,177,1220
noptr-new-declarator,109,1214
octal-digit,23,1209
octal-escape-sequence,25,1210
octal-literal,23,1209
opaque-enum-declaration,155,1218
operator,302,1223
operator-function-id,302,1223
original-namespace-definition,158,1219
original-namespace-name,158,1219
parameter-declaration,186,1221
parameter-declaration-clause,186,1221
parameter-declaration-list,186,1221
parameters-and-qualifiers,177,1220
pm-expression,116,1214
pointer-literal,29,1211
postfix-expression,96,1213
pp-number,21,1208
pp-tokens,398,1226
preprocessing-file,397,1225
preprocessing-op-or-punc,23,1208
preprocessing-token,19,1207
primary-expression,86,1212
pseudo-destructor-name,96,1213
ptr-abstract-declarator,178,1221
ptr-declarator,177,1220
ptr-operator,178,1220
pure-specifier,214,1222
q-char,21,1208
q-char-sequence,21,1208
qualified-id,88,1212
qualified-namespace-specifier,161,1219
r-char,27,1211
r-char-sequence,27,1211
raw-string,27,1211
ref-qualifier,178,1220
relational-expression,118,1214
replacement-list,398,1226
s-char,27,1210
s-char-sequence,27,1210
selection-statement,128,1215
shift-expression,118,1214
sign,27,1210
simple-capture,89,1212
simple-declaration,136,1216
simple-escape-sequence,25,1210
simple-template-id,314,1224
simple-type-specifier,148,1218
statement,127,1215
statement-seq,127,1215
static_assert-declaration,136,1216
storage-class-specifier,138,1217
string-literal,27,1210
template-argument,314,1224
template-argument-list,314,1224
template-declaration,310,1223
template-id,314,1224
template-name,314,1224
template-parameter,311,1224
template-parameter-list,310,1223
text-line,397,1225
throw-expression,386,1224
token,20,1208
trailing-return-type,177,1220
trailing-type-specifier,145,1217
trailing-type-specifier-seq,146,1217
translation-unit,56,1211
try-block,386,1224
type-id,178,1221
type-id-list,391,1225
type-name,148,1218
type-parameter,311,1224
type-specifier,145,1217
type-specifier-seq,146,1217
typedef-name,141,1217
typename-specifier,340,1224
ud-suffix,30,1211
unary-expression,107,1213
unary-operator,107,1213
universal-character-name,18,1207
unnamed-namespace-definition,158,1219
unqualified-id,86,1212
unsigned-suffix,24,1209
user-defined-character-literal,30,1211
user-defined-floating-literal,30,1211
user-defined-integer-literal,30,1211
user-defined-literal,30,1211
user-defined-string-literal,30,1211
using-declaration,161,1219
using-directive,167,1219
virt-specifier,214,1222
virt-specifier-seq,214,1222
Cross references 1318
c
ISO/IEC N????
Index of library names
_Exit,448
__alignas_is_defined,464
__bool_true_false_are_defined,463,464
_1,578
a
cauchy_distribution,961
extreme_value_distribution,957
uniform_int_distribution,949
uniform_real_distribution,950
weibull_distribution,957
abort,62,132,419,448,455,459
abs,982,993
complex,921
accumulate,991
acos,982,993
complex,922
acosh,993
complex,922
address
allocator,531
addressof,533
adjacent_difference,992
adjacent_find,886
adopt_lock,1170
adopt_lock_t,1170
advance,850
<algorithm>,873
align,527
all
bitset,518
all_of,884
allocate
allocator,531
allocator_traits,530
scoped_allocator_adaptor,626
allocate_shared,553
allocator, 1121
allocator,530
address,531
allocate,531
constructor, 532
deallocate,532
destructor, 532
max_size,532
operator!=,532
operator==,532
allocator_arg,527
allocator_arg_t,527
allocator_traits,528
allocate,530
const_pointer,529
const_void_pointer,529
constructor, 530
deallocate,530
destructor, 530
difference_type,529
max_size,530
pointer,528
propagate_on_container_copy_assignment,
529
propagate_on_container_move_assignment,
529
propagate_on_container_swap,529
rebind_alloc,529
select_on_container_copy_construction,
530
size_type,529
void_pointer,529
alpha
gamma_distribution,956
always_noconv
codecvt,697
any
bitset,518
any_of,884
append
basic_string,652,653
apply
valarray,979
arg,924
complex,921
<array>,760
array,762,763,765
begin,763
data,764
end,763
fill,764
get,765
max_size,763
Cross references 1319
c
ISO/IEC N????
size,763,764
swap,764
asin,982,993
complex,922
asinh,993
complex,922
<assert.h>,419
assign
basic_regex,1108
basic_string,653,654
error_code,477
error_condition,479
function,582
async,1201
at
basic_string,651
map,800
unordered_map,817
at_quick_exit,448,449
atan,982,993
complex,922
atan2,982,993
atanh,993
complex,922
atexit,61,419,448
<atomic>,1135
atomic type
atomic_compare_exchange_strong,1147
atomic_compare_exchange_strong_-
explicit,1147
atomic_compare_exchange_weak,1147
atomic_compare_exchange_weak_-
explicit,1147
atomic_exchange,1147
atomic_exchange_explicit,1147
atomic_fetch_,1149
atomic_is_lock_free,1146
atomic_load,1147
atomic_load_explicit,1147
atomic_store,1146
atomic_store_explicit,1146
compare_exchange_strong,1147
compare_exchange_strong_explicit,1147
compare_exchange_weak,1147
compare_exchange_weak_explicit,1147
constructor, 1146
exchange,1147
fetch_,1149
load,1147
operator @=,1149
operator C,1147
operator++,1150
operator--,1150
operator=,1147
store,1146
atomic_compare_exchange_strong
atomic type,1147
shared_ptr,561
atomic_compare_exchange_strong_explicit
atomic type,1147
shared_ptr,561
atomic_compare_exchange_weak
atomic type,1147
shared_ptr,561
atomic_compare_exchange_weak_explicit
atomic type,1147
shared_ptr,561
atomic_exchange
atomic type,1147
shared_ptr,561
atomic_exchange_explicit
atomic type,1147
shared_ptr,561
atomic_fetch_
atomic type,1149
atomic_flag
clear,1151
atomic_flag_clear,1151
atomic_flag_clear_explicit,1151
atomic_flag_test_and_set,1151
atomic_flag_test_and_set_explicit,1151
atomic_is_lock_free
atomic type,1146
shared_ptr,560
atomic_load
atomic type,1147
shared_ptr,560
atomic_load_explicit
atomic type,1147
shared_ptr,560
atomic_signal_fence,1152
atomic_store
atomic type,1146
shared_ptr,560
atomic_store_explicit
atomic type,1146
shared_ptr,560
atomic_thread_fence,1151
auto_ptr,551,1264
auto_ptr,1265
auto_ptr_ref,1266
constructor, 1265,1266
Cross references 1320
c
ISO/IEC N????
destructor, 1266
operator=,1265
auto_ptr_ref
auto_ptr,1266
operator auto_ptr,1266
operator=,1266
b
cauchy_distribution,961
extreme_value_distribution,958
uniform_int_distribution,949
uniform_real_distribution,950
weibull_distribution,957
back
basic_string,651
back_insert_iterator,856
back_insert_iterator,856
back_inserter,857
bad
basic_ios,1018
bad_alloc,112,450,453,455
bad_alloc,454
bad_alloc::what
implementation-defined, 454
bad_array_length,454
bad_array_length,454
bad_array_new_length,454
bad_array_new_length,454
bad_cast,101,455,456
bad_cast,456
bad_cast::what
implementation-defined, 457
bad_exception,459
bad_exception,459
bad_exception::what
implementation-defined, 459
bad_function_call,579
bad_function_call,579
bad_optional_access,511
bad_typeid,102,455,457
bad_typeid,457
bad_weak_ptr,546
bad_weak_ptr,547
what,547
base
move_iterator,862
reverse_iterator,853
basic_filebuf,999,1072
basic_filebuf,1073
constructor, 1074
destructor, 1074
operator=,1074
swap,1074
basic_filebuf<char>,1072
basic_filebuf<wchar_t>,1072
basic_fstream,999,1083
basic_fstream,1084
constructor, 1084
operator=,1085
swap,1085
basic_ifstream,999,1079
basic_ifstream,1080
constructor, 1080
operator=,1080
swap,1080
basic_ifstream<char>,1072
basic_ifstream<wchar_t>,1072
basic_ios,999,1014
basic_ios,1015
constructor, 1015
destructor, 1015
exceptions,1019
fill,1016
init,1015
move,1017
rdbuf,1016
set_rdbuf,1017
swap,1017
tie,1016
basic_ios<char>,1004
basic_ios<wchar_t>,1004
basic_iostream,1046
basic_iostream,1046
constructor, 1046
destructor, 1046
operator=,1046
swap,1047
basic_istream,999,1033
basic_istream,1035
constructor, 1036
destructor, 1036,1037
get,1041,1042,1045
operator<<,1047
operator=,1036
seekg,1045
swap,1036
tellg,1045
basic_istream<char>,1032
basic_istream<wchar_t>,1032
basic_istreambuf_iterator,999
basic_istringstream,999,1066
basic_istringstream,1067
Cross references 1321
c
ISO/IEC N????
constructor, 1067
operator=,1067
str,1068
swap,1067
basic_istringstream<char>,1061
basic_istringstream<wchar_t>,1061
basic_ofstream,999,1081
basic_ofstream,1082
constructor, 1082
operator=,1082
swap,1082,1083
basic_ofstream<char>,1072
basic_ofstream<wchar_t>,1072
basic_ostream,999,1116
basic_ostream,1049
constructor, 1049
destructor, 1049,1050
operator<<,1052,1053,1055
operator=,1049
seekp,1050
swap,1049
basic_ostream<char>,1033
basic_ostream<wchar_t>,1033
basic_ostreambuf_iterator,999
basic_ostringstream,999,1068
basic_ostringstream,1069
constructor, 1069
operator=,1069
str,1070
swap,1069
basic_ostringstream<char>,1061
basic_ostringstream<wchar_t>,1061
basic_regex,1091,1104,1132
assign,1108
basic_regex,1106,1107
constants, 1105,1106
constructor, 1106,1107
flag_type,1109
getloc,1109
imbue,1109
mark_count,1109
operator=,1107
swap,1109
basic_streambuf,999,1023
basic_streambuf,1025
constructor, 1025
destructor, 1025
operator=,1027
setbuf,1066
swap,1027
basic_streambuf<char>,1022
basic_streambuf<wchar_t>,1022
basic_string,641,663,1061
append,652,653
assign,653,654
at,651
back,651
begin,649
capacity,650
cbegin,649
cend,649
clear,650
compare,663
constructor, 645647
copy,658
crbegin,649
crend,649
empty,651
end,649
erase,656
find,659
find_first_not_of,661,662
find_first_of,660
find_last_not_of,662
find_last_of,661
front,651
get_allocator,659
getline,668,669
insert,654,655
length,649
max_size,650
operator!=,666
operator+,663665
operator+=,651,652
operator<,666
operator<=,667
operator<<,668
operator=,648,649
operator==,665
operator>,666,667
operator>=,667
operator>>,668
operator[],651
pop_back,656
push_back,653
rbegin,649
rend,649
replace,656658
reserve,650
resize,650
rfind,660
shrink_to_fit,650
Cross references 1322
c
ISO/IEC N????
size,649
substr,662
swap,659,667
basic_stringbuf,999,1061
basic_stringbuf,1062
constructor, 1062,1063
operator=,1063
str,1064
swap,1063
basic_stringbuf<char>,1061
basic_stringbuf<wchar_t>,1061
basic_stringstream,999,1070
basic_stringstream,1071
constructor, 1071
operator=,1071
str,1071
swap,1071
before
type_info,456
before_begin
forward_list,776
begin,462
array,763
basic_string,649
initializer_list,463
match_results,1120
valarray,990
begin(C&),871
begin(initializer_list<E>),463
begin(T (&)[N]),871
bernoulli_distribution,950
constructor, 950
p,951
beta
gamma_distribution,956
bidirectional_iterator_tag,849
binary_function,568,1260
binary_negate,576
binary_search,902
bind,577578
bind1st,1263
bind2nd,1264
binder1st,1263
binder2nd,1263
binomial_distribution,951
constructor, 951
p,951
t,951
bit_and,574
bit_and<>,575
bit_not<>,575
bit_or,574
bit_or<>,575
bit_xor,575
bit_xor<>,575
<bitset>,513
bitset,513
bitset,515
flip,517
operator[],519
reset,517
set,516
boolalpha,1019
byte_string
wstring_convert,685
c_str
basic_string,659
cacos
complex,922
cacosh
complex,922
call_once,1180
calloc,535,1247
capacity
basic_string,650
vector,790
casin
complex,922
casinh
complex,922
<cassert>,419
catan
complex,922
catanh
complex,922
category
error_code,477
error_condition,479
locale,678
cauchy_distribution,960
a,961
b,961
constructor, 961
cbefore_begin
forward_list,776
cbegin
basic_string,649
cbegin(const C&),871
cbrt,993
<ccomplex>,924
cend
Cross references 1323
c
ISO/IEC N????
basic_string,649
cend(const C&),871
cerr,1002
<cerrno>,429
<cfenv>,913
CHAR_BIT,446
char_class_type
regex_traits,1102
CHAR_MAX,446
char_traits,633636
char_type,633
int_type,633
off_type,633
pos_type,633
state_type,633
char_type
char_traits,633
chi_squared_distribution,960
constructor, 960
n,960
chrono,606
cin,1002
<ciso646>,1245
classic
locale,683
classic_table
ctype<char>,695
clear
atomic_flag,1151
basic_ios,1018
basic_string,650
error_code,477
error_condition,479
forward_list,778
<climits>,1252
<clocale>,416,1245
clock,463,464
clock_t,464
CLOCKS_PER_SEC,464
clog,1002
close
basic_filebuf,1076,1085
basic_ifstream,1081
basic_ofstream,1083
messages,726
code
future_error,1191
system_error,481
codecvt,696,729
always_noconv,697
do_always_noconv,699
do_encoding,699
do_in,698
do_length,699
do_max_length,700
do_out,698
do_unshift,698
encoding,697
in,697
length,697
max_length,697
out,697
unshift,697
codecvt_byname,700
collate,711
compare,712
do_compare,712
do_hash,712
do_transform,712
hash,712
transform,712
collate_byname,713
combine
locale,682
common_type,610,611,614
compare
basic_string,663
collate,712
sub_match,1110
compare_exchange_strong
atomic type,1147
compare_exchange_strong_explicit
atomic type,1147
compare_exchange_weak
atomic type,1147
compare_exchange_weak_explicit
atomic type,1147
<complex>,914
complex,916
complex,918
imag,918
operator-,920
operator/,920
real,918
<condition_variable>,1182
condition_variable
constructor, 1183
destructor, 1183
notify_all,1183
notify_one,1183
wait,1184
wait_for,1185,1186
Cross references 1324
c
ISO/IEC N????
wait_until,1184,1185
condition_variable_any
constructor, 1187
destructor, 1187
notify_all,1188
notify_one,1188
wait,1188
wait_for,1189
wait_until,1188,1189
conj,924
complex,922
const_mem_fun1_ref_t,1262
const_mem_fun1_t,1262
const_mem_fun_ref_t,1262
const_mem_fun_t,1262
const_pointer
allocator_traits,529
const_pointer_cast
shared_ptr,555
const_void_pointer
allocator_traits,529
construct
scoped_allocator_adaptor,626628
converted
wstring_convert,685
copy,889
basic_string,658
copy_backward,890
copy_n,889
copyfmt
basic_ios,1016
copysign,993
cos,982,993
complex,923
cosh,982,993
complex,923
count,886
bitset,518
duration,613
count_if,886
cout,1002
crbegin
basic_string,649
crbegin(const C& c),872
cref
reference_wrapper,569
crend
basic_string,649
crend(const C& c),872
<csetjmp>,430,463,464
cshift
valarray,979
<csignal>,463,464
<cstdalign>,464
<cstdarg>,430,463,464
<cstdbool>,463,464
<cstddef>,1245,1247
<cstdint>,446
<cstdio>,10011003,1072,1075,1076,1245
<cstdlib>,419,463,464,1245,1248
<cstring>,416,1245,1247,1252,1257
<ctgmath>,993
<ctime>,463,464,676,1245
ctype,689
do_is,691
do_narrow,692
do_scan_not,691
do_tolower,692
do_toupper,691
do_widen,692
is,690
narrow,691
scan_is,690
scan_not,690
tolower,691
toupper,690
widen,691
ctype<char>,693
classic_table,695
constructor, 694
ctype<char>,694
destructor, 694
do_narrow,695
do_tolower,695
do_toupper,695
do_widen,695
is,694
narrow,695
scan_is,694
scan_not,694
table,695
tolower,695
toupper,695
widen,695
ctype_base,689
do_scan_is,691
ctype_byname,693
<cuchar>,430
curr_symbol
moneypunct,723
current_exception,461
<cwchar>,430,1245,1247
Cross references 1325
c
ISO/IEC N????
data
basic_string,659
array,764
dynarray,772
vector,791
date_order
time_get,714
DBL_DIG,446
DBL_EPSILON,446
DBL_MANT_DIG,446
DBL_MAX,446
DBL_MAX_10_EXP,446
DBL_MAX_EXP,446
DBL_MIN,446
DBL_MIN_10_EXP,446
DBL_MIN_EXP,446
deallocate
allocator,532
allocator_traits,530
scoped_allocator_adaptor,626
dec,1021,1052
DECIMAL_DIG,446
decimal_point
moneypunct,723
numpunct,710
declare_no_pointers,526
declare_reachable,525
declval,487
default_delete
default_delete,537
operator(),537
default_error_condition
error_category,474,475
error_code,477
default_random_engine,944
defaultfloat,1021
defer_lock,1170
defer_lock_t,1170
delete
operator,535
operator,430,451,452
denorm_absent,444
denorm_indeterminate,444
denorm_min
numeric_limits,442
denorm_present,444
densities
piecewise_constant_distribution,966
piecewise_linear_distribution,968
<deque>,760
deque,765
deque,768
shrink_to_fit,768
swap,769
detach
thread,1160
difference_type
allocator_traits,529
pointer_traits,525
digits
numeric_limits,439
digits10
numeric_limits,439
discard_block_engine,940
constructor, 941
discrete_distribution,963
constructor, 964
probabilities,964
distance,850
div,993
divides,569
divides<>,571
do_always_noconv
codecvt,699
do_close
message,726
do_compare
collate,712
do_curr_symbol
moneypunct,724
do_date_order
time_get,715
do_decimal_point
moneypunct,724
numpunct,710
do_encoding
codecvt,699
do_falsename
numpunct,711
do_frac_digits
moneypunct,724
do_get
messages,726
money_get,720
num_get,702,704
time_get,717
do_get_date
time_get,716
do_get_monthname
time_get,716
do_get_time
time_get,716
Cross references 1326
c
ISO/IEC N????
do_get_weekday
time_get,716
do_get_year
time_get,716
do_grouping
moneypunct,724
numpunct,710
do_hash
collate,712
do_in
codecvt,698
do_is
ctype,691
do_length
codecvt,699
do_max_length
codecvt,700
do_narrow,695
ctype,692
ctype<char>,695
do_neg_format
moneypunct,724
do_negative_sign
moneypunct,724
do_open
messages,726
do_out
codecvt,698
do_pos_format
moneypunct,724
do_positive_sign
moneypunct,724
do_put
money_put,721
num_put,706,708
time_put,718
do_scan_is
ctype_base,691
do_scan_not
ctype,691
do_thousands_sep
moneypunct,724
numpunct,710
do_tolower
ctype,692
ctype<char>,695
do_toupper
ctype,691
ctype<char>,695
do_transform
collate,712
do_truename
numpunct,711
do_unshift
codecvt,698
do_widen,695
ctype,692
ctype<char>,695
domain_error,466,467
domain_error,467
duration
constructor, 612
count,613
max,614
min,614
operator!=,616
operator*,615
operator*=,614
operator+,613,619
operator++,613
operator+=,613
operator-,613,619
operator-=,613
operator--,613
operator/,615
operator/=,614
operator<,616
operator<=,616
operator==,616
operator>=,616
operator%,615
operator%=,614
zero,614
duration_cast,616
duration_values,610
max,610
min,610
zero,610
dynamic_pointer_cast
shared_ptr,555
<dynarray>,761
dynarray,770
data,772
destructor, 772
dynarray,771,772
fill,772
eback
basic_streambuf,1028
egptr
basic_streambuf,1028
element_type
Cross references 1327
c
ISO/IEC N????
pointer_traits,525
emplace
optional,508
priority_queue,835
emplace_after
forward_list,777
emplace_front
forward_list,776
empty,849
basic_string,651
match_results,1119
enable_shared_from_this,559
constructor, 559
destructor, 559
operator=,559
shared_from_this,559
encoding
codecvt,697
end,462
array,763
basic_string,649
initializer_list,463
match_results,1120
valarray,990
end(C&),871
end(initializer_list<E>),463
end(T (&)[N]),871
endl,1052,1055
ends,1055
entropy
random_device,945
eof
basic_ios,1018
epptr
basic_streambuf,1028
epsilon
numeric_limits,440
eq
char_traits,659662
equal,887
istreambuf_iterator,869
equal_range,901
equal_to,571
equal_to<>,572
equivalent
error_category,474,475
erase
deque,769
list,784
basic_string,656
vector,791
erase_after
forward_list,777
erased
forward_list,777
erf,993
erfc,993
errc,470
error_category,470,473
constructor, 474
default_error_condition,474,475
destructor, 474
equivalent,474,475
message,474
name,474,475
operator!=,474
operator<,474
operator==,474
error_code,470,475,478
assign,477
category,477
clear,477
default_error_condition,477
error_code,476
message,477
operator bool,477
operator!=,480
operator<,477
operator<<,477
operator=,477
operator==,480
value,477
error_condition,470
assign,479
category,479
clear,479
constructor, 478
message,479
operator bool,479
operator!=,480
operator<,479
operator=,479
operator==,480
value,479
error_type,1100,1101
exception
bad_function_call,579
bad_weak_ptr,546
<exception>,457
exception,458
constructor, 458
destructor, 458
Cross references 1328
c
ISO/IEC N????
exception_ptr,460
exceptions
basic_ios,1019
exchange
atomic type,1147
exit,59,61,132,419,448,455
EXIT_FAILURE,448
EXIT_SUCCESS,448
exp,982,993
complex,923
exp2,993
expired
weak_ptr,557
expm1,993
exponential_distribution,954
constructor, 955
lambda,955
extreme_value_distribution,957
a,957
b,958
constructor, 957
facet
locale,680
fail
basic_ios,1018
failed
ostreambuf_iterator,871
failure
ios_base::failure,1007
falsename
numpunct,710
fclose,1076
fdim,993
FE_ALL_EXCEPT,913
FE_DFL_ENV,913
FE_DIVBYZERO,913
FE_DOWNWARD,913
FE_INEXACT,913
FE_INVALID,913
FE_OVERFLOW,913
FE_TONEAREST,913
FE_TOWARDZERO,913
FE_UNDERFLOW,913
FE_UPWARD,913
feclearexcept,913
fegetenv,913
fegetexceptflag,913
fegetround,913
feholdexcept,913
fenv_t,913
feraiseexcept,913
fesetenv,913
fesetexceptflag,913
fesetround,913
fetch_
atomic type,1149
fetestexcept,913
feupdateenv,913
fexcept_t,913
filebuf,999,1072
fill,892
array,764
basic_ios,1016
dynarray,772
gslice_array,987
indirect_array,990
mask_array,988
slice_array,984
fill_n,892
find,885
basic_string,659
map,801
multimap,805
find_end,885
find_first_not_of
basic_string,661,662
find_first_of,885
basic_string,660
find_if,885
find_if_not,885
find_last_not_of
basic_string,662
find_last_of
basic_string,661
fisher_f_distribution,961
constructor, 962
m,962
n,962
fixed,1021
flag_type
basic_regex,1109
flags
ios_base,689,1009
flip
bitset,517
bitset,517
vector<bool>,794
float_denorm_style,437,444
numeric_limits,442
float_round_style,437,443
floor,993
Cross references 1329
c
ISO/IEC N????
FLT_DIG,446
FLT_EPSILON,446
FLT_EVAL_METHOD,446
FLT_MANT_DIG,446
FLT_MAX,446
FLT_MAX_10_EXP,446
FLT_MAX_EXP,446
FLT_MIN,446
FLT_MIN_10_EXP,446
FLT_MIN_EXP,446
FLT_RADIX,446
FLT_ROUNDS,446
flush,1009,1036,1050,1055
basic_ostream,1055
fma,993
fmax,993
fmin,993
fmtflags
ios,1056
ios_base,1007,1009
fopen,1075
for_each,884
format
match_results,1120
format_default,1098
format_default,1099
format_first_only,1098,1125
format_first_only,1100
format_no_copy,1098,1125
format_no_copy,1100
format_sed,1098
format_sed,1099
forward,485
forward_as_tuple,498
forward_iterator_tag,849
<forward_list>,761
forward_list
before_begin,776
cbefore_begin,776
clear,778
emplace_after,777
emplace_front,776
erase_after,777
erased,777
forward_list,775
front,776
insert_after,776,777
merge,779
pop,776
push_front,776
remove,779
remove_if,779
resize,777
reverse,780
sort,779
splice_after,778
swap,780
unique,779
fpclassify,997
fpos,1004,1012,1013
state,1013
frac_digits
moneypunct,723
free,535
freeze
ostrstream,1258
strstream,1259
strstreambuf,1253
frexp,993
from_bytes
wstring_convert,685
from_time_t,621
front
basic_string,651
forward_list,776
front_insert_iterator,857
front_insert_iterator,857
front_inserter,858
fseek,1075
<fstream>,1072
fstream,999
function,579
assign,582
bool conversion, 583
destructor, 582
function,581
invocation, 583
operator!=,583
operator(),583
operator=,582
operator==,583
swap,582,583
target,583
target_type,583
<functional>,562
future
constructor, 1196,1197
get,1197
operator=,1197
share,1197
valid,1197
wait,1197
Cross references 1330
c
ISO/IEC N????
wait_for,1198
wait_until,1198
future_category,1191
future_errc
make_error_code,1191
make_error_condition,1191
future_error
code,1191
what,1192
gamma_distribution,955
alpha,956
beta,956
constructor, 956
gbump
basic_streambuf,1028
gcount
basic_istream,1040
generate,892
seed_seq,946
generate_canonical,947
generate_n,892
generic_category,473,475
geometric_distribution,952
constructor, 952
p,952
get
array,765
auto_ptr,1266
basic_istream,1041,1042,1045
future,1197
messages,726
money_get,719
num_get,702
pair,491,492
reference_wrapper,568
shared_future,1200
shared_ptr,552
time_get,715
tuple,500
unique_ptr,542
get_allocator
basic_string,659
match_results,1121
get_date
time_get,714
get_deleter
shared_ptr,556
unique_ptr,542
get_future
packaged_task,1204
promise,1194
get_id
this_thread,1161
thread,1160
get_money,1058
get_monthname
time_get,714
get_new_handler,431
get_pointer_safety,526
get_temporary_buffer,533
get_terminate,431
get_time,1058
time_get,714
get_unexpected,431
get_weekday
time_get,714
get_year
time_get,714
getenv,463,464
getline
basic_istream,1042,1043
basic_string,668,669
getloc,1103
basic_regex,1109
basic_streambuf,1026
ios_base,1010
global
locale,683
good
basic_ios,1018
gptr
basic_streambuf,1028
greater,571
greater<>,572
greater_equal,572
greater_equal<>,573
grouping
moneypunct,723
numpunct,710
gslice,984
constructor, 986
gslice_array,986
hardware_concurrency
thread,1160
has_denorm_loss
numeric_limits,442
has_facet
locale,683
has_infinity
numeric_limits,441
Cross references 1331
c
ISO/IEC N????
has_quiet_NaN
numeric_limits,441
has_signaling_NaN
numeric_limits,441
hash,480,512,562,584,630,671
collate,712
hash_code,519
type_info,456
type_index,630
hex,1021
hexfloat,1021
hypot,993
id
locale,680
idxl
operator>,616
ifstream,999,1072
ignore
basic_istream,1043
ilogb,993
imag,924
complex,918,921
imbue,1103
basic_filebuf,1078
basic_ios,1016
basic_regex,1109
basic_streambuf,1028
ios_base,1010
in
codecvt,697
in_avail
basic_streambuf,1026
in_place,510
in_place_t,510
includes,903
independent_bits_engine,941
indirect_array,988
operator[],989
infinity
numeric_limits,442
Init
ios_base::Init,1009
init
basic_ios,1015,1035,1049
<initializer_list>,462
initializer_list,462
begin,463
end,463
initializer_list,463
size,463
inner_allocator
scoped_allocator_adaptor,626
inner_allocator_type
scoped_allocator_adaptor,624
inner_product,991
inplace_merge,902
input_iterator_tag,849
emplace
deque,769
insert
deque,769
list,784
basic_string,654,655
map,801
multimap,805
unordered_map,818
unordered_multimap,821
vector,791
push_back
deque,769
push_front
deque,769
insert_after
forward_list,776,777
insert_iterator,858
insert_iterator,859
inserter,859
int16_t,446
int32_t,446
int64_t,446
int8_t,446
int_fast16_t,446
int_fast32_t,446
int_fast64_t,446
int_fast8_t,446
int_least16_t,446
int_least32_t,446
int_least64_t,446
int_least8_t,446
INT_MAX,446
INT_MIN,446
int_type
char_traits,633
wstring_convert,686
integer_sequence,502
internal,1020
intervals
piecewise_constant_distribution,966
piecewise_linear_distribution,968
intmax_t,446
intptr_t,446
Cross references 1332
c
ISO/IEC N????
invalid_argument,466,467,514,515
invalid_argument,467
INVOKE ,566
<iomanip>,1033
<ios>,1003
ios,999,1004
ios_base,1004
destructor, 1012
fmtflags,1009
ios_base,1012
iostate,1007
precision,1010
setf,1010
streamsize,1010
ios_base::failure,1007
ios_base::Init,1009
destructor, 1009
<iosfwd>,999
iostate
ios_base,1007
<iostream>,1001
iostream_category,1022
iota,993
is
ctype,690
ctype<char>,694
is_bind_expression,576
is_bounded
numeric_limits,443
is_error_code_enum,470
is_error_condition_enum,470
is_exact
numeric_limits,440
is_heap,907
is_heap_until,907
is_iec559
numeric_limits,442
is_integer
numeric_limits,440
is_modulo
numeric_limits,443
is_open
basic_filebuf,1075,1085
basic_ifstream,1081
basic_ofstream,1083
is_partitioned,896
is_permutation,888
is_placeholder,577
is_signed
numeric_limits,440
is_sorted,900
is_sorted_until,900
isalnum,683
isalpha,683
isblank,683
iscntrl,683
isctype
regex_traits,1103
regular expression traits, 1133
isdigit,683
isfinite,997
isgraph,683
isgreater,997
isgreaterequal,997
isinf,997
isless,997
islessequal,997
islessgreater,997
islower,683
isnan,997
isnormal,997
<iso646.h>,1245
isprint,683
ispunct,683
isspace,683
<istream>,1032
istream,999,1032
istream_iterator,864
constructor, 865
destructor, 865
operator!=,866
operator*,865
operator++,866
operator->,865
operator==,866
istreambuf_iterator,868
constructor, 869
operator++,869
istringstream,999,1061
istrstream,1256
constructor, 1256
istrstream,1256
isunordered,997
isupper,683
isxdigit,683
iter_swap,891
<iterator>,844
iword
ios_base,1011
jmp_buf,464
join
Cross references 1333
c
ISO/IEC N????
thread,1159
joinable
thread,1159
kill_dependency,1140
knuth_b,944
lambda
exponential_distribution,955
LDBL_DIG,446
LDBL_EPSILON,446
LDBL_MANT_DIG,446
LDBL_MAX,446
LDBL_MAX_10_EXP,446
LDBL_MAX_EXP,446
LDBL_MIN,446
LDBL_MIN_10_EXP,446
LDBL_MIN_EXP,446
left,1020
length
char_traits,646,648,654,665
basic_string,649
codecvt,697
match_results,1119
regex_traits,1102
sub_match,1110
valarray,978
length_error,466,468,641
length_error,468
less,572
less<>,573
less_equal,572
less_equal<>,573
lexicographical_compare,909
lgamma,993
<limits>,437
linear_congruential_engine,936
constructor, 936
<list>,761
list,780
list,783
splice,785
swap,787
LLONG_MAX,446
LLONG_MIN,446
llrint,993
llround,993
load
atomic type,1147
<locale>,675,676
locale,1103,1109,1132
category,678
classic,683
combine,682
constructor, 681
destructor, 682
facet,680
global,683
has_facet,683
id,680
name,682
operator!=,682
operator(),682
operator=,682
operators==,682
use_facet,683
lock,1180
shared_lock,1178
unique_lock,1174
weak_ptr,558
lock_guard
constructor, 1171
destructor, 1171
log,982,993
complex,923
log10,982,993
complex,923
log1p,993
log2,993
logb,993
logic_error,466
logic_error,467
logical_and,573
logical_and<>,574
logical_not,574
logical_not<>,574
logical_or,573
logical_or<>,574
lognormal_distribution,959
constructor, 959
m,959
s,959
LONG_MAX,446
longjmp,464
lookup_classname
regex_traits,1102
regular expression traits, 1133
lookup_collatename
regex_traits,1102
regular expression traits, 1133
lower_bound,900
lowest
Cross references 1334
c
ISO/IEC N????
numeric_limits,439
lrint,993
lround,993
m
fisher_f_distribution,962
lognormal_distribution,959
make_error_code,470,477,1022
future_errc,1191
make_error_condition,470,479,1022
future_errc,1191
make_exception_ptr,461
make_heap,906
make_integer_sequence,503
make_move_iterator,864
make_optional,512
make_pair,490
make_ready_at_thread_exit
packaged_task,1205
make_shared,553
make_tuple,498
make_unique,544
malloc,535,1247
<map>,794
map,796
constructor, 800
find,801
insert,801
map,800
operator<,800
operator==,800
swap,801
mark_count
basic_regex,1109
mask_array,987
operator[],988
match_any,1098
match_any,1099
match_continuous,1098,1128
match_continuous,1099
match_default,1098
match_flag_type,1098,1099,1134
match_not_bol,1098
match_not_bol,1099
match_not_bow,1098
match_not_bow,1099
match_not_eol,1098
match_not_eol,1099
match_not_eow,1098
match_not_eow,1099
match_not_null,1098,1128
match_not_null,1099
match_prev_avail,1098,1128
match_prev_avail,1099
match_results,1116,1126,1129
begin,1120
empty,1119
end,1120
format,1120
get_allocator,1121
length,1119
match_results,1118
matched,1116
max_size,1119
operator!=,1121
operator=,1118
operator==,1121
operator[],1119
position,1119
prefix,1119
size,1119
state,1118
str,1119
suffix,1119
swap,1121
max,907,908
duration,614
duration_values,610
numeric_limits,439
time_point,619
valarray,979
max_align_t,436,437
max_digits10
numeric_limits,440
max_element,909
max_exponent
numeric_limits,441
max_exponent10
numeric_limits,441
max_length
codecvt,697
max_size
allocator,532
allocator_traits,530
array,763
basic_string,650
match_results,1119
scoped_allocator_adaptor,626
MB_LEN_MAX,446
mean
normal_distribution,958
poisson_distribution,954
Cross references 1335
c
ISO/IEC N????
student_t_distribution,963
mem_fn,578
mem_fun,1261,1262
mem_fun1_ref_t,1261
mem_fun1_t,1261
mem_fun_ref,1261,1263
mem_fun_ref_t,1261
mem_fun_t,1261
memchr,672
<memory>,520
merge,902
list,786
forward_list,779
mersenne_twister_engine,937
constructor, 938
message
do_close,726
error_category,474
error_code,477
error_condition,479
messages,725
close,726
do_get,726
do_open,726
get,726
open,725
messages_byname,726
min,907
duration,614
duration_values,610
numeric_limits,439
time_point,619
valarray,979
min_element,908
min_exponent
numeric_limits,440
min_exponent10
numeric_limits,441
minmax,908
minmax_element,909
minstd_rand,943
minstd_rand0,943
minus,569
minus<>,570
mismatch,886
mod,993
modf,993
modulus,570
modulus<>,571
money_get,719
do_get,720
get,719
money_put,721
do_put,721
put,721
moneypunct,722
curr_symbol,723
decimal_point,723
do_curr_symbol,724
do_decimal_point,724
do_frac_digits,724
do_grouping,724
do_neg_format,724
do_negative_sign,724
do_pos_format,724
do_positive_sign,724
do_thousands_sep,724
frac_digits,723
grouping,723
negative_sign,723
positive_sign,723
thousands_sep,723
moneypunct_byname,725
move,486
basic_ios,1017
movemove,890
move_backward,890
move_if_noexcept,486
move_iterator,860
base,862
constructor, 861
move_iterator,861
operator!=,863
operator*,862
operator+,862,864
operator++,862
operator+=,862
operator-,863,864
operator-=,863
operator->,862
operator--,862
operator<,863
operator<=,863
operator=,861
operator==,863
operator>,863
operator>=,863
operator[],863
mt19937,943
mt19937_64,943
multimap,801
find,805
Cross references 1336
c
ISO/IEC N????
insert,805
multimap,804
operator<,804
operator==,804
swap,805
multiplies,569
multiplies<>,570
multiset,809
multiset,811,812
operator<,811
operator==,811
swap,812
<mutex>,1161
mutex
shared_lock,1179
unique_lock,1175
n
chi_squared_distribution,960
fisher_f_distribution,962
name
type_info,456
error_category,474,475
locale,682
type_index,630
nan,993
narrow
basic_ios,1016
ctype,691
ctype<char>,695
NDEBUG,419
nearbyint,993
negate,570
negate<>,571
negative_binomial_distribution,952
constructor, 953
p,953
t,953
negative_sign
moneypunct,723
nested_exception,461
nested_exception,461
nested_ptr,462
rethrow_if_nested,462
rethrow_nested,462
throw_with_nested,462
nested_ptr
nested_exception,462
<new>,449
new
operator,450,453
operator,430,450453,535
new_handler,455
next,850
next_permutation,910
nextafter,993
nexttoward,993
noboolalpha,1019
none
bitset,518
none_of,884
norm,924
complex,921
normal_distribution,958
constructor, 958
mean,958
stddev,959
noshowbase,1019
noshowpoint,1019
noshowpos,1020
noskipws,1020
not1,576
not2,576
not_equal_to,571
not_equal_to<>,572
notify_all
condition_variable,1183
condition_variable_any,1188
notify_one
condition_variable,1183
condition_variable_any,1188
nounitbuf,1020
nouppercase,1020
nth_element,900
NULL,436,437
nullopt,511
nullopt_t,511
nullptr_t,436,437
num_get,700
do_get,702,704
get,702
num_put,705
do_put,706,708
put,706
<numeric>,990
numeric_limits,438
numeric_limits,437
denorm_min,442
digits,439
digits10,439
epsilon,440
float_denorm_style,442
Cross references 1337
c
ISO/IEC N????
has_denorm_loss,442
has_infinity,441
has_quiet_NaN,441
has_signaling_NaN,441
infinity,442
is_bounded,443
is_exact,440
is_iec559,442
is_integer,440
is_modulo,443
is_signed,440
lowest,439
max,439
max_digits10,440
max_exponent,441
max_exponent10,441
min,439
min_exponent,440
min_exponent10,441
quiet_NaN,442
radix,440
round_error,440
round_style,443
signaling_NaN,442
tinyness_before,443
traps,443
numeric_limits<bool>,445
numpunct,709
decimal_point,710
do_decimal_point,710
do_falsename,711
do_grouping,710
do_thousands_sep,710
do_truename,711
falsename,710
grouping,710
thousands_sep,710
truename,710
numpunct_byname,711
oct,1021
off_type
char_traits,633
offsetof,436,437,1247
ofstream,999,1072
once_flag,1180
open
basic_filebuf,1075,1085
basic_ifstream,1081
basic_ofstream,1083
messages,725
openmode
ios_base,1007
operator @=
atomic type,1149
operator auto_ptr
auto_ptr_ref,1266
operator basic_string
sub_match,1110
operator bool
basic_istream,1037
basic_ios,1018
basic_ostream,1050
error_code,477
error_condition,479
optional,510
shared_lock,1179
shared_ptr,553
unique_lock,1175
unique_ptr,542
operator C
atomic type,1147
operator T&
reference_wrapper,568
operator!
basic_ios,1018
valarray,977
operator!=,484
pair,490
type_info,456
allocator,532
basic_string,666
bitset,518
complex,920
duration,616
error_category,474
error_code,480
error_condition,480
function,583
istream_iterator,866
istreambuf_iterator,870
locale,682
match_results,1121
move_iterator,863
queue,831
regex_iterator,1128
regex_token_iterator,1132
reverse_iterator,855
scoped_allocator_adaptor,628
shared_ptr,554
stack,837
sub_match,11101115
Cross references 1338
c
ISO/IEC N????
thread::id,1158
time_point,620
tuple,501
type_index,629
unique_ptr,545
valarray,981
operator()
default_delete,537
function,583
locale,682
packaged_task,1205
random_device,945
reference_wrapper,568
operator*
auto_ptr,1266
back_insert_iterator,857
complex,920
duration,615
front_insert_iterator,858
insert_iterator,859
istream_iterator,865
istreambuf_iterator,869
move_iterator,862
optional,509
ostream_iterator,867
ostreambuf_iterator,871
raw_storage_iterator,533
regex_iterator,1128
regex_token_iterator,1132
reverse_iterator,853
shared_ptr,552
unique_ptr,542
valarray,980
operator*=
complex,919
duration,614
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator+
basic_string,663665
complex,919
duration,613,619
move_iterator,862,864
reverse_iterator,854,855
time_point,619
valarray,977,980
operator++
atomic type,1150
back_insert_iterator,857
duration,613
front_insert_iterator,858
insert_iterator,859
istream_iterator,866
istreambuf_iterator,869
move_iterator,862
ostream_iterator,867
ostreambuf_iterator,871
raw_storage_iterator,533
regex_iterator,1128,1129
regex_token_iterator,1132
reverse_iterator,853
operator+=
basic_string,651,652
complex,918,919
duration,613
gslice_array,987
indirect_array,989
mask_array,988
move_iterator,862
reverse_iterator,854
slice_array,984
time_point,619
valarray,978
operator-
complex,920
duration,613,619
move_iterator,863,864
reverse_iterator,854,855
time_point,619,620
valarray,977,980
operator-=
complex,919
duration,613
gslice_array,987
indirect_array,989
mask_array,988
move_iterator,863
reverse_iterator,854
slice_array,984
time_point,619
valarray,978
operator->
auto_ptr,1266
istream_iterator,865
move_iterator,862
optional,509
regex_iterator,1128
regex_token_iterator,1132
reverse_iterator,853
Cross references 1339
c
ISO/IEC N????
shared_ptr,552
unique_ptr,542
operator--
atomic type,1150
duration,613
move_iterator,862
reverse_iterator,854
operator/
complex,920
duration,615
valarray,980
operator/=
complex,919
duration,614
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator<
pair,490
basic_string,666
duration,616
error_category,474
error_code,477
error_condition,479
move_iterator,863
optional,511,512
queue,832
reverse_iterator,855
shared_ptr,554
stack,837
sub_match,1111,11131115
thread::id,1158
time_point,620
tuple,501
type_index,629
unique_ptr,545,546
valarray,981
operator«
shared_ptr,556
sub_match,1116
operator<<
bitset,518,520
complex,921
operator<<=
bitset,516
operator<=,484
pair,490
basic_string,667
duration,616
move_iterator,863
queue,832
reverse_iterator,855
shared_ptr,545,554
stack,838
sub_match,11111115
thread::id,1158
time_point,620
tuple,501
type_index,629
unique_ptr,546
valarray,981
operator<<
basic_istream,1047
basic_ostream,10511053,1055
basic_string,668
error_code,477
thread::id,1158
valarray,980
operator<<=
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator=
bad_alloc,454
bad_cast,456
bad_exception,459
bad_typeid,457
reverse_iterator,853
atomic type,1147
auto_ptr,1265
auto_ptr_ref,1266
back_insert_iterator,856,857
basic_filebuf,1074
basic_fstream,1085
basic_ifstream,1080
basic_iostream,1046
basic_istream,1036
basic_istringstream,1067
basic_ofstream,1082
basic_ostream,1049
basic_ostringstream,1069
basic_regex,1107
basic_streambuf,1027
basic_string,648,649
basic_stringbuf,1063
basic_stringstream,1071
enable_shared_from_this,559
error_code,477
Cross references 1340
c
ISO/IEC N????
error_condition,479
exception,458
front_insert_iterator,858
function,582
future,1197
gslice_array,987
indirect_array,989
insert_iterator,859
locale,682
mask_array,988
match_results,1118
move_iterator,861
optional,507,508
ostream_iterator,867
ostreambuf_iterator,871
packaged_task,1204
pair,489
promise,1194
raw_storage_iterator,533
reference_wrapper,568
shared_future,1199,1200
shared_ptr,551,552
slice_array,984
thread,1159
tuple,497,498
unique_lock,1173
unique_ptr,541,542
valarray,974,975,980
weak_ptr,557
operator==
pair,490
type_info,456
allocator,532
basic_string,665
bitset,518
complex,920
duration,616
error_category,474
error_code,480
error_condition,480
function,583
istream_iterator,866
istreambuf_iterator,870
match_results,1121
move_iterator,863
optional,511,512
queue,831
regex_iterator,1128
regex_token_iterator,1129,1131
reverse_iterator,854
scoped_allocator_adaptor,628
shared_ptr,554
stack,837
sub_match,11101115
thread::id,1157
time_point,620
tuple,501
type_index,629
unique_ptr,545
valarray,981
operator>,484
pair,490
basic_string,666,667
idxl,616
move_iterator,863
queue,832
reverse_iterator,855
shared_ptr,554
stack,838
sub_match,11111115
thread::id,1158
time_point,620
tuple,501
type_index,630
unique_ptr,545,546
valarray,981
operator>=,485
pair,490
basic_string,667
duration,616
move_iterator,863
queue,832
reverse_iterator,855
shared_ptr,555
stack,838
sub_match,11111115
thread::id,1158
time_point,620
tuple,502
type_index,630
unique_ptr,545,546
valarray,981
operator>>
bitset,518,519
complex,920
operator>>=
bitset,516
operator>>
basic_istream,1039
basic_string,668
istream,10371040
valarray,980
Cross references 1341
c
ISO/IEC N????
operator>>=
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator[]
basic_string,651
bitset,519
indirect_array,989
map,800
mask_array,988
match_results,1119
move_iterator,863
reverse_iterator,854
unique_ptr,544
unordered_map,817
valarray,975977
operator%
duration,615
valarray,980
operator%=
duration,614
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator&
bitset,519
valarray,980
operator&=
bitset,516
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator&&
valarray,980,981
operatorˆ
bitset,519
valarray,980
operatorˆ=
bitset,516
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator˜
bitset,517
valarray,977
operators==
locale,682
operator|
bitset,519
valarray,980
operator|=
bitset,516
gslice_array,987
indirect_array,989
mask_array,988
slice_array,984
valarray,978
operator||
valarray,980,981
<optional>,503
optional,503
constructor, 505,506
destructor, 507
emplace,508
operator bool,510
operator*,509
operator->,509
operator<,511,512
operator=,507,508
operator==,511,512
swap,509,512
value,510
value_or,510
<ostream>,1032
ostream,999,1033
ostream_iterator,866
constructor, 867
destructor, 867
operator*,867
operator++,867
operator=,867
ostreambuf_iterator,870
constructor, 870
ostringstream,999,1061
ostrstream,1257
constructor, 1257
ostrstream,1257
out
codecvt,697
out_of_range,468,514518,641
out_of_range,468
out_of_range_error,466
outer_allocator
scoped_allocator_adaptor,626
Cross references 1342
c
ISO/IEC N????
output_iterator_tag,849
overflow
basic_filebuf,1077
basic_streambuf,1031
basic_stringbuf,1064
strstreambuf,1253
overflow_error,466,469,470,515,517
overflow_error,469
owner_before
shared_ptr,553,558
owns_lock
shared_lock,1179
unique_lock,1175
p
bernoulli_distribution,951
binomial_distribution,951
geometric_distribution,952
negative_binomial_distribution,953
packaged_task
constructor, 1203,1204
destructor, 1204
get_future,1204
make_ready_at_thread_exit,1205
operator(),1205
operator=,1204
reset,1205
swap,1204,1206
valid,1204
pair,487,496498
get,491,492
operator=,489
pair,488
swap,489
param
seed_seq,947
partial_sort,899
partial_sort_copy,899
partial_sum,992
partition,896
partition_copy,897
partition_point,897
pbackfail
basic_filebuf,1076
basic_streambuf,1031
basic_stringbuf,1064
strstreambuf,1254
pbase
basic_streambuf,1028
pbump
basic_streambuf,1028
pcount
ostrstream,1258
strstream,1259
strstreambuf,1253
peek
basic_istream,1043
piecewise_constant_distribution,965
constructor, 965,966
densities,966
intervals,966
piecewise_construct,492
piecewise_construct_t,492
piecewise_linear_distribution,967
constructor, 967,968
densities,968
intervals,968
placeholders,578
plus,569
plus<>,570
pointer
allocator_traits,528
pointer_to
pointer_traits,525
pointer_to_binary_function,1260
pointer_to_unary_function,1260
pointer_traits,524
difference_type,525
element_type,525
pointer_to,525
rebind,525
poisson_distribution,953
constructor, 954
mean,954
polar
complex,922
pop
priority_queue,835
forward_list,776
pop_back
basic_string,656
pop_heap,906
pos_type
char_traits,633
position
match_results,1119
positive_sign
moneypunct,723
pow,924,982,993
complex,923
pptr
basic_streambuf,1028
Cross references 1343
c
ISO/IEC N????
precision
ios_base,689,1010
prefix
match_results,1119
prev,850
prev_permutation,910
priority_queue,832
emplace,835
priority_queue,833
swap,835
probabilities
discrete_distribution,964
proj
complex,922
promise
constructor, 1194
destructor, 1194
get_future,1194
operator=,1194
set_exception,1195
set_exception_at_thread_exit,1195
set_value,1194
set_value_at_thread_exit,1195
swap,1194,1195
propagate_on_container_copy_assignment
allocator_traits,529
scoped_allocator_adaptor,624
propagate_on_container_move_assignment
allocator_traits,529
scoped_allocator_adaptor,624
propagate_on_container_swap
allocator_traits,529
scoped_allocator_adaptor,624
proxy
istreambuf_iterator,868
ptr_fun,1260
ptrdiff_t,436
pubimbue
basic_streambuf,1025
pubseekoff
basic_streambuf,1026
pubseekpos
basic_streambuf,1026
pubsetbuf
basic_streambuf,1026
pubsync
basic_streambuf,1026
push
priority_queue,834
push_back
basic_string,653
push_front
forward_list,776
push_heap,906
put
basic_ostream,1054
money_put,721
num_put,706
time_put,718
put_money,1058
put_time,1059
putback
basic_istream,1044
putenv,464
pword
ios_base,1012
<queue>,829
queue,829
swap,832
quick_exit,448,449
quiet_NaN
numeric_limits,442
quoted,1060
radix
numeric_limits,440
raise,464
<random>,933935
random_access_iterator_tag,849
random_device,944
constructor, 945
entropy,945
operator(),945
random_shuffle,895
range_error,466,469
range_error,469
ranlux24,944
ranlux24_base,943
ranlux48,944
ranlux48_base,943
ratio,603
ratio_equal,605
ratio_greater,606
ratio_greater_equal,606
ratio_less,605
ratio_less_equal,606
ratio_not_equal,605
raw_storage_iterator
constructor, 533
operator*,533
operator++,533
Cross references 1344
c
ISO/IEC N????
operator=,533
rbegin
basic_string,649
rbegin(C&),872
rbegin(initializer_list<E>),872
rbegin(T (&array)[N]),872
rdbuf
basic_filebuf,1085
basic_ifstream,1081
basic_ios,1016
basic_istringstream,1068
basic_ofstream,1083
basic_ostringstream,1069
basic_stringstream,1071
istrstream,1257
ostrstream,1258
strstream,1259
wbuffer_convert,688
rdstate
basic_ios,1018
read
basic_istream,1043
readsome
basic_istream,1044
real,924
complex,918,921
realloc,535,1247
rebind
pointer_traits,525
rebind_alloc
allocator_traits,529
ref
reference_wrapper,569
reference_wrapper,567
cref,569
get,568
operator T&,568
operator(),568
operator=,568
ref,569
reference_wrapper,568
<regex>,1091
regex,1091
regex_constants,1097
error_type,1100,1101
match_flag_type,1098
syntax_option_type,1097
regex_error,1101,1104,1134
constructor, 1101
regex_iterator,1126
increment, 1128
operator!=,1128
operator*,1128
operator++,1128,1129
operator->,1128
operator==,1128
regex_iterator,1127,1128
regex_match,1122,1123
regex_replace,1125,1126
regex_search,11231125
regex_token_iterator,1129
end-of-sequence, 1129
operator!=,1132
operator*,1132
operator++,1132
operator->,1132
operator==,1129,1131
regex_token_iterator,1131
regex_traits,1101
char_class_type,1102
isctype,1103
length,1102
lookup_classname,1102
lookup_collatename,1102
transform,1102
transform_primary,1102
translate,1102
translate_nocase,1102
value,1103
register_callback
ios_base,1012
regular expression traits
isctype,1133
lookup_classname,1133
lookup_collatename,1133
transform_primary,1133
rel_ops,482
release
auto_ptr,1266
shared_lock,1179
unique_lock,1175
unique_ptr,542
remainder,993
remove,893
list,785
forward_list,779
remove_copy,893
remove_copy_if,893
remove_if,893
forward_list,779
remquo,993
rend
Cross references 1345
c
ISO/IEC N????
basic_string,649
rend(const C&),872
rend(initializer_list<E>),872
rend(T (&array)[N]),872
rep
system_clock,621
replace,891
basic_string,656658
replace_copy,892
replace_copy_if,892
replace_if,891
reserve
basic_string,650
vector,790
reset
auto_ptr,1266
bitset,517
packaged_task,1205
shared_ptr,552
unique_ptr,542,544
weak_ptr,557
resetiosflags,1056
resize
deque,768
list,783
basic_string,650
forward_list,777
valarray,979
vector,791
rethrow_exception,461
rethrow_if_nested
nested_exception,462
rethrow_nested
nested_exception,462
return_temporary_buffer,533
reverse,894
list,786
forward_list,780
reverse_copy,894
reverse_iterator,851
reverse_iterator,852
base,853
constructor, 852
operator++,853
operator--,854
rfind
basic_string,660
right,1020
rint,993
rotate,895
rotate_copy,895
round,993
round_error
numeric_limits,440
round_indeterminate,444
round_style
numeric_limits,443
round_to_nearest,444
round_toward_infinity,444
round_toward_neg_infinity,444
round_toward_zero,444
runtime_error,466,468
runtime_error,469
s
lognormal_distribution,959
sbumpc
basic_streambuf,1026
scalbln,993
scalbn,993
scan_is
ctype,690
ctype<char>,694
scan_not
ctype,690
ctype<char>,694
SCHAR_MAX,446
SCHAR_MIN,446
scientific,1021
<scoped_allocator>,622
scoped_allocator_adaptor
allocate,626
construct,626628
constructor, 625
deallocate,626
destructor, 628
inner_allocator,626
inner_allocator_type,624
max_size,626
operator!=,628
operator==,628
outer_allocator,626
propagate_on_container_copy_assignment,
624
propagate_on_container_move_assignment,
624
propagate_on_container_swap,624
select_on_container_copy_construction,
628
search,888
search_n,889
seed_seq
Cross references 1346
c
ISO/IEC N????
constructor, 946
generate,946
param,947
size,947
seekdir
ios_base,1007
seekg
basic_istream,1045
seekoff
basic_filebuf,1078
basic_streambuf,1029
basic_stringbuf,1065
strstreambuf,1254
seekp
basic_ostream,1050
seekpos
basic_filebuf,1078
basic_streambuf,1029
basic_stringbuf,1066
strstreambuf,1255
select_on_container_copy_construction
allocator_traits,530
scoped_allocator_adaptor,628
sentry
basic_istream,1036
basic_ostream,1050
constructor, 1036,1050
<set>,795
set,805
bitset,516
operator<,808
operator==,808
set,808
swap,809
set_difference,904
set_exception
promise,1195
set_exception_at_thread_exit
promise,1195
set_intersection,904
set_new_handler,431,455
set_rdbuf
basic_ios,1017
set_symmetric_difference,905
set_terminate,431,460
set_unexpected,431,1267
set_union,903
set_value
promise,1194
set_value_at_thread_exit
promise,1195
setbase,1056
setbuf
basic_filebuf,1077
basic_streambuf,1029,1066
streambuf,1256
strstreambuf,1256
setenv,464
setf
ios_base,1009,1010
setfill,1057
setg
basic_streambuf,1028
strstreambuf,1253
setiosflags,1056
setjmp,430,464
<setjmp.h>,463
setlocale,416
setp
basic_streambuf,1028
setprecision,1057
setstate
basic_ios,1018
setw,1057
sgetc
basic_streambuf,1026
sgetn
basic_streambuf,1026
share
future,1197
shared_from_this
enable_shared_from_this,559
shared_future
constructor, 1199
destructor, 1199
get,1200
operator=,1199,1200
valid,1200
wait,1200
wait_for,1200
wait_until,1201
shared_lock
constructor, 1176,1177
destructor, 1177
lock,1178
mutex,1179
operator bool,1179
operator=,1178
owns_lock,1179
release,1179
swap,1179
try_lock,1178
Cross references 1347
c
ISO/IEC N????
try_lock_for,1178
try_lock_until,1178
unlock,1179
<shared_mutex>,1162
shared_ptr,547,559
atomic_compare_exchange_strong,561
atomic_compare_exchange_strong_-
explicit,561
atomic_compare_exchange_weak,561
atomic_compare_exchange_weak_-
explicit,561
atomic_exchange,561
atomic_exchange_explicit,561
atomic_is_lock_free,560
atomic_load,560
atomic_load_explicit,560
atomic_store,560
atomic_store_explicit,560
const_pointer_cast,555
constructor, 549551
destructor, 551
dynamic_pointer_cast,555
get,552
get_deleter,556
operator bool,553
operator!=,554
operator*,552
operator->,552
operator<,554
operator«,556
operator<=,545,554
operator=,551,552
operator==,554
operator>,554
operator>=,555
owner_before,553,558
reset,552
shared_ptr,549
static_pointer_cast,555
swap,552,555
unique,553
use_count,553
shift
valarray,979
showbase,1019
showmanyc
basic_filebuf,1076
basic_streambuf,1029,1076
showpoint,1019
showpos,1019
shrink_to_fit
basic_string,650
deque,768
vector,790
SHRT_MAX,446
SHRT_MIN,446
shuffle,895
shuffle_order_engine,942
constructor, 943
sig_atomic_t,464
SIG_DFL,464
SIG_ERR,464
SIG_IGN,464
SIGABRT,464
SIGFPE,464
SIGILL,464
SIGINT,464
signal,464
<signal.h>,463
signaling_NaN
numeric_limits,442
signbit,997
SIGSEGV,464
SIGTERM,464
sin,982,993
complex,923
sinh,982,993
complex,923
size
array,763,764
basic_string,649
bitset,518
gslice,986
initializer_list,463
match_results,1119
seed_seq,947
slice,983
size_t,109,436
size_type
allocator_traits,529
skipws,1020
sleep_for
this_thread,1161
sleep_until
this_thread,1161
slice,982
slice,983
slice_array,983
snextc
basic_streambuf,1026
sort,898
list,786
Cross references 1348
c
ISO/IEC N????
forward_list,779
sort_heap,906
splice
list,785
list,785
splice_after
forward_list,778
sputbackc
basic_streambuf,1027
sputc
basic_streambuf,1027
sputn
basic_streambuf,1027
sqrt,982,993
complex,923
<sstream>,1061
<staarg.h>,463
stable_partition,896
stable_sort,898
<stack>,835
stack,835
swap,838
start
gslice,986
slice,983
state
fpos,1013
match_results,1118
wbuffer_convert,688
wstring_convert,686
state_type
char_traits,633
wbuffer_convert,688
wstring_convert,686
static_pointer_cast
shared_ptr,555
<stdalign.h>,464
<stdarg.h>,463
<stdbool.h>,464
stddev
normal_distribution,959
<stdexcept>,466
<stdlib.h>,463,1248
stod,670
stof,669,670
stoi,669,670
stol,669,670
stold,669,670
stoll,669,670
store
atomic type,1146
stoul,669,670
stoull,669,670
str
basic_istringstream,1068
basic_ostringstream,1069,1070
basic_stringbuf,1063,1064
basic_stringstream,1071
istrstream,1257
match_results,1119
ostrstream,1258
strstream,1259
strstreambuf,1253
sub_match,1110
strchr,671
<streambuf>,1022
streambuf,999,1022
streamoff,1004,1013,1249
streamsize,1004
ios_base,1010
strftime,718
stride
gslice,986
slice,983
<string>,637
stringbuf,999,1061
stringstream,999
strlen,1252,1257
strpbrk,672
strrchr,672
strstr,672
strstream,1258
destructor, 1259
strstream,1259
strstreambuf,1250,1252
strstreambuf,1251
destructor, 1253
setg,1253
student_t_distribution,962
constructor, 963
mean,963
sub_match,1109
compare,1110
constructor, 1110
length,1110
operator basic_string,1110
operator!=,11101115
operator<,11111115
operator«,1116
operator<=,11111115
operator==,11101115
operator>,11111115
Cross references 1349
c
ISO/IEC N????
operator>=,11111115
str,1110
substr
basic_string,662
subtract_with_carry_engine,938
constructor, 939
suffix
match_results,1119
sum
valarray,979
sungetc
basic_streambuf,1027
swap,485,502
pair,490
array,764
basic_filebuf,1074
basic_fstream,1085
basic_ifstream,1080
basic_ios,1017
basic_iostream,1047
basic_istream,1036
basic_istringstream,1067
basic_ofstream,1082,1083
basic_ostream,1049
basic_ostringstream,1069
basic_regex,1109
basic_streambuf,1027
basic_string,659,667
basic_stringbuf,1063
basic_stringstream,1071
deque,769
forward_list,780
function,582,583
list,787
map,801
match_results,1121
multimap,805
multiset,812
optional,509,512
packaged_task,1204,1206
pair,489
priority_queue,835
promise,1194,1195
queue,832
set,809
shared_lock,1179
shared_ptr,552,555
stack,838
thread,1159,1160
tuple,498
unique_lock,1175
unique_ptr,543
unordered_map,818
unordered_multimap,822
unordered_multiset,828
unordered_set,825
valarray,978,982
vector,790,792
vector<bool>,794
weak_ptr,557,558
swap(unique_ptr&, unique_ptr&),545
swap_ranges,890
sync
basic_filebuf,1078
basic_istream,1044
basic_streambuf,1029
sync_with_stdio
ios_base,1011
syntax_option_type,1097,1098
awk,1098
basic,1098
collate,1098,1134
ECMAScript,1098
egrep,1098
extended,1098
grep,1098
icase,1098
nosubs,1098
optimize,1098
syntax_option_type
awk,1098
basic,1098
collate,1098
ECMAScript,1098
egrep,1098
extended,1098
grep,1098
icase,1098
nosubs,1098
optimize,1098
system,463,464
system_category,473,475
system_clock
rep,621
system_error,470,480
code,481
system_error,481
what,481
t
binomial_distribution,951
negative_binomial_distribution,953
Cross references 1350
c
ISO/IEC N????
table
ctype<char>,695
tan,982,993
complex,924
tanh,982,993
complex,924
target
function,583
target_type
function,583
tellg
basic_istream,1045
tellp
basic_ostream,1050
terminate,448,449,459,460,1267
terminate_handler,431,459
test
bitset,518
tgamma,993
this_thread
get_id,1161
sleep_for,1161
sleep_until,1161
yield,1161
thousands_sep
moneypunct,723
numpunct,710
<thread>,1156
thread
constructor, 1158,1159
destructor, 1159
detach,1160
get_id,1160
hardware_concurrency,1160
join,1159
joinable,1159
operator=,1159
swap,1159,1160
thread::id
constructor, 1157
operator!=,1158
operator<,1158
operator<=,1158
operator<<,1158
operator==,1157
operator>,1158
operator>=,1158
throw_with_nested
nested_exception,462
tie,499
basic_ios,1015,1016
time,463
<time.h>,463
time_get,713
date_order,714
do_date_order,715
do_get,717
do_get_date,716
do_get_monthname,716
do_get_time,716
do_get_weekday,716
do_get_year,716
get,715
get_date,714
get_monthname,714
get_time,714
get_weekday,714
get_year,714
time_get_byname,717
time_point
constructor, 618
max,619
min,619
operator!=,620
operator+,619
operator+=,619
operator-,619,620
operator-=,619
operator<,620
operator<=,620
operator==,620
operator>,620
operator>=,620
time_since_epoch,619
time_point_cast,620
time_put,717
do_put,718
put,718
time_put_byname,718
time_since_epoch
time_point,619
tinyness_before
numeric_limits,443
to_bytes
wstring_convert,686
to_string,670
bitset,517
to_time_t,621
to_ullong
bitset,517
to_ulong
bitset,517
Cross references 1351
c
ISO/IEC N????
to_wstring,670
tolower,684
ctype,691
ctype<char>,695
toupper,684
ctype,690
ctype<char>,695
transform,891
collate,712
regex_traits,1102
transform_primary
regex_traits,1102
translate
regex_traits,1102
translate_nocase
regex_traits,1102
traps
numeric_limits,443
treat_as_floating_point,610
truename
numpunct,710
trunc,993
try_lock,1180
shared_lock,1178
unique_lock,1174
try_lock_for
shared_lock,1178
unique_lock,1174
try_lock_until
shared_lock,1178
unique_lock,1174
try_to_lock,1170
try_to_lock_t,1170
<tuple>,492
tuple,492,494,765
constructor, 495,496
forward_as_tuple,498
get,500
make_tuple,498
operator!=,501
operator<,501
operator<=,501
operator=,497,498
operator==,501
operator>,501
operator>=,502
swap,498
tie,499
tuple,495
tuple_cat,499
tuple_element,491,499,765
tuple_size,491,499,765
type_index
constructor, 629
hash_code,630
name,630
operator!=,629
operator<,629
operator<=,629
operator==,629
operator>,630
operator>=,630
type_info,102,455
type_info::name
implementation-defined, 456
<typeinfo>,455,629
UCHAR_MAX,446
uflow
basic_filebuf,1076
basic_streambuf,1031
uint16_t,446
uint32_t,446
uint64_t,446
uint8_t,446
uint_fast16_t,446
uint_fast32_t,446
uint_fast64_t,446
uint_fast8_t,446
uint_least16_t,446
uint_least32_t,446
uint_least64_t,446
uint_least8_t,446
UINT_MAX,446
uintmax_t,446
uintptr_t,446
ULLONG_MAX,446
unary_function,567,1259
unary_negate,576
uncaught_exception,460
undeclare_no_pointers,526
undeclare_reachable,525
underflow
basic_filebuf,1076
basic_streambuf,1030
basic_stringbuf,1064
strstreambuf,1254
underflow_error,466
underflow_error,470
unexpected,1267
unexpected_handler,431,1267
unget
Cross references 1352
c
ISO/IEC N????
basic_istream,1044
uniform_int_distribution,948
a,949
b,949
constructor, 949
uniform_real_distribution,949
a,950
b,950
constructor, 949
uninitialized_copy,534
uninitialized_copy_n,534
uninitialized_fill,534
uninitialized_fill_n,534
unique,894
list,786
forward_list,779
shared_ptr,553
unique_copy,894
unique_lock
constructor, 1172,1173
destructor, 1173
lock,1174
mutex,1175
operator bool,1175
operator=,1173
owns_lock,1175
release,1175
swap,1175
try_lock,1174
try_lock_for,1174
try_lock_until,1174
unlock,1174
unique_ptr,551
constructor, 540,541,544
destructor, 541
get,542
get_deleter,542
operator bool,542
operator!=,545
operator*,542
operator->,542
operator<,545,546
operator<=,546
operator=,541,542
operator==,545
operator>,545,546
operator>=,545,546
operator[],544
release,542
reset,542,544
swap,543
unique_ptr,539
unitbuf,1020
unlock
shared_lock,1179
unique_lock,1174
<unordered_map>,812
unordered_map,812,814
at,817
insert,818
operator[],817
swap,818
unordered_map,817
unordered_multimap,812,818
insert,821
swap,822
unordered_multimap,821
unordered_multiset,813,825
swap,828
unordered_multiset,828
<unordered_set>,813
unordered_set,813,822
swap,825
unordered_set,825
unsetf
ios_base,1010
unshift
codecvt,697
upper_bound,901
uppercase,1020
use_count
shared_ptr,553
weak_ptr,557
use_facet
locale,683
uses_allocator,527,772,1193,1206
uses_allocator<tuple>,502
USHRT_MAX,446
<utility>,482
va_arg,464
va_copy,464
va_end,430,464
va_list,430,464
va_start,463,464
<valarray>,969
valarray,971,986
begin,990
constructor,973,974
destructor, 974
end,990
operator!=,981
Cross references 1353
c
ISO/IEC N????
operator*,980
operator*=,978
operator+,980
operator+=,978
operator-=,978
operator/,980
operator/=,978
operator<,981
operator<=,981
operator<<,980
operator<<=,978
operator=,974,975,980
operator==,981
operator>,981
operator>=,981
operator>>,980
operator>>=,978
operator%,980
operator%=,978
operator&,980
operator&=,978
operator&&,981
operatorˆ,980
operatorˆ=,978
operator|,980
operator|=,978
operator||,981
swap,978,982
valarray,973
valid
future,1197
packaged_task,1204
shared_future,1200
value
error_code,477
error_condition,479
optional,510
regex_traits,1103
value_or
optional,510
<vector>,762
vector,787
operator<,789
operator==,789
vector,789,790
swap,792
vector<bool>,792
flip,794
swap,794
void_pointer
allocator_traits,529
wait
condition_variable,1184
condition_variable_any,1188
future,1197
shared_future,1200
wait_for
condition_variable,1185,1186
condition_variable_any,1189
future,1198
shared_future,1200
wait_until
condition_variable,1184,1185
condition_variable_any,1188,1189
future,1198
shared_future,1201
wbuffer_convert,687
constructor, 688
destructor, 688
rdbuf,688
state,688
state_type,688
wcerr,1003
wcin,1002
wclog,1003
wcout,1002
wcschr,672
wcspbrk,672
wcsrchr,672
wcsstr,672
weak_ptr,550,556
constructor, 557
destructor, 557
expired,557
lock,558
operator=,557
reset,557
swap,557,558
use_count,557
weibull_distribution,956
a,957
b,957
constructor, 956
wfilebuf,999,1072
wfstream,999
what
bad_alloc,454
bad_cast,457
bad_exception,459
bad_typeid,457
exception,459
bad_weak_ptr,547
Cross references 1354
c
ISO/IEC N????
future_error,1192
system_error,481
wide_string
wstring_convert,686
widen
basic_ios,1016
ctype,691
ctype<char>,695
width
ios_base,689,1010
wifstream,999,1072
wios,1004
wistream,999,1032
wistringstream,999,1061
wmemchr,672
wofstream,999,1072
wostream,999,1033
wostringstream,999,1061
wregex,1091
write
basic_ostream,1054
ws,1039,1045
wstreambuf,999,1022
wstring_convert,684
byte_string,685
constructor, 687
converted,685
destructor, 687
from_bytes,685
int_type,686
state,686
state_type,686
to_bytes,686
wide_string,686
wstringbuf,999,1061
wstringstream,999
xalloc
ios_base,1011
xsgetn
basic_streambuf,1029
xsputn
basic_streambuf,1031
yield
this_thread,1161
zero
duration,614
duration_values,610
Cross references 1355
c
ISO/IEC N????
Index of implementation-defined behavior
The entries in this section are rough descriptions; exact specifications are at the indicated page in the
general text.
#pragma,406
additional formats for time_get::do_get_date,
716
alignment, 76
alignment additional values, 76
alignment of bit-fields within a class object, 222
allocation of bit-fields within a class object, 222
argument values to construct basic_ios::failure,
1018
assignability of placeholder objects, 578
behavior of attribute scoped token, 173
behavior of iostream classes when traits::pos_-
type is not streampos or when traits::off_-
type is not streamoff,999
behavior of non-standard attributes, 174
bits in a byte, 6
choice of larger or smaller value of floating literal,
27
concatenation of some types of string literals, 29
conversions between pointers and integers, 104
converting characters from source character set to
execution character set, 17
converting function pointer to object pointer and
vice versa, 105
default number of buckets in unordered_map,817
default number of buckets in unordered_multimap,
821
default number of buckets in unordered_multiset,
828
default number of buckets in unordered_set,825
defining main in freestanding environment, 58
definition and meaning of _ _ STDC _ _,406
definition and meaning of _ _ STDC_VERSION _ _-
,407
derived type for typeid,102
diagnostic message, 2
distinctness of string literals, 29
dynamic initialization of static objects before main,
60
dynamic initialization of thread-local objects be-
fore entry, 61
effect of calling basic_filebuf::setbuf with non-
zero arguments, 1077
effect of calling basic_filebuf::sync when a get
area exists, 1078
effect of calling basic_streambuf::setbuf with
non-zero arguments, 1066
effect of calling ios_base::sync_with_stdio af-
ter any input or output operation on stan-
dard streams, 1011
effect on C locale of calling locale::global,683
encoding of universal character name not in exe-
cution character set, 26
error_category for errors originating outside the
operating system, 435
exception type when shared_ptr constructor fails,
549551
exceptions thrown by standard library functions
that do not have an exception specifica-
tion, 435
execution character-set and execution wide-character
set, 18
exit status, 449
extended signed integer types, 71
formatted character sequence generated by time_-
put::do_put in C locale, 718
headers for freestanding implementation, 419
interactive device, 8
linkage of main,59
linkage of names from Standard C library, 420
locale names, 681
manner of search for included source file, 399
mapping from name to catalog when calling messages
::do_open,726
mapping header name to header or external source
file, 21
Cross references 1356
c
ISO/IEC N????
mapping physical source file characters to basic
source character set, 16
mapping to message when calling messages::do_-
get,726
meaning of asm declaration, 170
meaning of attribute declaration, 137
negative value of character literal in preprocessor,
399
nesting limit for #include directives, 400
number of threads in a program under a freestand-
ing implementation, 11
numeric values of character literals in #if direc-
tives, 399
parameters to main,59
passing argument of class type through ellipsis, 98
physical source file characters, 16
presence and meaning of native_handle_type and
native_handle,1153
rank of extended signed integer type, 82
representation of char,71
required libraries for freestanding implementation,
5
result of exception::what,459
result of inexact floating-point conversion, 80
result of right shift of negative value, 118
return value of bad_alloc::what,454
return value of bad_cast::what,457
return value of bad_exception::what,459
return value of bad_typeid::what,457
return value of char_traits<char16_t>::eof,635
return value of char_traits<char32_t>::eof,636
return value of type_info::name(),456
search locations for "" header, 400
search locations for <> header, 399
semantics of linkage specification on templates,
311
semantics of linkage specifiers, 170
semantics of non-standard escape sequences, 26
sequence of places searched for a header, 399
set of blank characters defined by regex_traits
::isctype,1103
signedness of char,71
sizeof applied to fundamental types other than
char,signed char, and unsigned char,
108
stack unwinding before call to std::terminate(),
390,395
start-up and termination in freestanding environ-
ment, 58
string resulting from __func__,193
support for extended alignment, 602
support for over-aligned types, 109,531,533
supported multibyte character encoding rules, 634,
636
text of _ _ DATE _ _ when date of translation is not
available, 406
text of _ _ TIME _ _ when time of translation is not
available, 406
type of ios_base::streamoff,1249
type of ios_base::streampos,1249
type of ptrdiff_t,117,437
type of regex_constants::error_type,1100
type of size_t,437
type of streamoff,634
type of streampos,634
type of u16streampos,635
type of u32streampos,636
type of wstreampos,636
type of array::const_iterator,763
type of array::iterator,763
underlying source of random numbers for random_-
shuffle,896
underlying type for enumeration, 156
use of non-POF function as signal handler, 464
value of ctype<char>::table_size,694
value of character literal outside range of corre-
sponding type, 26
value of multicharacter literal, 25
value of result of inexact integer to floating-point
conversion, 81
value of result of unsigned to signed conversion, 80
value of wide-character literal containing multiple
characters, 26
value of wide-character literal with single c-char
that is not in execution wide-character
set, 26
value representation of floating-point types, 72
value representation of pointer types, 73
values of a trivially copyable type, 69
values of various ATOMIC_..._LOCK_FREE macros,
1141
whether get_pointer_safety returns pointer_-
safety::relaxed or pointer_safety::preferred
if the implementation has relaxed pointer
safety, 526
Cross references 1357
c
ISO/IEC N????
whether time_get::do_get_year accepts two-digit
year numbers, 716
whether an implementation has relaxed or strict
pointer safety, 65
whether locale object is global or per-thread, 678
whether sequence pointers are copied by basic_-
filebuf move constructor, 1074
whether sequence pointers are copied by basic_-
stringbuf move constructor, 1063
whether source of translation units must be avail-
able to locate template definitions, 17
whether stack is unwound before calling std::terminate()
when a noexcept specification is violated,
395
whether values are rounded or truncated to the
required precision when converting be-
tween time_t values and time_point ob-
jects., 621
which functions in Standard C++ library may be
recursively reentered, 434
Cross references 1358