Your question is actually twofold:
1) Why does std::string have its own find function, which returns a std::size_t instead of an iterator?
This is largely due to the fact that std::string was developed separately from most of the rest of the standard library. Only in the latest standards was it covered by other templates (e.g. iostream). Therefore, when it was added to the standard, it had some functions added to it, but its original functionality was largely left as it is (the exception is the usual copy-on-write implementation, which was forbidden in C + + 11). It was left this way mainly for backward compatibility.
To your question about why this was from the very beginning: The original string.h was a very thin wrapper around several functions of the string C. It was not so rare to see strlen used as the return value for length() or strcpy used in the constructor copying. Requirements were not required to use these functions, so the developers began to do some interesting things (for example, copies to write, non-contiguous blocks of memory), but they left the interface the same to maintain backward compatibility. Although functions were added to it, no public functions were removed from the interface. This way, you can track design decisions for using a pointer and length for function parameters in the days when it was just a wrapper around C. functions
2) How can you write an erase sequence in a string without having to check the return value?
This can be done simply using the find-erase idiom, but without using the std::string find function:
s.erase(std::find(s.begin(), s.end(), '#'), s.end());
source share