#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. Похоже, что стандарт выбирает безопасный маршрут и прибегает к неопределенному поведению.