Почему нельзя изменять строку через извлеченный указатель на ее данные?

В C ++ 11 символыstd::string должны храниться смежно, как § 21.4.1 / 5 баллов:

Символоподобные объекты в объекте basic_string должны храниться непрерывно. То есть для любого объекта s basic_string идентификатор &* (s.begin () + n) == &* s.begin () + n должно выполняться для всех значений n, таких что 0 <= n < s.size ().

Однако вот как 21.4.7.1 перечисляет две функции для извлечения указателя на основное хранилище (выделено мной):

const charT * c_str () const noexcept;

const charT * data () const noexcept;

1 Возвращает: указатель p такой, что p + i == &оператор [] (i) для каждого i в [0, size ()].

2 Сложность: постоянное время.

3 Требуется: программа не должна изменять никакие значения, хранящиеся в массиве символов.

Одна из возможностей, которую я могу придумать для точки номер 3, заключается в том, что указатель может стать недействительным в результате следующих применений объекта (§ 21.4.1 / 6):

в качестве аргумента любой стандартной библиотечной функции, принимая в качестве аргумента ссылку на неконстантную basic_string.Вызов неконстантных функций-членов, кроме operator [], at, front, back, begin, rbegin, end и rend.

Несмотря на это, итераторы могут стать недействительными, но мы все равно можем изменять их, пока они не сделают это. Мы по-прежнему можем использовать указатель, пока он не станет недействительным и для чтения из буфера.

Почему можномы пишем напрямую в этот буфер? Потому что это привело бы класс в противоречивое состояние, как, например,end() не будет обновляться с новым концом? Если так, то почему разрешено писать прямо в буфер чего-то подобного?std::vector

Варианты использования для этого включают возможность передать буферstd::string в интерфейс C, чтобы получить строку вместо передачи вvector вместо этого и инициализируя строку с итераторами из этого:

std::string text;
text.resize(GetTextLength());
GetText(text.data());

Ответы на вопрос(1)

Ваш ответ на вопрос