Рассмотрим следующий код:
std::vector vec;
vec.reserve(500);
size_t cap = vec.capacity();
std::vector newVec = std::move(vec);
assert(cap == newVec.capacity());
Практически в любой реализации, с которой вы столкнетесь, это будет работать. Меня не волнует, что делают реализации. Я хочу знать, что стандарт требует. Будет ли переезд vector
имеют ту же емкость, что и оригинал? Или актив будет срабатывать?
Глядя на стандарт, кажется, что ничего не требуется от конструктора перемещения, однако, как говорит @amaurea, было бы полностью нарушено назначение семантики перемещения, если бы конструктор перемещения попытался выделить или освободить память, поэтому я ожидал, что емкость оставаться неизменным во всех реализациях.
23.2.1 Общие требования к контейнерам
выражение
X u(a);
X u = a;
Утверждение / примечание до / после условия
Требуется: T
CopyInsertable в X (см. ниже).
сообщение: u == a
Стандарт требует только, чтобы newVec == vec
, Поскольку мощность не учитывается для std::vector::operator==
, newVec
не обязательно должны иметь такую же емкость, как vec
,
Стандартные требования C ++ 11 к конструктору перемещения для std::vector
(Таблица 99 — Требования к контейнерам, учитываемые Распределителем):
X(rv)
X u(rv)
rv
имел до этой конструкции; значение get_allocator()
должно быть таким же, как значение rv.get_allocator()
до этой конструкции.Здесь нет требований / гарантии по мощности. Но мы можем сделать вывод, что постоянная сложность неявно отрицает любые перераспределения. И я не вижу ничего другого логический причина для изменения емкости, кроме перераспределения. Так и должно быть.
С другой стороны, если вектор с удалением пуст, совершенно законно просто игнорировать его и конструировать по умолчанию. Это все равно будет O (1), так как он не требует каких-либо конструкций для каждого элемента. (Благодаря Николь Болас по этому вопросу).
Также реализация может уменьшить емкость до размера, используя hint
параметр std::allocator::allocate
функция:
pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
Использование hint
не определено, но предназначено как помощь населению, если реализация того пожелает. Таким образом, какое-то изощренное решение может передать указатель на векторное хранилище как hint
и использовать realloc
на это уменьшить емкость.
Заключение: выглядит как стандарт, не гарантирует сохранение грузоподъемности при движении std::vector
, хранилище потенциально может быть сокращено.