This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118f. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-11-19


3131. Value categories and types for the range in iterable expansion statements

Section: 8.7  [stmt.expand]     Status: open     Submitter: Jakub Jelinek     Date: 2025-11-13

(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 constant evaluation to fail.

Furthermore, in order to allow expansion over non-constant std::array (which does have a compile-time size), the constexpr in the range declaration should be optional, similar to the destructuring case.

Possible resolution:

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