Skip to content

CWG3048 [stmt.expand] Zero "iterations" only possible for iterating and enumerating expansion statements #743

Description

@jakubjelinek

Full name of submitter (unless configured in github; will be published with the issue): Jakub Jelinek

Reference (section label): stmt.expand

Link to reflector thread (if any):

Issue description: Right now both iterating and enumerating expansion statements can have zero "iterations", the former if begin is the same as end, the latter for {}. But for destructuring expansion statements, I believe it has to have at least one iteration, because a valid structured binding declaration needs to have at least one name. While with structured binding packs one can have zero, i.e. if ihttps://eel.is/c++draft/stmt.expand#5.3 was instead constexpropt auto&& [...u] = expansion-initializer; and for-range-declaration = u...[i]; then it would allow also zero "itereations". Though, structured binding packs can only appear in templates, so such a change isn't possible, it would need to be some special case.

Suggested resolution:

Activity

  1. jensmaurer commented on Aug 9, 2025

    @jensmaurer
    Member

    I'm reading the above as "the specification of destructuring expansion statements needs a special case for N=0, because the syntactic rewrite is not well-formed for that case".

  2. jakubjelinek commented on Aug 9, 2025

    @jakubjelinek
    Author

    Right. Whether it needs it or not (and can stay as is) will defer to CWG.

  3. jensmaurer commented on Aug 10, 2025

    @jensmaurer
    Member
  4. changed the title [-][stmt.expand] Zero "iterations" only possible for iterating and enumerating expansion statements[/-] [+]CWG3048 [stmt.expand] Zero "iterations" only possible for iterating and enumerating expansion statements[/+] on Aug 10, 2025
  5. t3nsor commented on Aug 10, 2025

    @t3nsor

    The section label is wrong, it should be [stmt.expand].

    I think this resolution isn't quite right because it doesn't check all the semantic constraints that an empty structured binding declaration would have (if written using a pack in a templated context). For example, it doesn't check constexpr if present and it doesn't try to instantiate std::tuple_size<E>. I think we're better off trying to find a way to say that we still treat it as a structured binding declaration even though it would be ill-formed to write it directly.

  6. jensmaurer commented on Aug 11, 2025

    @jensmaurer
    Member

    In order to determine N, we need to instantiate tuple_size, I think. [dcl.struct.bind] p7

  7. jakubjelinek commented on Aug 11, 2025

    @jakubjelinek
    Author

    Yes. For the constexpr if present it could just be
    constexpropt auto && range = expansion-initializer;
    in the N == 0 case instead of (void) expansion-initializer;. Though, I think N should be introduced before it is used in the N == 0 case.

  8. jensmaurer commented on Aug 11, 2025

    @jensmaurer
    Member

    I've fixed CWG3048. I haven't done anything about "N"; the general pattern is "rewrite ... where N is ..."
    so N is already introduced too late.

  9. t3nsor commented on Aug 11, 2025

    @t3nsor

    In order to determine N, we need to instantiate tuple_size, I think. [dcl.struct.bind] p7

    Right, my bad. It looks like [dcl.struct.bind] checks all the constraints before telling us the structured binding size, so the proposed resolution looks good now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions