
pt., 26 wrz 2025 o 09:32 Richard Hodges via Boost <boost@lists.boost.org> napisaĆ(a):
On Thu, 25 Sept 2025 at 17:15, Peter Dimov via Boost < boost@lists.boost.org> wrote:
You need strlen for more than size(). It's also needed in end(), operator[], at(), remove_prefix, substr (both overloads), the find functions taking a start offset, back(), actually everything taking a start offset, ends_with, and probably others as well.
If the purpose of the class is to provide the functionality of a c string, then the only required methods are those available on a c string: - data - array indexing - length
There is no need for any string manipulation. In C++,.the correct class for string manipulation operations is a std::string
There is a reasonable argument that you may want begin() and end() iterators, maybe. But it's reasonable to write end() in terms of strlen(), because it's unlikely that a sane program will need to call end() more than once, and also unlikely that it will need to call both end() and size(), when dealing with a c string.
Computing the length of a string with strlen() is very high performance for anything other than an extremely long string.
I don't think this thing needs to be over-engineered. I am of the view that providing a full std::string interface is an utter waste of time and effort
Agreed about the full interface (I don't think I even know the full interface of std::string). Considering the subset of SQLite use-cases, those where a user has a `const char*` or an std::string, passes it to the library and the library will ultimately use it to call a C library and pass a `const char *`, I have the following expectations: E1: Distinguish (in the type) the situation where `const char*` is used to represent a null-terminated character sequence from the situation where `const char*` is used as a pointer to object which happens to be of type `char`: ``` const char* delimited = "delimited_data.dat"; constexpr char regular_delimiter = ';'; constexpr char special_delimiter = 0; auto delimiter = use_regular ? & regular_delimiter : use_special ? & special_delimiter: nullptr; // ... fopen(delimiter, "r"); // I want compiler error here ``` E2: Shorter function call syntax: when I have a std::string, I would not like to spell `.c_str()` unnecessarily. E3: I need the operator== (and cousins) to have the intuitive meaning of comparing character sequences rather than addresses. 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. I also note that Boost.Sqlite has other use cases, where a text column from a table, potentially containing null characters in the middle, is returned to the user. This is news to me, so I am not even sure yet what I would expect there. Another observation is that the key selling point of the std::string_view was that any substring can be computed and returned without any memory management issues. This property is fundamentally incompatible with the null-terminator guarantee. 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. Regards, &rzej;