Structured Binding

Structured binding, introduced in C++17, is the ability to decompose an object into its subobjects or elements and bind them to, for example, variables.

std::tuple<int, int, int> a = {1, 2, 3};
auto [x, y, z] = a; // structured binding
// x = 1, y = 2, z = 3

Simulating structured binding with std::tie and unpacking

Not all code bases are C++17 or, frankly, will ever migrate to C++17 (but they definitely should). Fear not! There is still a way to acheive a subset of the functionality in C++14 and C++11 using std::tie unpacking.

#include <tuple>
std::tuple<int, int, int> a = {1, 2, 3};
int x, y, z;
std::tie(x, y, z) = a; // unpacking
// x = 1, y = 2, z = 3

The major syntactic difference is that variables need to be declared prior to use with std::tie, something that is done for you in structured binding.

Limitations of std::tie unpacking

Big caveat: std::tie unpacking is only compatible with std::tuple, std::pair, and derivative objects. This means C arrays, std::array, and struct fields will only work with structured binding.

Structured binding only:

std::array<int, 2> a = {1, 2};
auto [x, y] = a;
// x = 1, y = 2

struct Foo { int a; int b; };
Foo f{0, 1};
auto [i, j] = f;
// i = 0, j = 1

Ignoring unpacked elements with std::ignore

If using std::tie unpacking, the STL provides std::ignore to ignore any unneeded values.

std::tuple<int, int, int> a = {1, 2, 3};
int x, z;
std::tie(x, std::ignore, z) = a;
// x = 1, y = 2, z = 3

This can’t be done with structured binding; each value must be bound.