The C++ Standard Library Fourth Edition includes C++23 (Rainer Grimm) (Z-Library)
Author: Rainer Grimm
商业
No Description
📄 File Format:
PDF
💾 File Size:
5.1 MB
20
Views
0
Downloads
0.00
Total Donations
📄 Text Preview (First 20 pages)
ℹ️
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
📄 Page
1
(This page has no text content)
📄 Page
2
The C++ Standard Library What every professional C++ programmer should know about the C++ standard library. Rainer Grimm This book is for sale at http://leanpub.com/cpplibrary This version was published on 2023-03-11 This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to get reader feedback, pivot until you have the right book and build traction once you do. © 2016 - 2023 Rainer Grimm
📄 Page
3
Contents Reader Testimonials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i English Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i German Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Purpose of this Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Source Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv Value versus Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v Further Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v Cippi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v About Me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi 1. The Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 The History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Use of Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2. Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Useful Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Adaptors for Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Reference Wrappers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Smart Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Type Traits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Time Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 std::any, std::optional, and std::variant . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 std::expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
📄 Page
4
CONTENTS 3. Interface of All Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Create and delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Assign and Swap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Erasure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 4. Sequence Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Deques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Forward Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5. Associative Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Ordered Associative Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Unordered Associative Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 6. Container Adaptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Linear Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Associative Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 7. Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Contiguous Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Multidimensional Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 8. Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Categories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Iterator Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Useful Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Adaptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 9. Callable Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Function Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Lambda Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 10. Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Iterators are the Glue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Sequential, Parallel, or Parallel Execution with Vectorisation . . . . . . . . . . . . . . . . . 127 for_each . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
📄 Page
5
CONTENTS Non-Modifying Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Modifying Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Partition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Binary Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 Merge Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Heaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 Min and Max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 Permutations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Numeric . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Unitialized Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 11. Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Range Adaptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Direct on the Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Function Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Lazy Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 std Algorithms versus std::ranges Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . 188 12. Numeric . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Random Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Numeric Functions Inherited from C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Mathematical Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 13. Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 Create and Delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Conversion Between C++ and C Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Size versus Capacity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 String Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Element Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 Input and Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 Check for a substring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Modifying Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Numeric Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 14. String Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Create and Initialise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 Non-modifying operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 Modifying operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
📄 Page
6
CONTENTS 15. Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 Character Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Regular Expression Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 The Search Result match_results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 Match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 Replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 Repeated Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 16. Input and Output Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 Input and Output Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 User-defined Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 17. Formatting Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 Formatting Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Format specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 User-defined formatter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 18. Filesystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Non-member functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 File types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 19. Multithreading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 Atomic Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 Stop Token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Shared Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Thread Local Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 Condition Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 Semaphores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Coordination Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 20. Coroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 Awaitables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314 An Infinite Data Stream with co_yield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
📄 Page
7
Reader Testimonials English Edition Rick Audet Senior Engineer, Dolby Laboratories ”Arguably the quickest and easiest way to get up to speed on the most important parts of the C++ standard library. Recommended for any modern C++ programmer.” German Edition Odin Holmes CEO/CTO at Auto-Intern GmbH ”Das Buch beinhaltet, wie der Name schon sagt, eine recht ausführliche Beschreibung der STL. Dabei merkt Mann deutlich dass der Autor auch selber auf hohem Niveau programmiert. Es gibt oft den ein oder andere Tipp oder Wink in die richtige Richtung die bei Bücher von Berufsautoren oft fehlen. Z.B. die Aussage dass std::vector für 95% aller Fälle die beste Wahl ist oder dass std::async meistens die erste Wahl sein sollte lenkt der Leser geschickt in die richtige Richtung. Auch die Auswahl an Komponente aus der STL ist sehr gut getroffen (keiner kann in ein kürzen Buch die ganze STL beschreiben). Oft sehe ich, vor allem in Deutschsprachige Literatur, dass die Auswahl eher auf Komponente trifft die leicht zu beschreiben sind und nicht auf die Nützlichen. Eine gute und dennoch kürze Beschreibung vom std::regex z.B. ist weiß Gott nicht einfach aber in diesem Fall ist es der Autor sehr gelungen.” Ramon Wartala Director Technology at Performance Media GmbH
📄 Page
8
Reader Testimonials ii ”Die 215 Seiten plus Index des ’C++ kurz & gut’ vom Autor Rainer Grimm stellen ein gelungene Destillat viel umfangreicherer Texte zum Thema da. So nimmt das Kapitel über die klassischen Algorithmen der Standardbibliothek ganze 131 Seiten ein. Selbst kurze Beispiele für die Anwendung der wichtigsten Bestandteile der Standardbibliothek passen eng gedruckt in das schmale Büchlein. Auch wenn heute Tools wie Dash oder entsprechend ausgestattete IDEs, mehr und mehr den Platz derartiger Desktop-Referenzen einnehmen, ist das ’kurz & gut’ zu C++ Standardbibliothek ein leichter und mobiler Begleiter für jeden C++ Entwickler. Und als Kindle Version um so bequemer mitzunehmen.”
📄 Page
9
Introduction Purpose of this Book The C++ Standard Library is a quick reference to the standard library of the current C++23 standard ISO/IEC 14882:2023¹. C++23 has more than 2100 pages and follows the big C++20 standard. In contrast, C++23 and C++17 are neither a big nor small C++ standards. C++14 is a small addition to C++11. C++11 had more than 1,300 pages and was published in 2011. That was 13 years after the first and only C++ standard, C++98. Of course, there is also C++03, published in 2003. But C++03 is considered a bug-fix release. This quick reference aims is to provide a concise reference to the C++ standard library. This book assumes that you are familiar with C++. If so, you will get the most benefit out of this book. If C++ is new to you, you should start with a textbook about core C++. Once you have mastered a book about the core language, you can make your next big step by reading this book. To make your job easier, I have provided many short code snippets to connect theory and practice. Index The book should be a reference for C++ and should, therefore, have an index. Leanpub does not support the creation of an index. So I’ve made it based on regular expressions, naming conventions, a lot of python magic, and a long table that I had to split for each page. Here is the problem. The index is only fully available in the pdf format of the book. Conventions I promise only a few conventions. Special Fonts Italic I use Italic if something is essential. Monospace I use Monospace for code, instructions, keywords, and names of types, variables, functions, and classes. ¹https://www.iso.org/standards.html
📄 Page
10
Introduction iv Special Boxes I use boxes for unique information, tips, and warning. Information headline Information text. Tip headline Tip description. Warning headline Warning description. Source Examples I don’t particularly appreciate using directives and declarations because they hide the library’s namespace. I use them so that the origin can always be deduced from the using directive (using namespace std;) or the using declaration (using std::cout;). Still, because of the limited length of a page, I have to use them from time to time. Only header files of the featured functionality are shown in the code snippets. true or false is displayed in the output code snippets for boolean values, and std::boolalpha is not used. When your compiler supports the modularized standard library in C++23, you can replace the headers with an import std statement. Source Code To be concise, I only present short code snippets in this book. The name of the entire program is in the first line of the code snippet. Value versus Object I call instances of fundamental data types values, which C++ inherited from C. Instances of more advanced types, which often consist of fundamental types, are called objects. Objects are typically instances of user-defined types or containers.
📄 Page
11
Introduction v Acknowledgments First, I want to thank Alexandra Follenius, the lector at O’Reilly, for the German book C++ Standardbibliothek². The German book is the ancestor of this book. For my book C++ Standardbib- liothek Karsten Ahnert, Guntram Berti, Dmitry Ganyushin, Sven Johannsen, Torsten Robitzki, Bart Vandewoestyne, and Felix Winter were very valuable proofreaders. A lot of thanks to all of them. I started a request in my English blog for translating this book to English www.ModernesCpp.com³. I received a much higher response than I expected. Special thanks to all of you, including my son Marius, the first proofreader. Here are the alphabetically ordered names: Mahesh Attarde, Rick Audet, Pete Barrow, Michael Ben- David, Dave Burns, Alvaro Fernandez, Juliette Grimm, George Haake, Clare Macrae, Arne Mertz, Ian Reeve, Jason Turner, Bart Vandewoestyne, Ivan Vergiliev, and Andrzej Warzynski. Further Information The idea of the book is relatively easy to paraphrase: “What every professional C++ programmer should know about the C++ standard library.” Because of this intention, I left many answers unanswered; therefore, I provide you with the links to the details at the beginning of each new topic. The link will refer to the excellent online resource www.cppreference.com⁴. Cippi Let me introduce Cippi. Cippi will accompany you in this book. I hope you like her. ²http://shop.oreilly.com/product/9783955619688.do ³http://www.modernescpp.com/index.php/do-you-wan-t-to-proofread-a-book ⁴http://en.cppreference.com/w/
📄 Page
12
Introduction vi I’m Cippi: curious, clever and - yes - feminine! About Me I’ve worked as a software architect, team lead, and instructor since 1999. In 2002, I created company- intern meetings for further education. I have given training courses since 2002. My first tutorials were about proprietary management software, but I began teaching Python and C++ soon after. I like to write articles about C++, Python, and Haskell in my spare time. I also like to speak at conferences. I publish weekly on my English blogModernes Cpp⁵, and the German blog⁶, hosted by Heise Developer. Since 2016, I have been an independent instructor giving seminars about modern C++ and Python. I have published several books in various languages about modern C++ and, in particular, about concurrency. Due to my profession, I always search for the best way to teach modern C++. ⁵https://www.modernescpp.com/ ⁶https://www.grimm-jaud.de/index.php/blog
📄 Page
13
Introduction vii Rainer Grimm
📄 Page
14
1. The Standard Library The C++ standard library consists of many components. This chapter serves two purposes. It should give you a quick overview of the features and a first idea of how to use them. The History C++ and, therefore, the standard library has a long history. C++ started in the 1980s of the last millennium and ended now in 2023. Anyone who knows about software development knows how fast our domain evolves. So 40 years is a very long period. You may not be so astonished that the first components of C++, like I/O streams, were designed with a different mindset than the modern Standard Template Library (STL). C++ started as an object-oriented language, incorporated generic programmingwith the STL, and has now adoptedmany functional programming ideas. This evolution of software development in the last 40 years, which you can observe in the C++ standard library, is also an evolution in how software problems are solved. C++ timeline The first C++98 standard library from 1998 had three components. Those were the previously mentioned I/O streams, mainly for file handling, the string library, and the Standard Template Library. The Standard Template Library facilitates the transparent application of algorithms on containers. The history continues in 2005 with Technical Report 1 (TR1). The extension to the C++ library ISO/IEC TR 19768 was not an official standard, but almost all components became part of C++11. These were, for example, the libraries for regular expressions, smart pointers, hash tables, random numbers, and time, based on the boost libraries (http://www.boost.org/). In addition to the standardization of TR1, C++11 got one new component: the multithreading library.
📄 Page
15
The Standard Library 2 C++14 was only a minor update to the C++11 standard. Therefore, C++14 added only a few improvements to existing libraries for smart pointers, tuples, type traits, and multithreading. C++17 includes libraries for the file system and the two new data types std::any and std::optional. C++20 has four outstanding features: concepts, ranges, coroutines, and modules. Besides the big four, there are more pearls in C++20: the three-way comparison operator, the formatting library, and the concurrency-related data types semaphores, latches, and barriers. C++23 improved the big four of C++20: extended ranges functionality, the coroutine generator std::generator, and a modularized C++ standard library. Overview As C++ has many libraries, finding the convenient one for each use case is often difficult. Utilities Utilities are libraries with a general focus and, therefore, can be applied in many contexts. Examples of utilities are functions to calculate the minimum or the maximum of values, the midpoint of two values, or to swap or move values. Thanks to save comparison of integers, integral promotion does not kick in. Other utilities are std::function, std::bind, or std:bind_front. With std::bind or std::bind_front, you can easily create new functions from existing ones. To bind them to a variable and invoke them later, you have std::function. With std::pair and the generalization std::tuple you can create heterogeneous pairs and tuples of arbitrary length. The reference wrappers std::ref and std::cref are pretty handy. One can use them to create a reference wrapper for a variable, which for std::cref is constant. Of course, the highlights of the utilities are the smart pointers. They allow explicit automatic memory management in C++. You can model the concept of explicit ownership with std::unique_ptr and model shared ownership with std::shared_ptr. std::shared_ptr uses reference counting for taking care of its resource. The third one, std::weak_ptr, helps to break the cyclic dependencies among std::shared_ptrs. Cyclic references are the classic problem of reference counting. The type traits library can check, compare and manipulate type information at compile time. The time library is an import addition to the new multithreading capabilities of C++. But it is also quite handy to make performance measurements and includes support for calender and time zone. With std::any, std::optional, and std::variant, we get with C++17 three special datatypes that can have any, an optional value, or a variant of values.
📄 Page
16
The Standard Library 3 The Standard Template Library The three components of the STL The Standard Template Library (STL) consists of three components from a bird’s-eye view. Those are containers, algorithms that run on the containers, and iterators that connect both of them. The containers have only minimal requirements for their elements. This abstraction of generic programming enables you to combine algorithms and containers uniquely. The C++ Standard Library has a rich collection of containers. We have sequence and associative containers. Associative containers can be classified as ordered or unordered associative containers. Each of the sequence containers has a unique domain. Still, in 95 % of the use cases, std::vector is the right choice. std::vector can dynamically adjust its size, automatically manages its memory, and provides you with outstanding performance. In contrast, std::array is the only sequence container that cannot adjust its size at runtime. It is optimized for minimal memory and performance overhead. While std::vector is good at putting new elements at its end, you should use std::deque to put an element also at the beginning. With std::list being a doubly-linked list and std::forward_list as a singly linked list, we have two additional containers optimized for operations at arbitrary positions in the container, with high performance. Associative containers are containers of key-value pairs. They provide their values by their respective key. A typical use case for an associative container is a phone book, where you use the key family name to retrieve the value phone number. C++ has eight different associative containers. On one side are the associative containers with ordered keys: std::set, std::map, std::multiset and std::multimap. On the other side, there are the unordered associative containers: std::unordered_set, std::unordered_- map, std::unordered_multiset, and std::unordered_multimap. First, look at the ordered associative containers. The difference between std::set, and std::map is that the former has no associated value. The difference between std::map and std::multimap is that the latter can have more than one identical key. These naming conventions also hold for the unordered associative containers, which have much in common with the ordered ones. The critical difference is the performance. While the ordered associative containers have a logarithmic access time, the unordered associative containers allow constant access time. Therefore the access time of the unordered associative containers is independent of their size. The same rule applies to std::unordered_map as to std::vector. In 95 % of all use cases, std::unordered_map should be your first choice if you don’t need sorted keys.
📄 Page
17
The Standard Library 4 Container adapters provide a simplified interface to the sequence containers. C++ has std::stack, std::queue, and std::priority_queue. C-array, std::array, std::vector, or std::string support views. std::span is a view of a contiguous sequence of elements. A view is never an owner. Iterators are the glue between the containers and the algorithms. The container creates them. As generalized pointers, you can use them to iterate forward and backward or jump to an arbitrary position in the container. The type of iterator you get depends on the container. If you use an iterator adapter, you can directly access a stream. The STL gives you more than 100 algorithms. Specifying the execution policy, you can run most of the algorithms sequential, parallel, or parallel and vectorized. Algorithms operate on elements or a range of elements. Two iterators define a range. The first one defines the beginning, the second one, called end iterator, defines the end of the range. It’s important to know that the end iterator points to one element past the end of the range. The algorithms can be used in a wide range of applications. You can find elements, count them, find ranges, and compare or transform them. There are algorithms to generate, replace or remove elements from a container. Of course, you can sort, permute or partition a container or determine the minimum or maximum element of it. Many algorithms can be further customized by callables like functions, function objects, or lambda-functions. The callables provide special criteria for the search or the transformation of elements. They highly increase the power of the algorithm. The algorithms of the ranges library are lazy, can work directly on the container, and can easily be composed. They extend C++ with functional ideas. Furthermore, most of the classical STL algorithms have ranges pendants, which support projections and provide additional safety guarantees. Numeric There are two libraries for numerics in C++: the random numbers library and the mathematical functions, which C++ inherited from C. The random numbers library consists of two parts. There is the random number generator; the generated random numbers distribution is on the other side. The random number generator generates a stream of numbers between a minimum and a maximum value, which the random number distribution maps onto the concrete distribution. Because of C, C++ has a lot of mathematical standard functions. For example, there are logarithmic, exponential, and trigonometric functions. C++ supports basic and advanced mathematical constants such as e, π, or ϕ. Text Processing With strings and regular expressions, C++ has two powerful libraries to process text.
📄 Page
18
The Standard Library 5 std::string possesses a rich collection of member functions to analyze and modify its text. Because it has a lot in common with a std::vector of characters, you can apply the STL algorithms to std::string. std::string is the successor of the C string but a lot easier and safer to use. C++ strings manage their memory. In contrast to a std::string, a std::string_view is cheap to copy. A std::string_view is a non-owning reference to a std::string. Regular expression is a language for describing text patterns. You can use regular expressions to determine whether a text pattern is present once or more times in a text. But that’s not all. Regular expressions enable the replacement of a matched pattern with text. Input and Output I/O streams library is a library, present from the start of C++, that allows communication with the outside world. Communication means, in this concrete case, that the extraction operator (>>) enables it to read formatted or unformatted data from the input stream, and the insertion operator (<<) allows it to write the data on the output stream. Data can be formatted using manipulators. The stream classes have an elaborate class hierarchy. Two stream classes are significant: First, string streams allow you to interact with strings and streams. Second, file streams will enable you to read and write files easily. The state of streams is kept in flags, which you can read and manipulate. By overloading the input operator and output operator, your class can interact with the outside world like a fundamental data type. The formatting library provides a safe and extensible alternative to the printf family and extends the I/O streams library. In contrast to the I/O streams library, the filesystem library was added to the C++-Standard with C++17. The library is based on three concepts file, file name, and path. Files can be directories, hard links, symbolic links, or regular files. Paths can be absolute or relative. The filesystem library supports a powerful interface for reading and manipulating the filesystem. Multithreading C++ gets with the 2011 published C++ standard a multithreading library. This library has basic building blocks like atomic variables, threads, locks, and condition variables. That’s the base on which future C++ standards can build higher abstractions. But C++11 already knows tasks, which provide a higher abstraction than the cited basic building blocks. At a low level, C++11 provides for the first time a memory model and atomic variables. Both components are the foundation for well-defined behavior in multithreading programming.
📄 Page
19
The Standard Library 6 A new thread in C++ will immediately start its work. It can run in the foreground or background and gets its data by copy or reference. Thanks to the stop token, you can interrupt the improved thread std::jthread. The access of shared variables between threads has to be coordinated. This coordination can be done in different ways with mutexes or locks. But often, it’s sufficient to protect the initialization of the data as it will be immutable during its lifetime. Declaring a variable as thread-local ensures that a thread gets its copy, so there is no conflict. Condition variables are a classic solution to implement sender-receiver workflows. The key idea is that the sender notifies the receiver when it’s done with its work so that the receiver can start. Semaphores are a synchronization mechanism that controls concurrent access to a shared resource. A semaphore has a counter that is bigger than zero. Acquiring the semaphore decreases the counter, and releasing the semaphore increases the counter. A thread can only acquire the resource when the counter is greater than zero. Similar to semaphores, std::latch and std::barrier are coordination types that enable some threads to block until a counter becomes zero. In contrast to a std::barrier, you can reuse a std::latch for a new iteration and adjust its counter for this new iteration. Tasks have much in common with threads. But while a programmer explicitly creates a thread, a task will be implicitly created by the C++ runtime. Tasks are like data channels. The data can be a value, an exception, or simply a notification. The promise puts data into the data channel; the future picks the value up. Coroutines are functions that can suspend and resume their execution while keeping their state. Coroutines are the usual way to write event-driven applications¹. The event-driven application can be simulations, games, servers, user interfaces, or even algorithms. Coroutines enable cooperative multitasking². The key to cooperative multitasking is that each task takes as much time as it needs. Use of Libraries You must perform three steps to use a library in a program. At first, you have to include the header files with the #include statement, so the compiler knows the library’s names. Alternatively, you can import with C++23 the standard library using import std;. Because the C++ standard library names are in the namespace std, you can use them in the second step fully qualified, or you have to import them in the global namespace. The third and final step is to specify the libraries for the linker to get an executable. This third step is often optional. The following lines explain the three steps. Include Header Files The preprocessor includes the file, following the #include statement. That is, most of the time, a header file. The header files are placed in angle brackets: ¹https://en.wikipedia.org/wiki/Event-driven_programming ²https://de.wikipedia.org/wiki/Multitasking
📄 Page
20
The Standard Library 7 #include <iostream> #include <vector> Specify all necessary header files The compiler is free to add additional headers to the header files. So your program may have all the necessary headers, although you didn’t specify them. It’s not recommended to rely on this feature. All needed headers should always be explicitly specified. Otherwise, a compiler upgrade or code porting may provoke a compilation error. Import the Standard Library In C++23, you can import the entire standard library using the import statement: import std; The import std; statement imports everything in the namespace std fromC++ headers and Cwrapper headers such as std::printf from <cstdio>. Also ::operator new, or ::operator delete from the <new> header is imported. If you also want to import the global namespace counterparts such as ::printf from the C wrapper header <stdio.h>, use the import std.compat. Prefer importing modules to including headers Modules have many advantages over header files. These advantages hold for the modu- larized standard library but also user-defined modules. Modules are imported only once, and this process is literally for free. It makes no difference in which order you import modules, and duplicate names with modules are very unlikely. Modules enable you to express the logical structure of your code because you can explicitly specify names that should be exported or not. Additionally, you can bundle a fewmodules into a more extensive module and provide them to your customer as a logical package. Parallel use of header files and modules I use both syntactic forms: headers files and modules in the following code snippets. You should only use one of them exclusively. Usage of Namespaces If you use qualified names, you should use them precisely as defined. For each namespace, you must put the scope resolution operator ::. More libraries of the C++ standard library use nested namespaces.
The above is a preview of the first 20 pages. Register to read the complete e-book.