Ответ 1
К сожалению, стандартная неопределенность указывает поведение при назначении контейнером последовательности, соответствующее значению распределителя, и, строго говоря, несовместимо.
Мы знаем (из таблицы 28 и 23.2.1p7), что если allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value
true
, тогда распределитель заменяется на назначение копии. Далее, из таблиц 96 и 99 мы обнаруживаем, что сложность назначения копирования является линейной, а пост-условие для операции a = t
заключается в том, что a == t
, т.е. (Таблица 96), что distance(a.begin(), a.end()) == distance(t.begin(), t.end()) && equal(a.begin(), a.end(), t.begin())
. Из 23.2.1p7 после назначения копии, если распределитель распространяется, тогда a.get_allocator() == t.get_allocator()
.
Что касается векторной емкости, то 23.3.6.3 [vector.capacity] имеет:
5 - Замечания: Reallocation делает недействительными все ссылки, указатели и итераторы, ссылающиеся на элементы в последовательности. Гарантируется, что перераспределение не происходит во время вставок, которые происходят после вызова
reserve()
до момента, когда вставка сделает размер вектора большим, чем значениеcapacity()
.
Если мы возьмем библиотеку DR341 в качестве руководства для чтения стандарта:
Однако текст параграфа 23.3.6.3 [vector.capacity] исключает возможность уменьшения емкости вектора после вызова функции reserve(). Это приводит к недействительности идиомы, так как swap() не позволяет уменьшить емкость. [...]
DR341 был разрешен путем добавления абзацев в 23.3.6.3:
void swap(vector<T,Allocator>& x);
7 - Эффекты: Обменивает содержимое иcapacity()
*this
с текстомx
.
8 - Сложность: постоянное время.
Вывод состоит в том, что с точки зрения Библиотечного комитета операции только изменяют capacity()
, если они указаны в 23.3.6.3. Назначение копии не упоминается в 23.3.6.3 и поэтому не изменяет capacity()
. (Перемещение назначения имеет ту же проблему, особенно с учетом предлагаемой резолюции Библиотека DR2321.)
Ясно, что это дефект в стандарте, поскольку назначение копий, распространяющих неравные распределители, должно привести к перераспределению, что противоречит 23.3.6.3p5.
Мы можем ожидать и надеяться, что этот дефект будет разрешен в пользу:
- нередуцированный
capacity()
при назначении копирования без выделения распределителя; - неуказанный
capacity()
при назначении распределения с помощью распределителя; - нередуцированный
capacity()
при назначении перемещения, не распространяющего распределитель, - source-container
capacity()
при назначении распределения, распространяющего распределитель.
Однако в текущей ситуации и пока это не будет выяснено, вам не следует зависеть от какого-либо конкретного поведения. К счастью, существует обходное решение, которое не позволяет уменьшить capacity()
:
bigVector.assign(littleVector.begin(), littleVector.end());