Ответ 1
std::back_inserter
создает вставной итератор, который вставляет элементы в контейнер. Каждый раз, когда этот итератор разыменовывается, он вызывает push_back
в контейнере, чтобы добавить новый элемент в контейнер.
Для контейнера std::vector
вызов push_back
, где v.size() == v.capacity()
приведет к перераспределению: создается новый массив для хранения содержимого вектора, его текущее содержимое копируется в новый массив и старый массив уничтожается. Любые итераторы в вектор в это время недействительны, то есть они больше не могут использоваться.
В вашей программе это включает диапазон ввода, определенный begin(vec)
и end(vec)
, из которого копируется алгоритм copy
. Алгоритм продолжает использовать эти итераторы, даже если они недействительны, поэтому ваша программа демонстрирует поведение undefined.
Даже если ваш контейнер имел достаточную емкость, его поведение по-прежнему будет undefined: в спецификации указано, что при вставке "если перераспределение не происходит, все итераторы и ссылки до точки вставки остаются в силе" (С++ 11 § 23.3.6.5/1).
Вызов push_back
эквивалентен вставке в конце, поэтому конечный итератор (std::end(vec)
), который вы передали в std::copy
, недействителен после одного вызова push_back
. Если входной диапазон не пуст, программа поэтому демонстрирует поведение undefined.
Обратите внимание, что поведение вашей программы было бы четко определено, если вы использовали std::deque<int>
или std::list<int>
, потому что ни один из этих контейнеров не отменяет итераторы при добавлении элементов.