8

Structured bindings do not allow empty decomposable types.

auto [] = std::make_tuple(); // error

Ever since P1061R10 has been accepted for C++26, this allows structured bindings to introduce packs (as long as the pack is declared within template context):

auto [...args] = return_empty_tuple();
auto [one, ...rest] = return_single_tuple();

The latter allows ...rest to be an empty pack if return_single_tuple() has a structured binding size of 1.

My question is, can ...args still be declared as an empty pack even if return_empty_tuple() has a zero structured binding size (e.g. zero tuple size)?

0

2 Answers 2

8

P1061R10 mentions "empty" twice, but doesn't answer your question directly and the latest C++26 draft doesn't include the wording for P1061 yet, but, I dare to say Yes.

In P1061, the authors show many examples of how letting structured bindings introduce packs simplifies generic code where std::apply must be used today, sometimes in multiple layers. Even the implementation of std::apply itself could be simplified to

template <class F, class Tuple>
constexpr decltype(auto) apply(F &&f, Tuple &&t) {
    auto&& [...elems] = t;
    return std::invoke(std::forward<F>(f),
                       forward_like<Tuple, decltype(elems)>(elems)...);
}

according to the proposal. If empty packs will not be allowed, this implementation of std::apply would not work, and neither would many other situations in generic code.

Therefore, it's without question that the authors meant for empty packs to be allowed.

(Also, the experimental implementation of P1061 in Clang accepts them: Demo)

Sign up to request clarification or add additional context in comments.

Comments

2

The wording of P1061R10 contains the following:

A structured binding pack is an sb-identifier that introduces zero or more structured bindings ([dcl.struct.bind]).

This indicates that it is permissible for a structured binding pack to introduce 0 structured bindings, which was already pointed out by the OP.

The OP's question is whether the structured binding size is also allowed to be 0. There does not seem to be anything in the paper that would forbid it. Therefore, it is covered by the general rule in [temp.variadic]/8:

[...] When N is zero, the instantiation of a pack expansion does not alter the syntactic interpretation of the enclosing construct, even in cases where omitting the pack expansion entirely would otherwise be ill-formed or would result in an ambiguity in the grammar.

For example, template <class... Bases> struct T : Bases... {}; is well-formed even when Bases is an empty pack; it does not become equivalent to struct T : {}; which would be ill-formed because there is nothing after the colon. Similarly, auto [...args] = return_empty_tuple(); should be well-formed and introduce zero structured bindings even though it would be ill-formed to write auto [] = return_empty_tuple();.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.