What are use cases for structured bindings?

Viewed 11320

C++17 standard introduces a new structured bindings feature, which was initially proposed in 2015 and whose syntactic appearance was widely discussed later.

Some uses for them come to mind as soon as you look through documentation.

Aggregates decomposition

Let's declare a tuple:

std::tuple<int, std::string> t(42, "foo");

Named elementwise copies may be easily obtained with structured bindings in one line:

auto [i, s] = t;

which is equivalent to:

auto i = std::get<0>(t);
auto s = std::get<1>(t);

or

int i;
std::string s;
std::tie(i, s) = t;

References to tuple elements can also be obtained painlessly:

auto& [ir, sr] = t;
const auto& [icr, scr] = t;

So we can do with arrays or structs/classes whose all members are public.

Multiple return values

A convenient way to get multiple return values from a function immediately follows from the above.

What else?

Can you provide some other, possibly less obvious use cases for structured bindings? How else can they improve readability or even performance of C++ code?

Notes

As it were mentioned in comments, current implementation of structured bindings lacks some features. They are non-variadic and their syntax does not allow to skip aggregate members explicitly. Here one can find a discussion about variadicity.

4 Answers

Barring evidence to the contrary, I think Structured Bindings are merely a vehicle to deal with legacy API. IMHO, the APIs which require SB should have been fixed instead.

So, instead of

auto p = map.equal_range(k);
for (auto it = p.first; it != p.second; ++it)
    doSomethingWith(it->first, it->second);

we should be able to write

for (auto &e : map.equal_range(k))
    doSomethingWith(e.key, e.value);

Instead of

auto r = map.insert({k, v});
if (!r.second)
    *r.first = v;

we should be able to write

auto r = map.insert({k, v});
if (!r)
    r = v;

etc.

Sure, someone will find a clever use at some point, but to me, after a year of knowing about them, they are still an unsolved mystery. Esp. since the paper is co-authored by Bjarne, who's not usually known for introducing features that have such a narrow applicability.

Initializing multiple variables of different types in an if statement; for instance,

if (auto&& [a, b] = std::pair { std::string { "how" }, 4U }; a.length() < b)
   std::cout << (a += " convenient!") << '\n';
Related