C++ Logo

std-proposals

Advanced search

Re: [std-proposals] PROPOSAL: Nested structured bindings

From: Fabio Alemagna <falemagn_at_[hidden]>
Date: Tue, 22 Sep 2026 12:19:19 +0200
One obvious alternative that sticks out, to me, is using curly braces for
nested binding.

Curly braces were firstly proposed by P0144, but then the consensus shifted
towards the square brackets. Going back to curly braces is now impossible
because of C++ 23 valid `auto {x} = y` syntax, however it's entirely
possible to use curly braces for the nested bindings exclusively, like this:

auto [a, {b, {c, d}}, e] = f();

And, honestly, it feels the most natural approach to me.

Fabio

Il giorno lun 21 set 2026 alle ore 15:56 Thibault Ricord-Marchal via
Std-Proposals <std-proposals_at_[hidden]> ha scritto:

> Maybe a better syntax for it would be to inspire from designated
> initializers, with the dot-prefix.
>
> Like so:
> ˋˋˋcpp
> std::map<std::pair<int, std::string>, std::tuple<bool, float, char>>
> horrible_map { make_nightmare_map() };
>
> for (auto& [ .[id, name], .[isFoo, price, symbol] ]: horrible_map) {
> // ...
> }
> ˋˋˋ
>
> I believe this would disembiguate syntaxe from attributes as ˋ[[ˋ is not a
> valid structured binding opening syntax.
> For uniformity I also would allow (but not force) having a do even when
> not introducing a sub-binding:
>
> ˋˋˋcpp
> auto [.id, .name] = get_my_pair();
> ˋˋˋ
>
> Le lun. 21 sept. 2026, 15:29, Jan Schultke via Std-Proposals <
> std-proposals_at_[hidden]> a écrit :
>
>> Thanks for providing a more concrete example.
>>
>> However, this is presenting a false dichotomy. You could also use
>> addr.building and addr.country in subsequent code; you don't have to
>> std::move out of the bindings. If you only needed name and country, it
>> would be tedious to destructure everything, so it's a case-by-case thing
>> whether the nested destructuring is helpful or harmful.
>>
>> Without a more complete example, it's not possible to make a judgment
>> here.
>>
>> The issue of std::pair and std::tuple can also be solved by making a
>> simple aggregate with proper names. I personally consider std::pair
>> "never use" and std::tuple "only use for variadics". If you avoid these,
>> you don't end up bullying yourself into structured bindings as the result
>> of .first and .second being bad names.
>>
>> On Mon, 21 Sept 2026 at 15:24, HHN <harihara.sn_at_[hidden]> wrote:
>>
>>> The lack of nested sb first irked me when using dealing with maps where
>>> the value is a pair / tuple.
>>>
>>> This would obviously also extends to unpacking nested structs easily.
>>>
>>> Example:
>>> struct Address
>>> {
>>> std::string building;
>>> std::string pincode;
>>> std::string country;
>>> };
>>>
>>> struct Person
>>> {
>>> std::string name;
>>> Address addr;
>>> };
>>>
>>> auto [name, (building, pincode, country)] = make_person();
>>>
>>> // current alternative
>>> auto [name, addr] = make_person();
>>> auto [building, pincode, country] = std::move(addr); // forces move on
>>> building, pincode, country
>>>
>>>
>>> Godbolt link showcasing copies / moves: https://godbolt.org/z/r6aoTEd3f
>>>
>>> The proposal is not just purely to reduce verbosity, but also helps
>>> elide moves / copies
>>> I do believe unpacking nested packs (structs / pairs / tuples) would not
>>> be uncommon and having an elegant way to do it is definitely be well worth
>>> the effort.
>>>
>>> On Mon, Sep 21, 2026 at 6:04 PM Jan Schultke <janschultke_at_[hidden]>
>>> wrote:
>>>
>>>> Personally, I would find the use of parentheses quirky here, but square
>>>> brackets don't work because [[ and ]] are meant to be for attributes
>>>> always.
>>>>
>>>> Maybe if you had some really good motivating examples that show where
>>>> you need nested structured bindings frequently, I could be convinced, but
>>>> otherwise from me, it's a big
>>>>
>>>> eh, not worth the trouble, and we can't have nice syntax for it
>>>>
>>>>
>>>> The example that you have provided seems to use an artificially long
>>>> name for the bindings rather than e.g. [key, val] in order to make the
>>>> savings seem more significant. Do you have some real-world examples?
>>>>
>>>>
>>>> On Mon, 21 Sept 2026 at 14:15, HHN via Std-Proposals <
>>>> std-proposals_at_[hidden]> wrote:
>>>>
>>>>> Currently structured bindings do not allow for nested bindings.
>>>>>
>>>>> std::map<Identifier, std::pair<Handle, Context>> map;
>>>>>
>>>>> // to get a copy of identifier, handle and info
>>>>> for (const auto &[identifierRef, handleWithContextRef] : map)
>>>>> {
>>>>> auto identifier = identifierRef;
>>>>> auto [handle, context] = handleWithContextRef;
>>>>> }
>>>>>
>>>>> // Suggested replacement
>>>>> for(auto [identifier, (handle, context)]: map)
>>>>> {
>>>>> }
>>>>>
>>>>> All sb-identifiers in the structured-binding-declaration will have the
>>>>> same reference qualifier.
>>>>>
>>>>> *Updated in the C++ grammar*
>>>>>
>>>>> sb-identifier :
>>>>> ...opt identifier attribute-specifier-seqopt
>>>>> ( sb-identifier-list ) // new production rule
>>>>>
>>>>> sb-identifier-list :
>>>>> sb-identifier
>>>>> sb-identifier-list , sb-identifier
>>>>>
>>>>> structured-binding-declaration :
>>>>> attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [
>>>>> sb-identifier-list ]
>>>>>
>>>>>
>>>>> I have attached an argument
>>>>> <https://gist.github.com/Johan511/3bbae06c683fd343a08aa6c50f1de0ed> that
>>>>> this won't cause any parsing ambiguities
>>>>>
>>>>> --
>>>>> Hari Hara Naveen
>>>>> --
>>>>> Std-Proposals mailing list
>>>>> Std-Proposals_at_[hidden]
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>>
>>>>
>>>
>>> --
>>> Hari Hara Naveen
>>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2026-09-22 10:19:35