
Andrzej Krzemienski wrote:
I also note, although it is not crucial for me privately, that having the length of the string stored directly, allows the class invariant to be executable, checkable and enforceable at runtime. This means that the program owner can compile it in "assertions enabled" mode, and have the stringg's invariant checked at runtime and potentially detect a bug.
It should be crucial for everyone. In 2025, all our preconditions need to be "hardened preconditions", meaning that (a) they should be checkable and (b) they should be enabled in release builds as well unless there's unacceptable performance cost. There's work being done on that front: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3566r2.pdf https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3711r1.pdf The basic idea here is that if you do char x[ 128 ]; // fill (part of) x with characters std::string_view sv( x ); the constructor can actually see the size of the array (even though it currently doesn't) and therefore the strlen call inside is bounded and cannot lead to arbitrary memory reads as is the case with the normal `char const*` constructor if it's passed something not null terminated.
One last observation, although it is probably just academic, is that the range iteration could be provided without an explicit size: by using a "null- terminator-detecting sentinel". But this would no longer be a contiguous range.
It actually can be. That's the textbook example of a contiguous range that is not common (i.e. that is bounded by a sentinel) and not even sized (doesn't have O(1) size().)