As cbhattac's answer explains, the problem was that span's deduction guide's picked the wrong overload.
In issue3369 a fix was developed.
The core problem was that:
template <size_t Size>
requires (Extent == dynamic_extent || Extent == Size)
span(T (&)[Size]) {}
ctor generates an implicit deduction guide, and so does
template <typename T, size_t Extent>
span(T (&)[Extent]) -> span<T, Extent>;
The constructor builds a span
with variable length, and the deduction guide builds one with a fixed length.
When passed an array of fixed length, the ideal deduced span should also be of fixed length. But it wasn't happening.
Naively, explicit deduction guilds beat ones produced from constructors, but that isn't true -- the constructor here is more constrained due to the requires (Extent == dynamic_extent || Extent == Size)
clause. So it beats the deduction guide.
To fix this, type_identity_t<T>
was used to block CTAD with this constructor completely. (An alternative that would also work was to add a trivial constraint to the deduction guide).