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());
}