Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
C++20 STL Cookbook
C++20 STL Cookbook

C++20 STL Cookbook: Leverage the latest features of the STL to solve real-world problems

eBook
$25.99 $37.99
Paperback
$46.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Table of content icon View table of contents Preview book icon Preview Book

C++20 STL Cookbook

Chapter 2: General STL Features

This chapter is a general potpourri of STL features and techniques. These are mostly new features introduced over the past few years, which may not yet be widely used. These are useful techniques that will improve the simplicity and readability of your code.

In this chapter we will cover the following recipes:

  • Use the new span class to make your C-arrays safer
  • Use structured binding to return multiple values
  • Initialize variables within if and switch statements
  • Use template argument deduction for simplicity and clarity
  • Use if constexpr to simplify compile-time decisions

Technical requirements

You can find the code for this chapter on GitHub at https://github.com/PacktPublishing/CPP-20-STL-Cookbook/tree/main/chap02.

Use the new span class to make your C-arrays safer

New for C++20, the std::span class is a simple wrapper that creates a view over a contiguous sequence of objects. The span doesn't own any of its own data, it refers to the data in the underlying structure. Think of it as string_view for C-arrays. The underlying structure may be a C-array, a vector, or an STL array.

How to do it…

You can create a span from any compatible contiguous-storage structure. The most common use case will involve a C-array. For example, if you try to pass a C-array directly to a function, the array is demoted to a pointer and the function has no easy way to know the size of the array:

void parray(int * a);  // loses size information

If you define your function with a span parameter, you can pass it a C-array and it will be promoted to span. Here's a template function that takes a span and prints out the size in elements and in bytes:

template<typename T>
void pspan(span<T> s) {
    cout << format("number of elements: {}\n", s.size());
    cout << format("size of span: {}\n", s.size_bytes());
    for(auto e : s) cout << format("{} ", e);
    cout << "\n";
}

You can pass a C-array to this function and it's automatically promoted to span:

int main() {
    int carray[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    pspan<int>(carray);
}

Output:

number of elements: 10
number of bytes: 40
1 2 3 4 5 6 7 8 9 10 

The purpose of span is to encapsulate the raw data to provide a measure of safety and utility, with a minimum of overhead.

How it works…

The span class itself doesn't own any data. The data belongs to the underlying data structure. The span is essentially a view over the underlying data. It also provides some useful member functions.

Defined in the <span> header, the span class looks something like:

template<typename T, size_t Extent = std::dynamic_extent>
class span {
    T * data;
    size_t count;
public:
    ... 
};

The Extent parameter is a constant of type constexpr size_t, which is computed at compile time. It's either the number of elements in the underlying data or the std:: dynamic_extent constant, which indicates that the size is variable. This allows span to use an underlying structure like a vector, which may not always be the same size.

All member functions are constexpr and const qualified. Member functions include:

Important Note

The span class is but a simple wrapper that performs no bounds checking. So, if you try to access element n+1 in a span of n elements, the result is undefined, which is tech for, "Bad. Don't do that."

Use structured binding to return multiple values

Structured binding makes it easy to unpack the values of a structure into separate variables, improving the readability of your code.

With structured binding you can directly assign the member values to variables like this:

things_pair<int,int> { 47, 9 };
auto [this, that] = things_pair;
cout << format("{} {}\n", this, that);

Output:

47 9

How to do it…

  • Structured binding works with pair, tuple, array, and struct. Beginning with C++20, this includes bit-fields. This example uses a C-array:
    int nums[] { 1, 2, 3, 4, 5 };
    auto [ a, b, c, d, e ] = nums;
    cout << format("{} {} {} {} {}\n", a, b, c, d, e);

Output:

1 2 3 4 5

Because the structured binding uses automatic type deduction, its type must be auto. The names of the individual variables are within the square brackets, [ a, b, c, d, e ].

In this example the int C-array nums holds five values. These five values are assigned to the variables (a, b, c, d, and e) using structured binding.

  • This also works with an STL array object:
    array<int,5> nums { 1, 2, 3, 4, 5 };
    auto [ a, b, c, d, e ] = nums;
    cout << format("{} {} {} {} {}\n", a, b, c, d, e);

Output:

1 2 3 4 5
  • Or you can use it with a tuple:
    tuple<int, double, string> nums{ 1, 2.7, "three" };
    auto [ a, b, c ] = nums;
    cout << format("{} {} {}\n", a, b, c);

Output:

1 2.7 three
  • When you use it with a struct it will take the variables in the order they're defined:
    struct Things { int i{}; double d{}; string s{}; };
    Things nums{ 1, 2.7, "three" };
    auto [ a, b, c ] = nums;
    cout << format("{} {} {}\n", a, b, c);

Output:

1 2.7 three
  • You can use a reference with a structured binding, which allows you to modify the values in the bound container, while avoiding duplication of the data:
    array<int,5> nums { 1, 2, 3, 4, 5 };
    auto& [ a, b, c, d, e ] = nums;
    cout << format("{} {}\n", nums[2], c);
    c = 47;
    cout << format("{} {}\n", nums[2], c);

Output:

3 3
47 47

Because the variables are bound as a reference, you can assign a value to c and it will change the value in the array as well (nums[2]).

  • You can declare the array const to prevent values from being changed:
    const array<int,5> nums { 1, 2, 3, 4, 5 };
    auto& [ a, b, c, d, e ] = nums;
    c = 47;    // this is now an error 

Or you can declare the binding const for the same effect, while allowing the array to be changed elsewhere and still avoid copying data:

array<int,5> nums { 1, 2, 3, 4, 5 };
const auto& [ a, b, c, d, e ] = nums;
c = 47;    // this is also an error 

How it works…

Structured binding uses automatic type deduction to unpack the structure into your variables. It determines the type of each value independently, and assigns a corresponding type to each variable.

  • Because structured binding uses automatic type deduction, you cannot specify a type for the binding. You must use auto. You should get a reasonable error message if you try to use a type for the binding:
    array<int,5> nums { 1, 2, 3, 4, 5 };
    int [ a, b, c, d, e ] = nums;

Output:

error: structured binding declaration cannot have type 'int'
note: type must be cv-qualified 'auto' or reference to cv-qualified 'auto'

Above is the error from GCC when I try to use int with the structured binding declaration.

  • It's common to use structured binding for a return type from a function:
    struct div_result {
        long quo;
        long rem;
    };
    div_result int_div(const long & num, const long & denom) {
        struct div_result r{};
        r.quo = num / denom;
        r.rem = num % denom;
        return r;
    }
    int main() {
        auto [quo, rem] = int_div(47, 5);
        cout << format("quotient: {}, remainder {}\n",
          quo, rem);
    }

Output:

quotient: 9, remainder 2
  • Because the map container classes return a pair for each element, it can be convenient to use structured binding to retrieve key/value pairs:
    map<string, uint64_t> inhabitants {
        { "humans",   7000000000 },
        { "pokemon", 17863376 },
        { "klingons",   24246291 },
        { "cats",    1086881528 }
    };
    // I like commas
    string make_commas(const uint64_t num) {
        string s{ std::to_string(num) };
        for(int l = s.length() - 3; l > 0; l -= 3) {
            s.insert(l, ",");
        }
        return s;
    }
    int main() {
        for(const auto & [creature, pop] : inhabitants) {
            cout << format("there are {} {}\n", 
                make_commas(pop), creature);
        }
    }

Output:

there are 1,086,881,528 cats
there are 7,000,000,000 humans
there are 24,246,291 klingons
there are 17,863,376 pokemon

Using structured binding to unpack structures should make your code clearer and easier to maintain.

Initialize variables within if and switch statements

Beginning with C++17, if and switch now have initialization syntax, much like the for loop has had since C99. This allows you to limit the scope of variables used within the condition.

How to do it…

You may be accustomed to code like this:

const string artist{ "Jimi Hendrix" };
size_t pos{ artist.find("Jimi") };
if(pos != string::npos) {
    cout << "found\n";
} else {
    cout << "not found\n";
}

This leaves the variable pos exposed outside the scope of the conditional statement, where it needs to be managed, or it can collide with other attempts to use the same symbol.

Now you can put the initialization expression inside the if condition:

if(size_t pos{ artist.find("Jimi") }; pos != string::npos) {
    cout << "found\n";
} else {
    cout << "not found\n";
}

Now the scope of the pos variable is confined to the scope of the conditional. This keeps your namespace clean and manageable.

How it works…

The initializer expression can be used in either if or switch statements. Here are some examples of each.

  • Use an initializer expression with an if statement:
    if(auto var{ init_value }; condition) {
        // var is visible 
    } else {
        // var is visible 
    } 
    // var is NOT visible 

The variable defined in the initializer expression is visible within the scope of the entire if statement, including the else clause. Once control flows out of the if statement scope, the variable will no longer be visible, and any relevant destructors will be called.

  • Use an initializer expression with a switch statement:
    switch(auto var{ init_value }; var) {
    case 1: ...
    case 2: ...
    case 3: ...
    ...
    Default: ...
    }
    // var is NOT visible 

The variable defined in the initializer expression is visible within the scope of the entire switch statement, including all the case clauses and the default clause, if included. Once control flows out of the switch statement scope, the variable will no longer be visible, and any relevant destructors will be called.

There's more…

One interesting use case is to limit the scope of a lock_guard that's locking a mutex. This becomes simple with an initializer expression:

if (lock_guard<mutex> lg{ my_mutex }; condition) { 
    // interesting things happen here 
}

The lock_guard locks the mutex in its constructor and unlocks it in its destructor. Now the lock_guard will be automatically destroyed when it runs out of the scope of the if statement. In the past you would have had to delete it or enclose the whole if statement in an extra block of braces.

Another use case could be using a legacy interface that uses output parameters, like this one from SQLite:

if(
    sqlite3_stmt** stmt, 
    auto rc = sqlite3_prepare_v2(db, sql, -1, &_stmt,
        nullptr);
    !rc) {
          // do SQL things
} else {  // handle the error 
    // use the error code 
    return 0;
}

Here I can keep the statement handle and the error code localized to the scope of the if statement. Otherwise, I would need to manage those objects globally.

Using initializer expressions will help keep your code tight and uncluttered, more compact, and easier to read. Refactoring and managing your code will also become easier.

Use template argument deduction for simplicity and clarity

Template argument deduction occurs when the types of the arguments to a template function, or class template constructor (beginning with C++17), are clear enough to be understood by the compiler without the use of template arguments. There are certain rules to this feature, but it's mostly intuitive.

How to do it…

In general, template argument deduction happens automatically when you use a template with clearly compatible arguments. Let's consider some examples.

  • In a function template, argument deduction usually looks something like this:
    template<typename T>
    const char * f(const T a) {
        return typeid(T).name();
    }
    int main() {
        cout << format("T is {}\n", f(47));
        cout << format("T is {}\n", f(47L));
        cout << format("T is {}\n", f(47.0));
        cout << format("T is {}\n", f("47"));
        cout << format("T is {}\n", f("47"s));
    }

Output:

T is int
T is long
T is double
T is char const *
T is class std::basic_string<char...

Because the types are easily discernable there is no reason to specify a template parameter like f<int>(47) in the function call. The compiler can deduce the <int> type from the argument.

Note

The above output shows meaningful type names where most compilers will use shorthand, like i for int and PKc for const char *, and so on.

  • This works just as well for multiple template parameters:
    template<typename T1, typename T2>
    string f(const T1 a, const T2 b) {
        return format("{} {}", typeid(T1).name(), 
            typeid(T2).name());
    }
    int main() {
        cout << format("T1 T2: {}\n", f(47, 47L));
        cout << format("T1 T2: {}\n", f(47L, 47.0));
        cout << format("T1 T2: {}\n", f(47.0, "47"));
    }

Output:

T1 T2: int long
T1 T2: long double
T1 T2: double char const *

Here the compiler is deducing types for both T1 and T2.

  • Notice that the types must be compatible with the template. For example, you cannot take a reference from a literal:
    template<typename T>
    const char * f(const T& a) {
        return typeid(T).name();
    }
    int main() {
        int x{47};
        f(47);  // this will not compile 
        f(x);   // but this will 
    }
  • Beginning with C++17 you can also use template parameter deduction with classes. So now this will work:
    pair p(47, 47.0);     // deduces to pair<int, double>
    tuple t(9, 17, 2.5);  // deduces to tuple<int, int, double>

This eliminates the need for std::make_pair() and std::make_tuple() as you can now initialize these classes directly without the explicit template parameters. The std::make_* helper functions will remain available for backward compatibility.

How it works…

Let's define a class so we can see how this works:

template<typename T1, typename T2, typename T3>
class Thing {
    T1 v1{};
    T2 v2{};
    T3 v3{};
public:
    explicit Thing(T1 p1, T2 p2, T3 p3)
    : v1{p1}, v2{p2}, v3{p3} {}
    string print() {
        return format("{}, {}, {}\n",
            typeid(v1).name(),
            typeid(v2).name(),
            typeid(v3).name()
        );
    }
};

This is a template class with three types and three corresponding data members. It has a print() function, which returns a formatted string with the three type names.

Without template parameter deduction, I would have to instantiate an object of this type like this:

Things<int, double, string> thing1{1, 47.0, "three" }

Now I can do it like this:

Things thing1{1, 47.0, "three" }

This is both simpler and less error prone.

When I call the print() function on the thing1 object, I get this result:

cout << thing1.print();

Output:

int, double, char const *

Of course, your compiler may report something effectively similar.

Before C++17, template parameter deduction didn't apply to classes, so you needed a helper function, which may have looked like this:

template<typename T1, typename T2, typename T3>
Things<T1, T2, T3> make_things(T1 p1, T2 p2, T3 p3) {
    return Things<T1, T2, T3>(p1, p2, p3);
}
...
auto thing1(make_things(1, 47.0, "three"));
cout << thing1.print();

Output:

int, double, char const *

The STL includes a few of these helper functions, like make_pair() and make_tuple(), etc. These are now obsolescent, but will be maintained for compatibility with older code.

There's more…

Consider the case of a constructor with a parameter pack:

template <typename T>
class Sum {
    T v{};
public:
    template <typename... Ts>
    Sum(Ts&& ... values) : v{ (values + ...) } {}
    const T& value() const { return v; }
};

Notice the fold expression in the constructor (values + ...). This is a C++17 feature that applies an operator to all the members of a parameter pack. In this case, it initializes v to the sum of the parameter pack.

The constructor for this class accepts an arbitrary number of parameters, where each parameter may be a different class. For example, I could call it like this:

Sum s1 { 1u, 2.0, 3, 4.0f };  // unsigned, double, int, 
                              // float
Sum s2 { "abc"s, "def" };     // std::sring, c-string

This, of course, doesn't compile. The template argument deduction fails to find a common type for all those different parameters. We get an error message to the effect of:

cannot deduce template arguments for 'Sum'

We can fix this with a template deduction guide. A deduction guide is a helper pattern to assist the compiler with a complex deduction. Here's a guide for our constructor:

template <typename... Ts>
Sum(Ts&& ... ts) -> Sum<std::common_type_t<Ts...>>;

This tells the compiler to use the std::common_type_t trait, which attempts to find a common type for all the parameters in the pack. Now our argument deduction works and we can see what types it settled on:

Sum s1 { 1u, 2.0, 3, 4.0f };  // unsigned, double, int, 
                              // float
Sum s2 { "abc"s, "def" };     // std::sring, c-string
auto v1 = s1.value();
auto v2 = s2.value();
cout << format("s1 is {} {}, s2 is {} {}",
        typeid(v1).name(), v1, typeid(v2).name(), v2);

Output:

s1 is double 10, s2 is class std::string abcdef

Use if constexpr to simplify compile-time decisions

An if constexpr(condition) statement is used where code needs to be executed based on a compile-time condition. The condition may be any constexpr expression of type bool.

How to do it…

Consider the case where you have a template function that needs to operate differently depending upon the type of the template parameter.

template<typename T>
auto value_of(const T v) {
    if constexpr (std::is_pointer_v<T>) {
        return *v;  // dereference the pointer
    } else {
        return v;   // return the value
    }
}
int main() {
    int x{47};
    int* y{&x};
    cout << format("value is {}\n", value_of(x));  // value
    cout << format("value is {}\n", value_of(y));  
                                                // pointer
    return 0;
}

Output:

value is 47
value is 47

The type of the template parameter T is available at compile time. The constexpr if statement allows the code to easily distinguish between a pointer and a value.

How it works…

The constexpr if statement works like a normal if statement except it's evaluated at compile time. The runtime code will not contain any branch statements from a constexpr if statement. Consider our branch statement from above:

if constexpr (std::is_pointer_v<T>) {
    return *v;  // dereference the pointer
} else {
        return v;   // return the value
    }

The condition is_pointer_v<T> tests a template parameter, which is not available at runtime. The constexpr keyword tells the compiler that this if statement needs to evaluate at compile time, while the template parameter <T> is available.

This should make a lot of meta programming situations much easier. The if constexpr statement is available in C++17 and later.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Become familiar with the latest features of C++20 and write better code using the STL
  • Reduce the development time for your applications and enable faster deployment
  • Get up and running with the new and leaner STL capabilities introduced in the latest release

Description

Fast, efficient, and flexible, the C++ programming language has come a long way and is used in every area of the industry to solve many problems. The latest version C++20 will see programmers change the way they code as it brings a whole array of features enabling the quick deployment of applications. This book will get you up and running with using the STL in the best way possible. Beginning with new language features in C++20, this book will help you understand the language's mechanics and library features and offer insights into how they work. Unlike other books, the C++20 STL Cookbook takes an implementation-specific, problem-solution approach that will help you overcome hurdles quickly. You'll learn core STL concepts, such as containers, algorithms, utility classes, lambda expressions, iterators, and more, while working on real-world recipes. This book is a reference guide for using the C++ STL with its latest capabilities and exploring the cutting-edge features in functional programming and lambda expressions. By the end of the book C++20 book, you'll be able to leverage the latest C++ features and save time and effort while solving tasks elegantly using the STL.

Who is this book for?

This book is for intermediate to advanced C++ programmers who want to get the most out of the Standard Template Library of C++20, the newest version of C++. Basic knowledge of coding and C++ concepts is necessary to get started with this book.

What you will learn

  • Understand the new language features and the problems they can solve
  • Implement generic features of the STL with practical examples
  • Understand standard support classes for concurrency and synchronization
  • Perform efficient memory management using the STL
  • Implement seamless formatting using std::format
  • Work with strings the STL way instead of handcrafting C-style code

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : May 27, 2022
Length: 450 pages
Edition : 1st
Language : English
ISBN-13 : 9781803239057
Category :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning

Product Details

Publication date : May 27, 2022
Length: 450 pages
Edition : 1st
Language : English
ISBN-13 : 9781803239057
Category :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 140.97
C++20 STL Cookbook
$46.99
Template Metaprogramming with C++
$46.99
Modern CMake for C++
$46.99
Total $ 140.97 Stars icon

Table of Contents

12 Chapters
Chaper 1: New C++20 Features Chevron down icon Chevron up icon
Chapter 2: General STL Features Chevron down icon Chevron up icon
Chapter 3: STL Containers Chevron down icon Chevron up icon
Chapter 4: Compatible Iterators Chevron down icon Chevron up icon
Chapter 5: Lambda Expressions Chevron down icon Chevron up icon
Chapter 6: STL Algorithms Chevron down icon Chevron up icon
Chapter 7: Strings, Streams, and Formatting Chevron down icon Chevron up icon
Chapter 8: Utility Classes Chevron down icon Chevron up icon
Chapter 9: Concurrency and Parallelism Chevron down icon Chevron up icon
Chapter 10: Using the File System Chevron down icon Chevron up icon
Chapter 11: A Few More Ideas Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5
(10 Ratings)
5 star 80%
4 star 10%
3 star 0%
2 star 0%
1 star 10%
Filter icon Filter
Top Reviews

Filter reviews by




Geraldo Netto Aug 29, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
First things first, STL used to be a double-edge sword and there are still some caveats due to various reasonsLuckily, C++ community is working hard to improve the language and fill the gaps to allow C++ to have "modern syntactic sugar" and C++ 20 reflects thisThe book is super easy to follow, I think even if you don't know much of C++ you can easily follow the "recipes" because it's "just enough code"Also, the book approaches other C++ 20 features like:- strings (seem to be trivial but bad usage of string formatting is one of the causes for most security vulnerabilities)- threads- iterators (the generators part is super cool! feels like python programming)- lambdasSome highlights:- explains C++ 20 STL features with "recipes"/examples including also the compilers who are supposed to have mature C++ 20 support- there is a specific recipe on how to avoid recompiling template which is interesting because it used to be a major problem (I have saw projects that would take hours to compile even on new hardware due to the heavy usage of templates)- string handling- threads with futures- iterators and lambdasWhile I understand that STL is the core of the bookOnce it extrapolates the STL scope when it talks about threads, strings and file system, I wish it could also consider the following:- I missed the compilation flag to enable C++ 20 support on gcc, clang, msvc (I don't recall seeing it although it is a really small thing)- coroutinesOverall it's a great introduction to STL and some nice modern features of C++
Amazon Verified review Amazon
POE Jun 03, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I am a seasoned C++ programmer and read this book to see if I could learn something new. I was impressed with how thoroughly the author covered the C++ Standard Template Library (STL). The book is clearly written for C++ developers, and I highly recommend it if you want to increase your C++ programming prowess.Packt Publishing’s cookbook format is ideally suited for this content. The recipes are organized into 11 categories. Each recipe contains sections on ‘how to do it’ and ‘how it works.’ Many of the sections also include ‘see also’ or ‘there’s more’ that includes related and deeper concepts. The book does start with an STL primer, albeit short. This is okay as it is written for current C++ developers. Before diving into the individual recipes, the book covers new features that C++20 adds to the STL. The publisher has made all the book’s code available via GitHub.This book will be a great addition to your C++ library, at least until the C++23 standard is finalized in 2023.
Amazon Verified review Amazon
Mohammad Huwaidi Aug 31, 2023
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book is worth having. I like concise books.
Amazon Verified review Amazon
Jose Perez Jun 09, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I'm in love with this book. Great work.
Amazon Verified review Amazon
Daren R. Jun 02, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This is a fantastic book and I like the writing style of Bill Weinman. I have found this book to be an invaluable reference that has helped me get the most out of the new features that C++ 20 adds to the STL. I have now started to include concepts from this book into parts of my C++ code base modernisation.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.