Book Image

C++20 STL Cookbook

By : Bill Weinman
Book Image

C++20 STL Cookbook

By: Bill Weinman

Overview of this book

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.
Table of Contents (13 chapters)

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."