В С++ 11 символы a std::string
должны храниться смежно, как указано в пункте 21.4.1/5:
Объекты char в объекте basic_string сохраняются смежно. То есть для любого объекта basic_string s идентификатор & * (s.begin() + n) == & * s.begin() + n будет иметь место для всех значений n таких, что 0 <= n < lt; s.size().
Однако вот как в § 21.4.7.1 перечислены две функции для получения указателя на базовое хранилище (выделение мое):
const charT * c_str() const noexcept;
const charT * data() const noexcept;
1 Возвращает: Указатель p такой, что p + я == & operator [] (i) для каждого я из [0, size()].
2 Сложность: постоянное время.
3 Требуется: программа не должна изменять какие-либо значения, хранящиеся в массиве символов.
Одна из возможностей, которую я могу придумать для точки 3, состоит в том, что указатель может стать недействительным при использовании этого объекта (§ 21.4.1/6):
- как аргумент любой стандартной библиотечной функции, ссылающейся на не-const basic_string как на аргумент.
- Вызов неконстантных функций-членов, кроме оператора [], спереди, сзади, начала, rbegin, end и разрывать.
Тем не менее, итераторы могут стать недействительными, но мы все равно можем их модифицировать независимо от них. Мы все еще можем использовать указатель, пока он не станет недействительным для чтения из буфера.
Почему мы не можем писать непосредственно в этот буфер? Это потому, что он помещает класс в несогласованное состояние, так как, например, end()
не будет обновляться новым концом? Если да, то почему разрешено напрямую писать в буфер нечто вроде std::vector
?
Случаи для этого включают возможность передачи буфера std::string
в интерфейс C для извлечения строки вместо передачи в vector<char>
вместо этого и инициализации строки с помощью итераторов:
std::string text;
text.resize(GetTextLength());
GetText(text.data());