C++ Logo

std-proposals

Advanced search

Re: [std-proposals] vector::push_back must not invalidate past-the-end iterator

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Tue, 9 Dec 2025 10:14:22 +0100
Isn't it enough, if the for loop checks for the last element instead of one beyond?   This would work with all containers with bidirectional iterators. For forward_list there is not even a push_back() function.     #include <vector> struct mytype {   std::vector<int> vec;   // in real code it is complex iterator   // where vector iterator only part of it   using iterator = std::vector<int>::iterator;   void append(iterator b, iterator e) {       --e; // INSERT     for (; b != e; ++b) { // ASSERTION FAILURE, COMPARING b and e after push_back       // again, in real code it complex operation with inserting in my container       vec.push_back(*b);     }       vec.push_back(*b); // INSERT   }   iterator begin() {     return vec.begin();   }   iterator end() {     return vec.end();   } }; int main() {     mytype x;     x.vec = {1, 2, 3, 4};     x.vec.reserve(100);     x.append(x.begin(), x.end()); }     -----Ursprüngliche Nachricht----- Von:Nikl Kelbon via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Di 09.12.2025 05:19 Betreff:Re: [std-proposals] vector::push_back must not invalidate past-the-end iterator An:std-proposals_at_[hidden]; CC:Nikl Kelbon <kelbonage_at_[hidden]>; Im glad you now asking for a motivation and not asking "what is past the end iterator" or smth what was discussed before In real code i created my container template, so its iterator combines several iterators of its parts. std::vector was one of those parts Then i wrote append(iterator, iterator) and my code sures it is completely right, no reallocation etc etc. But msvc stl implementation find a way to assert it (by storing all .end() iterators in global map under mutex and invalidate them on each push_back) I dont know any other way to code it. Its impossible. THERE ARE NO OTHER WAY! Code: #include <vector> struct mytype {   std::vector<int> vec;   // in real code it is complex iterator   // where vector iterator only part of it   using iterator = std::vector<int>::iterator;   void append(iterator b, iterator e) {     for (; b != e; ++b) { // ASSERTION FAILURE, COMPARING b and e after push_back       // again, in real code it complex operation with inserting in my container       vec.push_back(*b);     }   }   iterator begin() {     return vec.begin();   }   iterator end() {     return vec.end();   } }; int main() {     mytype x;     x.vec = {1, 2, 3, 4};     x.vec.reserve(100);     x.append(x.begin(), x.end()); }   https://godbolt.org/z/cjfT9vran вт, 9 дек. 2025 г. в 07:18, Jason McKesson via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]> >: On Mon, Dec 8, 2025 at 1:56 PM Nikl Kelbon via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]> > wrote: > > Thats what standard exists for. Standard decides what is ub and what is not ub. How its even may be argument "its ub" in discussion about changing standard? Because your reasoning for why this change is needed is that many users do it regardless of the fact that it's UB, so it makes sense to change it. That is, your proposal is predicated on the idea that this is common code, and therefore if it isn't common code, then it has no motivation. So, what evidence can you provide that people believe that end iterators should work this way? The fact that it can be implemented is not, by itself, sufficient justification for changing the standard. -- Std-Proposals mailing list Std-Proposals_at_[hidden] <mailto:Std-Proposals_at_[hidden]> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2025-12-09 09:29:06