Title
Value categories and types for the range in iterable expansion statements
Status
ready
Section
8.7 [stmt.expand]
Submitter
Jakub Jelinek

Created on 2025-11-13.00:00:00 last changed 1 week ago

Messages

Date: 2026-03-26.09:52:47

Proposed resolution (approved by CWG 2026-03-26):

Change in 8.7 [stmt.expand] bullet 5.2 as follows:



  • ...
  • Otherwise, if S is an iterating expansion statement, S is equivalent to:
      {
        init-statement
        constexpr auto&& decltype(auto) range = (expansion-initializer) ;
        constexpr auto begin = begin-expr;  // see 8.6.5 [stmt.ranged]
        constexpr auto end = end-expr;      // see 8.6.5 [stmt.ranged]
        S0
        .
        .
        .
        SN-1
      }
    
    where N is ...
Date: 2026-03-26.09:52:47

(From submission #805.)

Consider:

  #include <span>

  constexpr int arr[3] = { 1, 2, 3 };
  consteval std::span<const int> foo() {
    return std::span<const int>(arr);
  }

  int main() {
    int r = 0;
    template for (constexpr auto m : foo())
      r += m;
  }

The expansion of this iterable expansion statement contains:

   constexpr auto &&range = foo();

The deduction yields std::span<const int>&& for the type of range, and the non-const lifetime-extended temporary causes later constant evaluation in the expansion to fail.

History
Date User Action Args
2026-03-26 09:52:47adminsetstatus: open -> ready
2025-11-19 21:24:58adminsetmessages: + msg8406
2025-11-13 00:00:00admincreate