Информация об изменениях

Сообщение Re[2]: v.emplace_back(v[0]) от 07.10.2017 21:49

Изменено 07.10.2017 21:57 rg45

Re[2]: v.emplace_back(v[0])
Здравствуйте, andyp, Вы писали:

C>>is subj. UB?

A>Почему? operator[] возвращает ссылку, дальше имеем обычную историю с forwarding reference (reference collapsing, это все) в результате получаем emplace_back(T& )

Потому что, если случится переаллокация, то в конструктор объекта может прийти дохлая ссылка:

23.3.6.5 vector modifiers
Remarks: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid. If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T or by any InputIterator operation there are no effects. If an exception is thrown while inserting a single element at the end and T is CopyInsertable or is_nothrow_move_constructible<T>::value is true, there are no effects. Otherwise, if an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified.

Re[2]: v.emplace_back(v[0])
Здравствуйте, andyp, Вы писали:

C>>is subj. UB?

A>Почему? operator[] возвращает ссылку, дальше имеем обычную историю с forwarding reference (reference collapsing, это все) в результате получаем emplace_back(T& )

Потому что, если случится переаллокация, то в конструктор объекта может прийти дохлая ссылка, если только в реализации вектора не создается промежуточная копия. Но рассчитывать на это не стоит:

23.3.6.5 vector modifiers
Remarks: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid. If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T or by any InputIterator operation there are no effects. If an exception is thrown while inserting a single element at the end and T is CopyInsertable or is_nothrow_move_constructible<T>::value is true, there are no effects. Otherwise, if an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified.