Почему нет конструктора резервирования для std::string?
Существует несколько конструкторов для std::string
. Я искал способ избежать перераспределения, и я удивлен тем, что есть конструктор заполнения, но конструктор "резервный".
std::string (size_t n, char c);
но не
std::string (size_t n);
Итак, мне нужно вызвать reserve()
после того, как он уже присвоил значение по умолчанию (16 байтов в моем случае), чтобы сразу перераспределить его?
Есть ли причина, почему нет такого конструктора для резервирования пространства непосредственно, когда объект создается, вместо того, чтобы делать это вручную? Или я что-то упускаю, и есть способ сделать это?
Использование конструктора заливки - пустая трата времени, потому что он будет циклически перемещаться по памяти, чтобы получить перезапись, а также вызвать неправильный размер, потому что s.length()
сообщает N
вместо 0
.
Ответы
Ответ 1
Это все догадки, но я постараюсь.
Если вы уже знаете размер строки, которая вам нужна, вы, скорее всего, будете копировать данные из другого места, например. из другой строки. В этом случае вы можете вызвать один из конструкторов, которые принимают char *
или const std::string &
, чтобы скопировать данные немедленно.
Кроме того, я не понимаю, почему использование reserve
сразу после построения строки - это плохо. Хотя это определение реализации, я бы предположил, что это будет иметь смысл для этого кода:
std::string str;
str.reserve(100);
выделить память для всего 100 элементов, а не 116 (как в "сначала выделить 16, а затем освободить их и выделить еще 100" ), тем самым не влияя на производительность несуществующего конструктора резервных копий.
Кроме того, если вам просто нужна пустая строка без выделения по умолчанию, вы можете использовать std::string str(0, ' ');
, которая делает недействительной точку "Использование конструктора заливки является пустой тратой времени".
Ответ 2
Одним из вариантов использования конструктора резерва может быть использование std::string со статическим /thread_local хранилищем для переменных кэша.
void function(){
thread_local std::string str; // no reserving constructor defined
}
Для таких сценариев вы можете написать лямбда-функцию, которая создает std::string и резервирует желаемый объем памяти.
void function(){
auto reserving_string_constr = [](std::size_t reserve_size){
std::string str;
str.reserve(reserve_size);
return str;
};
thread_local std::string str(reserving_string_constr(128));
/*...*/
}
Ответ 3
вы можете задать один и тот же вопрос о каждом методе std::string
, который не является конструктором.
например, почему у нас нет конструктора, который берет несколько строк и добавляет их один за другим к вновь созданной строке?
может быть много причин, чтобы не перегружать конструктор, который резервирует память. Я думаю, что в объектно-ориентированном множестве мысль о "зарезервированной строке памяти" немного нечетна. строка представляет последовательность символов, а не память позади нее - это детали реализации, а не основная функция.
Когда кто-то открывает нового ресторана, думает ли он себе:" Когда этот ресторан наконец откроется, в самый момент открытия я забронирую 100 сит для предполагаемой 100-местной группы, которая может или не придет!"
но ваш вопрос неявно говорит что-то очень короткое: отсутствие надлежащих объектов буфера в С++. вы спрашиваете о конструкторе резервирования, потому что вы хотите использовать строку в качестве буфера, но нуль-инициализация их очень дорогостоящая. резервирование памяти не позволит вам писать за пределами размера строки.
поэтому решение этой проблемы - использовать unique_ptr<char[]>
, который не будет нулевым-инициализировать символы, но даст вам стиль RAII, который вы ищете.