When looking over the member functions of the STL containers, an odd thought occurred to me. Why don\'t functions like std::vector not ha
I am not sure, but I think that one of the reasons why the mutating std::string members return an iterator is so that the programmer could obtain a non-const-iterator to the std::string after a mutating operation without requiring a second "leak".
The std::basic_string interface was designed to support a pattern called copy-on-write, which basically means that any mutating operation does not affect the original data, but a copy. For example, if you had the string "abcde" and replaced 'a' with 'z' to get "zbcde", the data for the resulting string might occupy a different location in the heap than the data for the original string.
If you obtain a non-const-iterator of a std::string, then a COW string implementation must make a copy (also called "leak the original"). Otherwise, the program can change the underlying data (and violate the read-only invariant) with:
char& c0 = *str.begin();
c0 = 'z';
But, after a string mutation operation, the resulting string object already has sole ownership of the data, so the string implementation does not need to leak its data a second time to make a non-const-iterator.
A std::vector is different because it does not support copy-on-write semantics.
Note: I got the term leak from the libstdc++ implementation of std::basic_string. Also, "leaking the data" does not mean that the implementation leaks memory.
EDIT: Here is the libstdc++ definition of std::basic_string for reference:
iterator
begin()
{
_M_leak();
return iterator(_M_data());
}