C++26 removes the initializer_list constructor of std::span
bool data[4] = {true, false, true, false};
const bool* ptr = data;
std::size_t n = 4;
std::span<const bool> s{ptr, n}; // how many elements?
In C++23 this calls the pointer and count constructor, and s.size() is 4. The C++26 draft once added a second constructor, span(initializer_list<value_type>), through P2447. Braces prefer a constructor that takes an initializer_list when one is viable.
Here one is viable. A pointer converts to bool, and so does a count. So {ptr, n} is a list of two bools. The standard calls that conversion narrowing and therefore ill-formed. GCC accepts it with a warning for non-constant values. Then s.size() is 2.
What the demo prints on each library
The demo builds a span over a real three-element array, once with braces and once with parentheses, and prints both sizes. It also prints whether the feature-test macro __cpp_lib_span_initializer_list is defined. I ran it on Compiler Explorer on 6 October 2026 with -std=c++26, and for clang with -stdlib=libc++:
| compiler | library | __cpp_lib_span_initializer_list |
span<const bool> s{ptr, n} |
|---|---|---|---|
| GCC 15.1, 15.2, 15.3 | libstdc++ 15 | 202311 | compiles with -Wnarrowing warnings, size 2 |
| GCC 16.1, 16.2 | libstdc++ 16 | not defined | size 3 |
| clang 19.1, 20.1, 21.1, 22.1 | libc++ 19 to 22 | error: const bool * cannot be narrowed to bool |
|
| clang 23.1.0 | libc++ 23.1.0 | not defined | size 3 |
| clang trunk | libc++ 24.0.0git | not defined | size 3 |
The clang 19 to 22 builds stop at the error. There the library version comes from a separate _LIBCPP_VERSION probe. Disable the narrowing error with -Wno-c++11-narrowing and clang 21.1 prints the macro as 202311 and size 2.
The span<const int> line gives 3 everywhere. A pointer does not convert to int, so the list is not viable.
How the removal got into the draft
LWG issue 4520 came from a bug report against NVIDIA’s libcu++, which had implemented the specification correctly. P4144R1 is dated 2026-03-26. Its first revision proposed a narrower fix for span<const bool>. On 2026-03-25 LEWG polled 16/14/2/0/0 to remove the constructor entirely.
The issue records “P4144R1 was approved in Croydon” on 2026-03-31 and changes its status to Resolved. In the draft repository the commit “P4144R1 Remove span’s initializer_list constructor for C++26” is part of “Merge 2026-03 LWG Motion 24”, dated 2026-04-19.
The paper’s wording removes the constructor and the __cpp_lib_span_initializer_list macro. As of 6 October 2026 the [views.span] page at eel.is has no initializer_list constructor. The cppreference constructor list for std::span and its feature-test table have no entry for it either. The libc++ 23 release notes list P4144R1 among the implemented papers.
The paper also links a post by Arthur O’Dwyer, one of P2447’s authors, about using the constructor in Chromium. It is input if the feature comes back in a later standard. I have not read that post.
What it means for your code
If you wrote span<const bool>{ptr, n} on a GCC 15 toolchain, the warning is the only sign. Moving to libstdc++ 16 changes the result from 2 to 4 in the example at the top. The -Wnarrowing warning will not say so.
Sources, all read on 6 October 2026:
- P4144R1 (full text, including the LEWG poll and the wording)
- LWG 4520 (status and the Croydon note)
- cplusplus/draft (commit log through the GitHub API; on main,
source/containers.texandsource/support.texcontain no mention of the removed macro) - eel.is [views.span] and [version.syn] (searched for
initializer_listand the macro) - cppreference: std::span::span and feature-test macros
- libc++ 23 release notes (the page was still headed “In-Progress”)
The compiler results come from Compiler Explorer (GCC 15.1 to 16.2, clang 19.1 to trunk). I also checked them locally with GCC 16.2.0 and clang 23.1.1.