Pre-C++17 Alternative to C++ 17 Structured Binding: Unpacking
Not everyone has C++17 available. std::tie unpacking is a limited pre-C++17 alternative.
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.