C++17 introduced a language feature called “structured bindings” which allows you to bind names to elements of another object easily. This makes your code more concise and easier to read, and also drives down maintenance costs. In this quick tip, we’ll take a look at how structured bindings work and give some examples of how you might use them in your own programs.

Accessing std::tuple

std::tuple is an extremely useful way to quickly combine multiple objects into a single object. I have used this often to combine various items that I want to serialize into a single byte stream for transmission somewhere (typically using MessagePack, for example see my code in the zRPC library). You can also use them effectively to return multiple values from a function (similar to std::pair, which is basically just a tuple of two objects).

When using std::tuple the canonical way of gaining access to the members of the tuple is to use std::get<T> like so:

// Given std::tuple<int, std::string, ExampleObject>
const int i = std::get<0>(tpl);
const std::string s = std::get<1>(tpl);
const ExampleObject o = std::get<2>(tpl);
Code language: C++ (cpp)

This always felt clunky to me, yet the benefits of tuples were tremendous, so I just dealt with it.

Structured Binding Approach

Fast-forward to the C++17 standard and the ability to use structured bindings. These allow you to tie names to elements of any object, std::tuple included! Now, your access to the tuple becomes a single line:

// Given std::tuple<int, std::string, ExampleObject>
const auto [i,s,o] = tpl; // decltype(i) = int
                          // decltype(s)=std::string
                          // decltype(o)=ExampleObject
Code language: C++ (cpp)

So much cleaner and easier for the developer to read and follow!

You can also get fancy with dealing with multiple return values from a function (see C++ Core Guidline F.21):

ExampleObject obj;
bool success{false};

// Use structured binding to get object and success value
// If creation succeeds, then process it
if (auto [obj, success] = createObject(); success) processObject(obj);
Code language: C++ (cpp)

Structured bindings are a great new feature in C++17. They make your code more readable and maintainable, and they’re easier to parse for humans. I think you’ll find that they make your life a lot easier. What are some ways you see yourself using them in your own code?

Last modified: January 30, 2023

Author

Comments

Write a Reply or Comment

Your email address will not be published.