There are many worse string formats than C's NUL terminated:
Last byte of string has bit 7 set.
First byte of string has length, so strings are limited to 255 bytes in length.
First two bytes of string has length, so strings are limited to 65535 bytes in length.
Strings are stored in fixed length buffers with space padding to the end.
Length prefixed strings are stored in a fixed length buffer, so you are limited to the buffer length. I think this was the case for PL/I "varying" strings.
Back in the day, C was better than PASCAL because it had strdup, meaning it had a heap and you could put strings in it.
C++ string is mediocre. I solves some problems, but what if:
You have very long strings and you are worried about heap fragmentation. So you are better to have something like a linked list of segments each in their own malloc block. But can you extend std::string? Nope, oh well.
You want strings to be semipredicates. I mean that strings should be able to have a NULL value, as I can do with C. (return NULL for 'char *'). Can std::string do this? Nope. Can it be extended? Nope.
"since C++17", I see.. I'm curious if it uses more space than "char *"
Also it's not great because I should be able to pass such a string through functions that expect std::string. A NULL string should act just like an empty string except that you can test it for NULL.
Yes. std::optional<T> allocates the T in-place. Just checked compiler explorer, and on g++ 8.1, sizeof(std::string) == 32, sizeof(std::optional<std::string>) == 40.
There isn't one (because what you want for long strings makes short string operations too slow, or because you need strings stored in a certain format or in a certain place for other reasons).
So I like the idea of polymorphism so you can adjust the implementation. C++ has polymorphism, but for some reason not enabled for strings (they needed to use all virtual member functions to allow it).
Last byte of string has bit 7 set.
First byte of string has length, so strings are limited to 255 bytes in length.
First two bytes of string has length, so strings are limited to 65535 bytes in length.
Strings are stored in fixed length buffers with space padding to the end.
Length prefixed strings are stored in a fixed length buffer, so you are limited to the buffer length. I think this was the case for PL/I "varying" strings.
Back in the day, C was better than PASCAL because it had strdup, meaning it had a heap and you could put strings in it.
C++ string is mediocre. I solves some problems, but what if:
You have very long strings and you are worried about heap fragmentation. So you are better to have something like a linked list of segments each in their own malloc block. But can you extend std::string? Nope, oh well.
You want strings to be semipredicates. I mean that strings should be able to have a NULL value, as I can do with C. (return NULL for 'char *'). Can std::string do this? Nope. Can it be extended? Nope.