STL container function return values

后端 未结 8 1187
名媛妹妹
名媛妹妹 2021-01-05 03:41

When looking over the member functions of the STL containers, an odd thought occurred to me. Why don\'t functions like std::vector::push_back(T) not ha

8条回答
  •  失恋的感觉
    2021-01-05 04:33

    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::begin() for reference:

    iterator
    begin()
    {
        _M_leak();
        return iterator(_M_data());
    }
    

提交回复
热议问题