Существует ли класс Стандартной библиотеки шаблонов C++, который обеспечивает эффективную функциональность конкатенации строк, подобную StringBuilder C# или StringBuffer Java?
ПРИМЕЧАНИЕ. В последнее время этот ответ привлек внимание. Я не защищаю это как решение (это решение, которое я видел в прошлом, до STL). Это интересный подход, и его следует применять только к std :: string
или std :: stringstream
, если после профилирования кода вы обнаружите, что это дает улучшение.
Обычно я использую либо std :: string
, либо std :: stringstream
. У меня никогда не было проблем с этим. Обычно я сначала резервирую комнату, если заранее знаю приблизительный размер струны.
В далеком прошлом я видел, как другие люди создавали свои собственные оптимизированные конструкторы струн.
class StringBuilder {
private:
std::string main;
std::string scratch;
const std::string::size_type ScratchSize = 1024; // or some other arbitrary number
public:
StringBuilder & append(const std::string & str) {
scratch.append(str);
if (scratch.size() > ScratchSize) {
main.append(scratch);
scratch.resize(0);
}
return *this;
}
const std::string & str() {
if (scratch.size() > 0) {
main.append(scratch);
scratch.resize(0);
}
return main;
}
};
Он использует две строки, одну для большей части строки, а другую в качестве рабочей области для объединения коротких строк. Он оптимизирует добавления, объединяя короткие операции добавления в одну небольшую строку, а затем добавляя ее к основной строке, тем самым уменьшая количество перераспределений, необходимых для основной строки по мере ее увеличения.
Мне не требовался этот трюк с std :: string
или std :: stringstream
. Я думаю, что он использовался со сторонней строковой библиотекой до std :: string, это было так давно. Если вы применяете подобную стратегию, сначала ваше приложение.
Способ C++ — использовать std::stringstream или просто конкатенации строк. Строки C++ изменяемы, поэтому соображения производительности конкатенации не вызывают беспокойства.
Что касается форматирования, вы можете сделать все то же форматирование на потоке, но по-другому, аналогично cout
. или вы можете использовать строго типизированный функтор, который инкапсулирует это и предоставляет интерфейс, подобный String.Format, например, boost::format
Вы можете использовать .append() для простой конкатенации строк.
std::string s = "string1";
s.append("string2");
Я думаю, вы даже сможете сделать:
std::string s = "string1";
s += "string2";
Что касается операций форматирования в C# StringBuilder
, я считаю, что snprintf
(или sprintf
, если вы хотите рискнуть написать багованный код ;-)) в символьный массив и преобразование обратно в строку - это единственный вариант.
std :: string
- это эквивалент C ++: он изменяемый.