I have some code that I'm updating to C++11 using gcc 4.7 (from 3.1)
I have a multiset defined as a private member of a class:
multiset <Object*, objectcomp> objects_;
In the code is a segment that looks like this (p_q is a pair of multiset iterators, sorry about that nasty line, can't wait to replace that with auto, haha):
void Terrain::removeObject(Object* obj){
pair<multiset<Object*, objectcomp>::iterator, multiset<Object*, objectcomp>::iterator> p_q;
multiset<Object*, objectcomp>::iterator p,q;
q = NULL;
p_q = objects_.equal_range(obj);
for(p = p_q.first; p != p_q.second; p++){
if(*p == obj) {q=p; break;}
}
if(q!=NULL){
... do stuff based on q no longer being null
}
}
This won't compile anymore. Can you not set iterators to null anymore? What is the alternative? (nullptr doesn't work either)
It was never legal to set iterators to NULL. You may have gotten lucky because your particular implementation happened to use pointers as iterators for that type, but it was still illegal.
The right answer is:
q = objects_.end();
Or, in some cases:
q = multiset<Object*, objectcomp>::iterator();
You never could set an iterator to NULL. If the above code ever worked, it was by sheer accident. Given any reasonable implementation of multiset, it's hard to see how it could ever have compiled, let alone run.
The best way to get a "nowhere" iterator is to use the end of the container. Replace q = NULL
with q = objects_.end()
.
Also, never put raw pointers in a container; it's an open invitation to memory leaks. You almost certainly want either multiset<Object,comp>
or multiset<shared_ptr<Object>,comp>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With