C++17 introduced a handy construct called structured binding:
Structured bindings are used to decompose arrays and structs/classes 1 to named subobjects. Almost any object with non-static, accessible data members can be destructured this way. It works even for bit-fields:
Resulting aliases (
y in the examples above) are actually not mere variables but rather identifiers or aliases.
This may feel unintuitive but there actually is a case when we cannot use these aliases as other variables. According to this C++ Language Standard working draft we cannot use structured bindings in lambda capture list:
If a lambda-expression explicitly captures an entity that is not odr-usable or captures a structured binding (explicitly or implicitly), the program is ill-formed.
(emphasis mine). That means following code is illegal:
It actually works on
gcc (10.3) and
msvc (v19.28) but fails on
error: ‘b’ in capture list does not name a variable
This restriction does not apply for init-captures, which is reasonable as with init-captures there is a new variable defined that is captured and this variable is no longer the structure binding, so this compiles well in
The standard got reworded along the way and in C++ 20 final working draft the restriction is no longer there. But
clang still fails, even with
msvc are fine with both simple- and init-capture of the structured binding. I feel way more comfortable with
msvc way as there is no need to provide special construct only to capture a single value.
Interesting resources (click to expand)
- C++ Language Standard working draft N4713 (2017-11-27)
- C++20 Language Standard final working draft N4861 (2020-04-01)
- Why structured bindings can’t declare variables? a Reddit post
- Lambda implicit capture fails with variable declared from structured binding Stack overflow thread
- Reference capture of structured bindings: a Public Proposal (2019-02-22)
- Changes between C++17 and C++20 DIS “Improvements for structured bindings” listed here (2020-03-02)
- A brief introduction to C++ structured binding by Raymond on devblogs.microsoft.com
Comments on dev.to.