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?
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 )
if boost is an option, you may use boost::optional
or since C++17, std::optional
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