Когда std ::vector перераспределяет свой массив памяти, используется конструктор копирования или конструктор перемещения?

#c #stdvector

#c #c 11 #stl #stdvector

Вопрос:

Когда std ::vector перераспределяет свой массив памяти, какой конструктор копирования / перемещения используется для копирования / перемещения элементов в новые дома?

Ответ №1:

Если конструктор перемещения существует и есть noexcept , то он используется. В противном случае используется конструктор копирования.

Использование конструктора перемещения, который может выдавать, нежелательно, поскольку может случиться так, что некоторые объекты будут перемещены в новое хранилище, а затем исключение предотвратит перемещение остальных объектов.

cppreference.com сайт говорит, что если объект не подлежит копированию, но имеет конструктор перемещения, отличный от noexcept, то он будет использовать этот конструктор перемещения с «неопределенным поведением», если генерируется исключение. Я предполагаю, что это означает, что элементы могут быть потеряны из вектора.

Комментарии:

1. Документация по адресу cppreference.com не совсем согласен с тем, что вы говорите. Если конструктор перемещения T не является noexcept и T не копируется в *this , vector будет использовать конструктор перемещения. Если он выдает ошибку, гарантия аннулируется, а последствия не указаны.

2. @RSahu В этой документации упоминается вставляемый элемент; этот вопрос касается поведения элементов, уже находящихся в векторе. Например. рассмотрим v.reserve( v.capacity() 1 );

3. std::vector::reserve использует ту же формулировку.

4. @RSahu Я предполагаю, что это говорит о том, что объекты, не подлежащие копированию, с помощью конструктора перемещения будут использовать этот конструктор и откажутся от строгой гарантии, но я не совсем уверен, каким будет поведение в случае исключения. Например. мне кажется, что объекты будут потеряны из вектора.

5. Похоже, что стандарт выбирает безопасный маршрут и прибегает к неопределенному поведению.