Разве это не точка для резерва () размера, чтобы вы могли получить к нему доступ?
Нет, это точка resize()
.
reserve()
только дает достаточно места, так что будущий вызов, который приводит к увеличению размера (например, вызов push_back()
), будет более эффективным.
Из вашего варианта использования похоже, что вы должны использовать .push_back()
.
my_string.reserve( 20 );
for ( parsing_something_else_loop )
{
char ch = <business_logic>;
my_string.push_back(ch);
}
Как получается, что строка имеет емкость, но не может на самом делеполучить к нему доступ с помощью []?
Вызов .reserve()
- это все равно что взорвать горы, чтобы дать вам немного свободной земли.Количество свободных земель составляет .capacity()
.Земля есть, но это не значит, что вы можете там жить.Вы должны строить дома, чтобы двигаться. Число домов: .size()
(= .length()
).
Предположим, вы строите город, но после постройки 50-го вы обнаружили, что естьземли недостаточно, поэтому вам нужно найти другое место, достаточно большое, чтобы вместить 51-й дом, а затем переселить туда все население.Это крайне неэффективно.Если вы знали, что вам нужно построить 1000 домов заранее, то вы можете позвонить
my_string.reserve(1000);
, чтобы получить достаточно земли, чтобы построить 1000 домов, а затем вы позвоните
my_string.push_back(ch);
, чтобы построитьдом с присвоением ch
этому месту.Емкость 1000, но размер все еще 1. Вы не можете сказать
my_string[16] = 'c';
, потому что дом № 16 еще не существует.Вы можете позвонить
my_string.resize(20);
, чтобы получить дома # 0 ~ # 19, построенные за один раз, поэтому
my_string[i++] = ch;
работает нормально (до тех пор, пока 0 ≤ i ≤ 19).
См. Также http://en.wikipedia.org/wiki/Dynamic_array.
По вашему дополнительному вопросу
.resize()
не может быть полностьюзамените .reserve()
, потому что (1) вам не всегда нужно использовать все выделенные пробелы, и (2) построение по умолчанию + назначение копирования - это двухэтапный процесс, который может занять больше времени, чем непосредственное построение (особенно длякрупные объекты), то есть
#include <vector>
#include <unistd.h>
struct SlowObject
{
SlowObject() { sleep(1); }
SlowObject(const SlowObject& other) { sleep(1); }
SlowObject& operator=(const SlowObject& other) { sleep(1); return *this; }
};
int main()
{
std::vector<SlowObject> my_vector;
my_vector.resize(3);
for (int i = 0; i < 3; ++ i)
my_vector[i] = SlowObject();
return 0;
}
Потратит на бега не менее 9 секунд, а
int main()
{
std::vector<SlowObject> my_vector;
my_vector.reserve(3);
for (int i = 0; i < 3; ++ i)
my_vector.push_back(SlowObject());
return 0;
}
- всего 6 секунд.
std::string
копирует только интерфейс std::vector
здесь.