This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
inplace_vector insertion functions do not specify iterator invalidationSection: 23.3.16.5 [inplace.vector.modifiers] Status: New Submitter: Karolis Špukas Opened: 2026-10-06 Last modified: 2026-10-10
Priority: Not Prioritized
View all other issues in [inplace.vector.modifiers].
View all issues with New status.
Discussion:
23.3.16.5 [inplace.vector.modifiers] does not specify iterator and reference invalidation for insertion functions.
According to 23.2.2.2 [container.reqmts] p67, the current wording of 23.3.16.5 [inplace.vector.modifiers] implies thatinplace_vector insertions do not invalidate
iterators and references or change the values of objects in the container:
Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.
P0843R8 specified reference invalidation for insert and emplace, for example:
constexpr iterator insert(const_iterator position, value_type&& x);Effects: Inserts
xat position and invalidates all references to elements after position.
This wording was removed in P0843R9 with no corresponding changelog entry.
On the other hand, 23.3.16.5 [inplace.vector.modifiers] p19 still specifies invalidation for erasure:Effects: Invalidates iterators and references at or after the point of the erase.
For comparison, 23.3.13.5 [vector.modifiers]/2 specifies invalidation for insertion without reallocation:
If no reallocation happens, then references, pointers, and iterators before the insertion point remain valid but those at or after the insertion point, including the past-the-end iterator, are invalidated.
I took a quick look at libstdc++ implementation. I believe an insertion to inplace_vector can shift elements,
therefore it is inconsistent with 23.2.2.2 [container.reqmts] p67.
Proposed resolution:
This wording is relative to N5054.
Modify 23.3.16.5 [inplace.vector.modifiers] as indicated:
constexpr iterator insert(const_iterator position, const T& x); constexpr iterator insert(const_iterator position, T&& x); […] template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); template<container-compatible-range <T> R> constexpr void append_range(R&& rg);-1- Let
-2- Complexity: Linear in the number of elements inserted plus the distance to the end of the vector. -3- Remarks: References, pointers, and iterators before the insertion point remain valid, but those at or after the insertion point, including the past-the-end iterator, are invalidated. If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator ofnbe the value ofsize()before this call for theappend_rangeoverload, and `distance(begin, position)` otherwise.Tor by anyInputIteratoroperation, there are no effects. Otherwise, if an exception is thrown, thensize() ≥ nand elements in the rangebegin() + [0, n)are not modified.constexpr reference push_back(const T& x); constexpr reference push_back(T&& x); template<class... Args> constexpr reference emplace_back(Args&&... args);-4- Returns:
-5- Throws:back().bad_allocor any exception thrown by the initialization of the inserted element. -6- Complexity: Constant. -7- Remarks: If an element is appended, invalidates the past-the-end iterator. If an exception is thrown, there are no effects on*this.template<class... Args> constexpr optional<reference> try_emplace_back(Args&&... args); constexpr optional<reference> try_push_back(const T& x); constexpr optional<reference> try_push_back(T&& x);-8- Let
-9- Preconditions: […] -10- Effects: Ifvalsdenote a pack: […]size() < capacity()istrue, appends an object of typeTdirect-non-list-initialized withvals.... Otherwise, there are no effects. -11- Returns:nulloptifsize() == capacity()istrue, otherwiseoptional<reference>(in_place, back()). -12- Throws: Nothing unless an exception is thrown by the initialization of the inserted element. -13- Complexity: Constant. -14- Remarks: If an element is appended, invalidates the past-the-end iterator. If an exception is thrown, there are no effects on*this.