Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying C++ STL Cookbook
  • Table Of Contents Toc
C++ STL Cookbook

C++ STL Cookbook - Second Edition

By : Bill Weinman
close
close
C++ STL Cookbook

C++ STL Cookbook

By: Bill Weinman

Overview of this book

C++ STL Cookbook is a comprehensive guide that provides practical solutions for mastering the latest features of the C++23 Standard Template Library (STL) through hands-on recipes. Beginning with new features in C++23, this book will help you understand the language's updated mechanics and library features, and offer insights into how they work. Unlike other books, this 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, through specific real-world recipes. Building on the success of the first edition, this updated guide includes a new chapter dedicated to the latest features introduced in C++23, such as improved modules, refined ranges, and coroutine-based generators. It also covers essential best practices for writing cleaner and more efficient code, including the use of coroutines, structured bindings, and std::span. Whether you're looking to deepen your understanding of the C++ STL or implement the latest features in your projects, this book provides valuable insights, clear and concise explanations and practical solutions to enhance your C++ programming skills.
Table of Contents (15 chapters)
close
close
14
Index

Initialize containers from ranges

Beginning with C++23, we can now initialize a container directly from a range or view.

Until now, to initialize a container from a range we could use a for loop:

vector<int> v {};
for (auto n : views::iota(1, 11)) {
    v.push_back(n);
}

Or we could construct the vector from the range iterators:

auto r = views::iota(1, 11);
vector<int> v(r.begin(), r.end());

In C++23, this becomes much easier with the new ranges::to class:

auto v = views::iota(1, 11) | ranges::to<vector<int>>();

This new pattern is both simpler and clearer. The ranges::to class is defined in the <ranges> header.

How to do it

The ranges::to class takes any range or view as input via the pipe syntax and returns a new non-view object.

  • For convenience, we first declare namespace aliases for ranges and views:
    namespace ranges = std::ranges;
    namespace views = ranges::views;
  • We start by populating a vector from a view:
    auto vec = views::iota(1, 11)
        | views::transform([](const auto n){ return n * 5; })
        | ranges::to<vector>();
    for (auto n : vec) print("{} ", n);
    print("\n");

    In this example, views::iota(1, 11) generates a sequence of integers from 1 to 10. We then use views::transform with a lambda function to multiply each integer by 5. Finally, ranges::to<vector>() returns a new vector for our initialization.

    The function call operator (parentheses) after ranges::to<> is required for use with the pipe syntax:

    auto vec = r | ranges::to<vector>;   // syntax error
    auto vec = r | ranges::to<vector>(); // correct usage

    This produces the output:

    5 10 15 20 25 30 35 40 45 50
  • You may use this technique to initialize any sequential container:
    auto lst = vec | views::reverse
        | ranges::to<list<double>>();
    for (auto d : lst) print("{} ", d);
    print("\n");

    In this example, we use views::reverse to reverse the order of the sequence, and ranges::to<list<double>>() to construct a list of double, which produces the output:

    50 45 40 35 30 25 20 15 10 5

Let's take a look at how this works.

How it works

The ranges::to class is designed to work in a variety of contexts. To return a container C from range R, it considers a series of scenarios and chooses the first valid method from the list:

  • Construct C from R
  • Construct C from R using a tagged range constructor (from_range_t)
  • Construct C from the range iterators R.begin(), R.end()
  • Construct C, then insert each element of R at the end of C
  • If C is a range whose value type is itself a range (and is not a view), and R's value type is also a range, for each element of R, a value of to<range_value_t> is inserted at the end of C

This allows a more unified and concise syntax for constructing containers from ranges.

CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
C++ STL Cookbook
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist download Download options font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon