Does span propagate const?
c++, c++20, constants, std-span
Solution
Propagating const for a type like `span` doesn't actually make much sense, since it cannot protect you from anything anyway.
Consider:
void foo(std::span<int> const& s) {
// let's say we want this to be ill-formed
// that is, s[0] gives a int const& which
// wouldn't be assignable
s[0] = 42;
// now, consider what this does
std::span<int> t = s;
// and this
t[0] = 42;
}
Even if `s[0]` gave an `int const&`, `t[0]` surely gives an `int&`. And `t` refers to the exactly same elements as `s`. It's a copy after all, and `span` doesn't own its elements - it's a reference type. Even if `s[0] = 42` failed, `std::span(s)[0] = 42` would succeed. This restriction wouldn't do anyone any good.
The difference with the regular containers (e.g. `vector`) is that the copies here still refer to the same elements, whereas copying a `vector` would give you entirely new elements.
The way to have `span` refer to immutable elements isn't to make the `span` itself `const`, it's to make the underlying elements themselves `const`. That is: `span<T const>`, not `span<T> const`.
Problem
The standard containers propagate const. That is, their elements are automatically const if the containers themselves are const. For example: ``` const std::vector vec{3, 1, 4, 1, 5, 9, 2, 6}; ranges::fill(vec, 314); // impossible const std::list lst{2, 7, 1, 8, 2, 8, 1, 8}; ranges::fill(lst, 272); // impossible ``` Builtin arrays also propagate const: ``` const int arr[] {1, 4, 1, 4, 2, 1, 3, 5}; ranges::fill(arr, 141); // impossible ``` However, I noticed that `std::span` (presumably) does not propagate const. Minimal Reproducible Example: ``` #include <algorithm> #include <cassert> #include <span> namespace ranges = std::ranges; int main() { int arr[] {1, 7, 3, 2, 0, 5, 0, 8}; const std::span spn{arr}; ranges::fill(spn, 173); // this compiles assert(ranges::count(arr, 173) == 8); // passes } ``` Why does this code work fine? Why does `std::span` treat const differently than the standard containers?