how to return a null iterator in c++?

10,078

Solution 1

Returning a list iterator, when the user doesn't have access to the list which the iterator is coming from, is weird and ugly. Why not return a pointer to a People instead, which can be NULL?

Solution 2

Iterators can never be null. If an iterator does not point to anything, it's value is end(). I think it's OK for you to return end(). Usually the user uses an iterator to iterate over something, and when they iterate it is their responsibility to check whether they have reached the end or not, and the only way to check is to compare the iterator's value with end().

Solution 3

It doesn't make sense to return an iterator that can be from different lists. There is no way to check whether the iterator is valid. The best way in your approach is to return a pointer to the actual object being stored and that can be null.

On the other hand, what you could do if you insist to return an iterator is having a method in Wrapper to check the validity of the iterator.

class Wrapper{
private:
    std::list<People> men;
    std::list<People> woman;

    /**
        some bizzar logics
    **/
public:
    std::list<People>::iterator getMeTheNextOne(){};

    bool isValid(std::list<People>::iterator const & it) const 
    {
       return it != men.end() || it != women.end();
    }
};

That you could use like this:

Wrapper wo;
std::list<People>::iterator it = wo.getMeTheNextPeople();
if(wo.isValid(it))
{
   // do something here
}
Share:
10,078
James Bond
Author by

James Bond

Licenced to ask!

Updated on June 04, 2022

Comments

  • James Bond
    James Bond almost 2 years

    I am writing a wrapper class which looks like this:

    class Wrapper{
    private:
        std::list<People> men;
        std::list<People> woman;
    
        /**
            some bizzar logics
        **/
    public:
        std::list<People>::iterator getMeTheNextOne(){};
    }
    

    The problem is, sometime, I need to return an empty (or NULL) iterator, saying that there is no more 'suitable' people in either list any more. If I simply return men.end() or women.end(), is the user gonna catch this?

    Imaging the user have following code:

    Wrapper wo;
    std::list<People>::iterator it = wo.getMeTheNextPeople();
    if(it == /*what should I put here? i cannot access the list members of the Wrapper*/){
    // do something here
    }
    
  • Puppy
    Puppy about 10 years
    Because it can't be incremented/etc?
  • Sneftel
    Sneftel about 10 years
    It can't (safely) be incremented anyway. The fact that he's returning elements from one of two lists suggests that the user has no way of knowing which list the next element should be drawn from.
  • Puppy
    Puppy about 10 years
    Depends on what else he provides- for example, if he provides a men_end and a women_end then there's no problem.
  • Sneftel
    Sneftel about 10 years
    @DeadMG Sure, maybe the purpose of the function is to provide some suffix of one of the two lists. But it seems far more likely that the OP was thinking in terms of list iterators as element references simply because he was using lists. In the absence of more information about the use case, I'm going with Occam's Razor.
  • MSalters
    MSalters about 10 years
    @DeadMG: Even if you provided both, the caller still wouldn't know which of the two to use.