Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
C++20 STL Cookbook

You're reading from   C++20 STL Cookbook Leverage the latest features of the STL to solve real-world problems

Arrow left icon
Product type Paperback
Published in May 2022
Publisher Packt
ISBN-13 9781803248714
Length 450 pages
Edition 1st Edition
Tools
Arrow right icon
Author (1):
Arrow left icon
Bill Weinman Bill Weinman
Author Profile Icon Bill Weinman
Bill Weinman
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

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

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.

You have been reading a chapter from
C++20 STL Cookbook
Published in: May 2022
Publisher: Packt
ISBN-13: 9781803248714
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image