How to initialize an iterator to something invalid if the container is not known?
c++, containers, visitor-pattern
Solution
The answer
You can't, there is no value for standard iterators that puts them into an "invalid state".
Proposed solution
Instead of relying on the value of `mLineIter`, default-initialize `mLineIter` and initialize `mpLinesToSearch` to `nullptr` in the constructor.
This way you will now that `mLineIter` isn't a valid iterator if `mpLinesToSearch` is still `nullptr`.
SAMPLE IMPLEMENTATION
class OverlapDisabler: public IntersectionHandler{
private:
std::vector<Segment>* mpLinesToSearch;
std::vector<Segment>::iterator mLineIter;
public:
InsideCollector() : mpLinesToSearch (nullptr), mLineIter() { }
...
void advance(){
if (mpLinesToSearch == nullptr)
return; // no iterator to increment
if(mLineIter != mpLinesToSearch->end()) ++mLineIter;
}
...
void treatIntersection(){
if(mpLinesToSearch == nullptr)
return; // the iterator doesn't refer to any element
if(mLineIter != mpLinesToSearch->end()) mLineIter->disable();
}
};
( Note: If you are compiling your source as C++03, `nullptr` isn't available; if that is the case use `NULL` or `0` to initialize your pointer )
Problem
I want to use a visitor given to a more complex function which should inflict changes on a container via the visitor of which is has only general knowledge. The example is reduced to a minimum. The real visitor has more functions and does not necessarily handle a container at all. ``` class IntersectionHandler{ public: virtual void advance()=0; virtual void treatIntersection()=0; }; class OverlapDisabler: public IntersectionHandler{ private: std::vector<Segment> mEmpty; std::vector<Segment>* mpLinesToSearch; std::vector<Segment>::iterator mLineIter; public: InsideCollector():mEmpty(),mpLinesToSearch(&mEmpty),mLineIter(mEmpty.end(){} void setLineContainer(std::vector<Segment>* lines){ mpLinesToSearch = lines; mLineIter = mpLinesToSearch->begin(); } void advance(){ if(mLineIter != mpLinesToSearch->end()) ++mLineIter; } void treatIntersection(){ if(mLineIter != mpLinesToSearch->end()) mLineIter->disable(); } }; ``` To intitailize the iterator I use a dummy vector, that I must keep as a class member in this case. Usually I would initialise the iterator with some globally invalid value such as 0 for a pointer. Unfortunately 0 is not a valid value for an iterator with many compilers and also seems a little odd to use. Is there a cleaner way to accomplish what I am trying without resorting to an empty dummy container?