В последнее время я делал некоторые необходимые оптимизации. Одна вещь, которую я делал, - это изменение некоторых ostringstreams -> sprintfs. Я sprintf'ing кучу std :: strings в массив стиля AC, аля
char foo[500];
sprintf(foo, "%s+%s", str1.c_str(), str2.c_str());
Оказывается, что реализация Microsoft std :: string :: c_str () выполняется за постоянное время (она просто возвращает внутренний указатель). Похоже, что libstdc ++ делает то же самое . Я понимаю, что std не дает никаких гарантий для c_str, но сложно представить другой способ сделать это. Если, например, они скопировали в память, им либо пришлось бы выделить память для буфера (предоставив вызывающей стороне его уничтожить - НЕ часть контракта STL) ИЛИ им пришлось бы скопировать во внутреннюю статическую память. буфер (вероятно, не потокобезопасный, и у вас нет никаких гарантий на его время жизни). Так что простой возврат указателя на внутренне поддерживаемую строку с нулевым символом в конце кажется единственным реальным решением.
c_str
что это метод const (или, по крайней мере, имеет перегрузку const - я забыл, какой), это не меняет логическое значение, поэтому может быть причинойmutable
. Это сломало бы указатели от других вызововc_str
, за исключением того, что любые такие указатели должны ссылаться на одну и ту же логическую строку (так что нет никакой новой причины для перераспределения - там уже должен быть нулевой терминатор), иначе должен был уже быть вызов не -константный метод между ними.