«История» заключалась в том, что давным-давно, когда все работали в отдельных потоках или, по крайней мере, потоки были работниками со своими собственными данными, они разработали строковый класс для C ++, который сделал обработку строк проще, чем раньше, и они перегружают оператор + для объединения строк.
Проблема заключалась в том, что пользователи будут делать что-то вроде:
s = s1 + s2 + s3 + s4;
и каждая конкатенация создаст временный объект, который должен был реализовать строку.
Поэтому у кого-то была мозговая волна «ленивой оценки», так что внутри вы могли хранить какую-то «веревку» со всеми строками, пока кто-то не захотел прочитать ее как C-строку, после чего вы изменили бы внутреннее представление на непрерывный буфер.
Это решило проблему выше, но вызвало множество других головных болей, особенно в многопоточном мире, где ожидалось, что операция .c_str () будет доступна только для чтения / ничего не изменится и, следовательно, нет необходимости блокировать что-нибудь. Преждевременная внутренняя блокировка в реализации класса на тот случай, если кто-то делал это многопоточным (когда не было даже потока), также не была хорошей идеей. На самом деле делать что-либо из этого было дороже, чем просто копировать буфер каждый раз. По той же причине реализация «копирование при записи» была оставлена для строковых реализаций.
Таким образом, сделать .c_str()
действительно неизменной операцией оказалось наиболее разумной вещью, однако можно ли «полагаться» на нее в стандарте, который теперь поддерживает потоки? Поэтому новый стандарт решил четко указать, что вы можете, и поэтому внутреннее представление должно содержать нулевой терминатор.