This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
(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.
Possible resolution:
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 constexprwhere N is ...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 }