Функция __invalidate_all_iterators
, на которую ссылается ваша ссылка, является просто средством отладки.Это не «делает» итераторы недействительными;Это эффективно сообщает, что итераторы были признаны недействительными предыдущими действиями.Может случиться так, что этот инструмент отладки может не обнаружить ошибку, вызванную этим назначением.
Предварительным условием assign
является то, что итераторы не относятся к одному и тому же контейнеру.Нарушение предусловия приводит к неопределенному поведению.
Стандартная цитата (последний черновик):
[sequence.reqmts] a.assign(i,j)
Ожидается: T является Cpp17EmplaceConstructible в X из * i и может быть назначеноот * я.Для вектора, если итератор не удовлетворяет требованиям прямого итератора ([forward.iterators]), T также Cpp17MoveInsertable в X. Ни i, ни j не являются итераторами в.
Ваша безопасная альтернатива верна.
Если вы хотите избежать перераспределения (имея в виду, что останется неиспользованное пространство), и если вы хотите избежать копирования (что важно для сложных типов, не 'Если значение имеет int
), то должно быть эффективно следующее:
int begin_offset = 1;
int end_offset = 1;
if (begin_offset)
std::move(data.begin() + begin_offset, data.end() - end_offset, data.begin());
data.erase(data.end() - end_offset - begin_offset, data.end());