Home Programming C++17 STL Cookbook

C++17 STL Cookbook

By Jacek Galowicz
books-svg-icon Book
Subscription FREE
eBook + Subscription $12.99
eBook $43.99
Print + eBook $54.99
READ FOR FREE Free Trial for 7 days. $12.99 p/m after trial. Cancel Anytime! BUY NOW BUY NOW BUY NOW
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
READ FOR FREE Free Trial for 7 days. $12.99 p/m after trial. Cancel Anytime! BUY NOW BUY NOW BUY NOW
Subscription FREE
eBook + Subscription $12.99
eBook $43.99
Print + eBook $54.99
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
  1. Free Chapter
    The New C++17 Features
About this book
C++ has come a long way and is in use in every area of the industry. Fast, efficient, and flexible, it is used to solve many problems. The upcoming version of C++ will see programmers change the way they code. If you want to grasp the practical usefulness of the C++17 STL in order to write smarter, fully portable code, then this book is for you. Beginning with new language features, this book will help you understand the language’s mechanics and library features, and offers insight into how they work. Unlike other books, ours takes an implementation-specific, problem-solution approach that will help you quickly overcome hurdles. You will learn the core STL concepts, such as containers, algorithms, utility classes, lambda expressions, iterators, and more, while working on practical real-world recipes. These recipes will help you get the most from the STL and show you how to program in a better way. By the end of the book, you will be up to date with the latest C++17 features and save time and effort while solving tasks elegantly using the STL.
Publication date:
June 2017
Publisher
Packt
Pages
532
ISBN
9781787120495

 

Chapter 1. The New C++17 Features

In this chapter, we will cover thefollowing recipes:

  • Using structured bindings to unpack bundled return values
  • Limiting variable scopes to if and switch statements
  • Profiting from the new bracket initializer rules
  • Letting the constructor automatically deduce the resulting template class type
  • Simplifying compile-time decisions with constexpr-if
  • Enabling header-only libraries with inline variables
  • Implementing handy helper functions with fold expressions
 

Introduction


C++ got a lot of additions in C++11, C++14, and, most recently, C++17. By now, it is a completely different language compared to what it was just a decade ago. The C++ standard does not only standardize the language, as it needs to be understood by the compilers, but also the C++ standard template library (STL).

This book explains how to put the STL to the best use with a broad range of examples. But at first, this chapter will concentrate on the most important new language features. Mastering them will greatly help you write readable, maintainable, and expressive code a lot.

We will see how to access individual members of pairs, tuples, and structures comfortably with structured bindings and how to limit variable scopes with the newif and switch variable initialization capabilities. The syntactical ambiguities, which were introduced by C++11 with the new bracket initialization syntax, which looks the same for initializer lists, were fixed bynew bracket initializer rules. The exacttypeof template class instances can now bededucedfrom the actual constructor arguments, and if different specializations of a template class will result in completely different code, this is now easily expressible with constexpr-if. The handling of variadic parameter packs in template functions became much easier in many cases with the newfold expressions. At last, it became more comfortable to define static globally accessible objects in header-only libraries with the new ability to declare inline variables, which was only possible for functions before.

Some of the examples in this chapter might be more interesting for implementers of libraries than for developers who implement applications. While we will have a look at such features for completeness reasons, it is not too critical to understand all the examples of this chapter immediately in order to understand the rest of this book.

 

Using structured bindings to unpack bundled return values


C++17 comes with a new feature, which combines syntactic sugar and automatic type deduction: structured bindings. These help to assign values from pairs, tuples, and structs into individual variables. In other programming languages, this is also called unpacking.

How to do it...

Applying a structured binding in order to assign multiple variables from one bundled structure is always one step. Let's first see how it was done before C++17. Then, we can have a look at multiple examples that show how we can do it in C++17:

  • Accessing individual values of an std::pair: Imagine we have a mathematical function, divide_remainder, which accepts a dividend and a divisor parameter and returns the fraction of both as well as the remainder. It returns those values using an std::pair bundle:
        std::pair<int, int> divide_remainder(int dividend, int divisor);

Consider the following way of accessing the individual values of the resulting pair:

        const auto result (divide_remainder(16, 3));
        std::cout << "16 / 3 is " 
                  << result.first << " with a remainder of " 
                  << result.second << '\n';

Instead of doing it as shown in the preceding code snippet, we can now assign the individual values to individual variables with expressive names, which is much better to read:

        auto [fraction, remainder] = divide_remainder(16, 3);
        std::cout << "16 / 3 is " 
                  << fraction << " with a remainder of "       
                  << remainder << '\n';
  • Structured bindings also work with std::tuple: Let's take the following example function, which gets us online stock information:
        std::tuple<std::string, 
                   std::chrono::system_clock::time_point, unsigned>
        stock_info(const std::string &name);

Assigning its result to individual variables looks just like in the example before:

        const auto [name, valid_time, price] = stock_info("INTC");
  • Structured bindings also work with custom structures: Let's assume a structure like the following:
        struct employee {
            unsigned id;
            std::string name;
            std::string role;
            unsigned salary;
        };

Now, we can access these members using structured bindings. We can even do that in a loop, assuming we have a whole vector of those:

        int main()
        {
            std::vector<employee> employees {
                /* Initialized from somewhere */};

            for (const auto &[id, name, role, salary] : employees) {
                std::cout << "Name: "   << name
                          << "Role: "   << role
                          << "Salary: " << salary << '\n';
            }
        }

How it works...

Structured bindings are always applied with the same pattern:

auto [var1, var2, ...] = <pair, tuple, struct, or array expression>;
  • The list of variables var1, var2, ... must exactly match the number of variables contained by the expression being assigned from.
  • The <pair, tuple, struct, or array expression> must be one of the following:
    • An std::pair.
    • An std::tuple.
    • A struct. All members must be non-static and defined in the same base class. The first declared member is assigned to the first variable, the second member to the second variable, and so on.
    • An array of fixed size.
  • The type can be auto, const auto, const auto&, and even auto&&.

Note

Not only for the sake of performance, always make sure to minimize needless copies by using references when appropriate.

If we write too many or not enough variables between the square brackets, the compiler will error out, telling us about our mistake:

std::tuple<int, float, long> tup {1, 2.0, 3};
auto [a, b] = tup; // Does not work

This example obviously tries to stuff a tuple variable with three members into only two variables. The compiler immediately chokes on this and tells us about our mistake:

error: type 'std::tuple<int, float, long>' decomposes into 3 elements, but only 2 names were provided
auto [a, b] = tup;

There's more...

A lot of fundamental data structures from the STL are immediately accessible using structured bindings without us having to change anything. Consider, for example, a loop that prints all the items of an std::map:

std::map<std::string, size_t> animal_population {
    {"humans",   7000000000},
    {"chickens", 17863376000},
    {"camels",   24246291},
    {"sheep",    1086881528},
    /* … */
};

for (const auto &[species, count] : animal_population) {
    std::cout << "There are " << count << " " << species 
              << " on this planet.\n";
}

This particular example works because when we iterate over an std::map container, we get the std::pair<const key_type, value_type> nodes on every iteration step. Exactly these nodes are unpacked using the structured bindings feature (key_type is the species string and value_type is the population count size_t) in order to access them individually in the loop body.

Before C++17, it was possible to achieve a similar effect using std::tie:

int remainder;
std::tie(std::ignore, remainder) = divide_remainder(16, 5);
std::cout << "16 % 5 is " << remainder << '\n';

This example shows how to unpack the resulting pair into two variables. The std::tie is less powerful than structured bindings in the sense that we have to define all the variables we want to bind to before. On the other hand, this example shows a strength of std::tie that structured bindings do not have: the value std::ignore acts as a dummy variable. The fraction part of the result is assigned to it, which leads to that value being dropped because we do not need it in that example.

Note

When using structured bindings, we don't have tie dummy variables, so we have to bind all the values to named variables. Doing so and ignoring some of them is efficient, nevertheless, because the compiler can optimize the unused bindings out easily.

Back in the past, the divide_remainder function could have been implemented in the following way, using output parameters:

bool divide_remainder(int dividend, int divisor, 
                      int &fraction, int &remainder);

Accessing it would have looked like the following:

 

int fraction, remainder;
const bool success {divide_remainder(16, 3, fraction, remainder)};
if (success) {
    std::cout << "16 / 3 is " << fraction << " with a remainder of " 
              << remainder << '\n';
}

A lot of people will still prefer this over returning complex structures like pairs, tuples, and structs, arguing that this way the code would be faster, due to avoided intermediate copies of those values. This is not true any longer for modern compilers, which optimize intermediate copies away.

Note

Apart from the missing language features in C, returning complex structures via return value was considered slow for a long time because the object had to be initialized in the returning function and then copied into the variable that should contain the return value on the caller side. Modern compilers support return value optimization (RVO), which enables for omitting intermediate copies.

           
About the Author
  • Jacek Galowicz

    Jacek Galowicz obtained his master of science in electrical engineering/computer engineering at RWTH Aachen University, Germany. While at university, he enjoyed working as a student assistant in teaching and research, and he participated in several scientific publications. During and after his studies, he worked as a freelancer and implemented applications as well as kernel drivers in C and C++, touching various areas, including 3D graphics programming, databases, network communication, and physics simulation. In recent years, he has been programming performance- and security-sensitive microkernel operating systems for Intel x86 virtualization at Intel and FireEye in Braunschweig, Germany. He has a strong passion for modern C++ implementations of low-level software, and he tries hard to combine high performance with an elegant coding style. Learning purely functional programming and Haskell in recent years triggered his drive to implement generic code with the aid of meta programming.

    Browse publications by this author
Latest Reviews (14 reviews total)
Interesting book, but I've not still finish reading it.
I am fully satisfied by this item, too.
Very illuminating an the new C++17 features
Recommended For You
C++17 STL Cookbook
Unlock this book and the full library FREE for 7 days
Start now