Modern C++ Programming Cookbook - Third Edition

Book description

Meta Description: With a wealth of practical recipes, this third edition isn't just a guide to C++23; it's a complete resource covering key features and techniques from C++11 through to C++23. It's designed to keep you ahead of the curve in C++.

Key Features

  • Updated and packed with new recipes, including sync streams, std:expected and std:mdspan, and C++20/23 range adaptors
  • Covers all significant features from all modern versions of the standard, providing comprehensive insights into modern C++
  • Learn through a series of hands-on, self-contained recipes
  • Purchase of the print or Kindle book includes a free eBook in PDF format

Book Description

The updated third edition of Modern C++ Programming Cookbook addresses the latest features of C++23, such as the stacktrace library, std::expected and std::mdspan classes, the header, formatting library improvements, and updates to the ranges library. It also gets into more C++20 topics not previously covered, such as sync streams and source_location.

The book is organized into practical recipes covering a wide range of real-world problems, helping you find the solutions you need quickly. You’ll find coverage of all the core concepts of modern C++ programming and features and techniques from C++11 through to C++23, meaning you’ll stay ahead of the curve by learning to incorporate the newest language and library improvements.

Beyond the core concepts and new features, you’ll explore recipes related to performance and best practices, how to implement useful patterns and idioms, like pimpl, named parameter, attorney-client, and the factory pattern, and how to complete unit testing with the widely used C++ libraries: Boost.Test, Google Test, and Catch2.

With the comprehensive coverage this C++ programming guide offers, by the end of the book you’ll have everything you need to build performant, scalable, and efficient applications in C++.

What you will learn

  • Explore the new C++23 language and library features
  • Go deep into the most useful C++20 features
  • Learn to handle threading and concurrency for better performance
  • Solve complex string manipulation tasks efficiently with regex
  • Leverage the standard library for faster development
  • Master the filesystem library to work with files and directories
  • Work with different types of strings and understand compilation
  • See how you can use CRTP, mixins and other patterns in C++

Who this book is for

This book is designed for entry- and intermediate-level programmers who already have a foundational understanding of the C++ programming language, but who are looking to master the language, implement the newest features, and become proficient modern C++ developers. Experienced C++ programmers can leverage the recipes in this book to quickly get up to speed on all the most important language and library features of C++11/14/17/20 and 23.

Table of contents

  1. Preface
    1. Who this book is for
    2. What this book covers
    3. What’s new in this edition
    4. To get the most out of this book
    5. Get in touch
  2. Learning Modern Core Language Features
    1. Using auto whenever possible
      1. How to do it...
      2. How it works...
      3. See also
    2. Creating type aliases and alias templates
      1. How to do it...
      2. How it works...
      3. See also
    3. Understanding uniform initialization
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    4. Understanding the various forms of non-static member initialization
      1. How to do it...
      2. How it works...
      3. See also
    5. Controlling and querying object alignment
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Using scoped enumerations
      1. How to do it...
      2. How it works...
      3. See also
    7. Using override and final for virtual methods
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Using range-based for loops to iterate on a range
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    9. Enabling range-based for loops for custom types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    10. Using explicit constructors and conversion operators to avoid implicit conversion
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    11. Using unnamed namespaces instead of static globals
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    12. Using inline namespaces for symbol versioning
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    13. Using structured bindings to handle multi-return values
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    14. Simplifying code with class template argument deduction
      1. How to do it...
      2. How it works...
      3. See also
    15. Using the subscript operator to access elements in a collection
      1. How to do it…
      2. How it works…
      3. See also
  3. Working with Numbers and Strings
    1. Understanding the various numeric types
      1. How to do it…
      2. How it works…
      3. See also
    2. Limits and other properties of numeric types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Converting between numeric and string types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Understanding the various character and string types
      1. How to do it…
      2. How it works…
      3. See also
    5. Printing Unicode characters to the output console
      1. How to do it…
      2. How it works…
      3. See also
    6. Generating pseudo-random numbers
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    7. Properly initializing a pseudo-random number generator
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Creating cooked user-defined literals
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    9. Creating raw user-defined literals
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    10. Using raw string literals to avoid escaping characters
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    11. Creating a library of string helpers
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more…
      5. See also
    12. Verifying the format of a string using regular expressions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    13. Parsing the content of a string using regular expressions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    14. Replacing the content of a string using regular expressions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    15. Using std::string_view instead of constant string references
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    16. Formatting and printing text with std::format and std::print
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    17. Using std::format with user-defined types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more…
      5. See also
  4. Exploring Functions
    1. Defaulted and deleted functions
      1. Getting started
      2. How to do it...
      3. How it works...
      4. See also
    2. Using lambdas with standard algorithms
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Using generic and template lambdas
      1. Getting started
      2. How to do it...
      3. How it works...
      4. See also
    4. Writing a recursive lambda
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Writing function templates
      1. How to do it…
      2. How it works…
      3. See also
    6. Writing a function template with a variable number of arguments
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    7. Using fold expressions to simplify variadic function templates
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    8. Implementing the higher-order functions map and fold
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    9. Composing functions into a higher-order function
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    10. Uniformly invoking anything callable
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
  5. Preprocessing and Compilation
    1. Conditionally compiling your source code
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more…
      5. See also
    2. Using the indirection pattern for preprocessor stringification and concatenation
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Performing compile-time assertion checks with static_assert
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Conditionally compiling classes and functions with enable_if
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    5. Selecting branches at compile time with constexpr if
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Providing metadata to the compiler with attributes
      1. How to do it...
      2. How it works...
      3. See also
  6. Standard Library Containers, Algorithms, and Iterators
    1. Using vector as a default container
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    2. Using bitset for fixed-size sequences of bits
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    3. Using vector<bool> for variable-size sequences of bits
      1. Getting ready...
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    4. Using the bit manipulation utilities
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    5. Finding elements in a range
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Sorting a range
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    7. Initializing a range
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more…
      5. See also
    8. Using set operations on a range
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    9. Using iterators to insert new elements into a container
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    10. Writing your own random-access iterator
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    11. Container access with non-member functions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    12. Selecting the right standard containers
      1. How to do it…
      2. How it works…
      3. See also
  7. General-Purpose Utilities
    1. Expressing time intervals with chrono::duration
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    2. Working with calendars
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. There’s more…
      5. See also
    3. Converting times between time zones
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    4. Measuring function execution time with a standard clock
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Generating hash values for custom types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Using std::any to store any value
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    7. Using std::optional to store optional values
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more…
      5. See also
    8. Chaining together computations that may or may not produce a value
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. There’s more…
      5. See also
    9. Using std::variant as a type-safe union
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    10. Visiting a std::variant
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    11. Using std::expected to return a value or an error
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    12. Using std::span for contiguous sequences of objects
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    13. Using std::mdspan for multi-dimensional views of sequences of objects
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. There’s more…
      5. See also
    14. Registering a function to be called when a program exits normally
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    15. Using type traits to query properties of types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    16. Writing your own type traits
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    17. Using std::conditional to choose between types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    18. Providing logging details with source_location
      1. How to do it…
      2. How it works…
      3. See also
    19. Using the stacktrace library to print the call sequence
      1. How to do it…
      2. How it works…
      3. See also
  8. Working with Files and Streams
    1. Reading and writing raw data from/to binary files
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    2. Reading and writing objects from/to binary files
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Using streams on fixed-size external buffers
      1. How to do it…
      2. How it works…
      3. See also
    4. Using localized settings for streams
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Using I/O manipulators to control the output of a stream
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Using monetary I/O manipulators
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    7. Using time I/O manipulators
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Working with filesystem paths
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    9. Creating, copying, and deleting files and directories
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    10. Removing content from a file
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    11. Checking the properties of an existing file or directory
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    12. Enumerating the content of a directory
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    13. Finding a file
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
  9. Leveraging Threading and Concurrency
    1. Working with threads
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    2. Synchronizing access to shared data with mutexes and locks
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Finding alternatives for recursive mutexes
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Handling exceptions from thread functions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Sending notifications between threads
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Using promises and futures to return values from threads
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    7. Executing functions asynchronously
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Using atomic types
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    9. Implementing parallel map and fold with threads
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    10. Implementing parallel map and fold with tasks
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    11. Implementing parallel map and fold with standard parallel algorithms
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    12. Using joinable threads and cancellation mechanisms
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    13. Synchronizing threads with latches, barriers, and semaphores
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    14. Synchronizing writing to output streams from multiple threads
      1. How to do it…
      2. How it works…
      3. See also
  10. Robustness and Performance
    1. Using exceptions for error handling
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    2. Using noexcept for functions that do not throw exceptions
      1. How to do it...
      2. How it works...
      3. There’s more...
      4. See also
    3. Ensuring constant correctness for a program
      1. How to do it...
      2. How it works...
      3. There’s more...
      4. See also
    4. Creating compile-time constant expressions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more…
      5. See also
    5. Creating immediate functions
      1. How to do it…
      2. How it works…
      3. See also
    6. Optimizing code in constant-evaluated contexts
      1. How to do it…
      2. How it works…
      3. See also
    7. Using virtual function calls in constant expressions
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    8. Performing correct type casts
      1. How to do it...
      2. How it works...
      3. There’s more...
      4. See also
    9. Implementing move semantics
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    10. Using unique_ptr to uniquely own a memory resource
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    11. Using shared_ptr to share a memory resource
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    12. Consistent comparison with the operator <=>
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    13. Comparing signed and unsigned integers safely
      1. How to do it…
      2. How it works…
      3. See also
  11. Implementing Patterns and Idioms
    1. Avoiding repetitive if-else statements in factory patterns
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    2. Implementing the pimpl idiom
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    3. Implementing the named parameter idiom
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Separating interfaces and implementations with the non-virtual interface idiom
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Handling friendship with the attorney-client idiom
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Static polymorphism with the curiously recurring template pattern
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    7. Adding functionality to classes with mixins
      1. How to do it…
      2. How it works…
      3. See also
    8. Handling unrelated types generically with the type erasure idiom
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    9. Implementing a thread-safe singleton
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
  12. Exploring Testing Frameworks
    1. Getting started with Boost.Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    2. Writing and invoking tests with Boost.Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Asserting with Boost.Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Using fixtures in Boost.Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Controlling output with Boost.Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    6. Getting started with Google Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    7. Writing and invoking tests with Google Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Asserting with Google Test
      1. How to do it...
      2. How it works...
      3. See also
    9. Using test fixtures with Google Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    10. Controlling output with Google Test
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    11. Getting started with Catch2
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    12. Writing and invoking tests with Catch2
      1. How to do it...
      2. How it works...
      3. See also
    13. Asserting with Catch2
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    14. Controlling output with Catch2
      1. Getting ready
      2. How to do it…
      3. How it works...
      4. See also
  13. C++ 20 Core Features
    1. Working with modules
      1. Getting ready
      2. How to do it…
      3. How it works...
      4. See also
    2. Understanding module partitions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    3. Specifying requirements on template arguments with concepts
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    4. Using requires expressions and clauses
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Exploring abbreviated function templates
      1. How to do it…
      2. How it works…
      3. See also
    6. Iterating over collections with the ranges library
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    7. Exploring the standard range adaptors
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    8. Converting a range to a container
      1. Getting ready
      2. How to do it…
      3. How it works…
      4. See also
    9. Creating your own range view
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    10. Using constrained algorithms
      1. How to do it…
      2. How it works…
      3. See also
    11. Creating a coroutine task type for asynchronous computations
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    12. Creating a coroutine generator type for sequences of values
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There’s more...
      5. See also
    13. Generating a sequence of values with the std::generator type
      1. How to do it…
      2. How it works…
      3. See also
  14. Other Books You May Enjoy
  15. Index

Product information

  • Title: Modern C++ Programming Cookbook - Third Edition
  • Author(s): Marius Bancila
  • Release date: February 2024
  • Publisher(s): Packt Publishing
  • ISBN: 9781835080542