2

I want to write a function that takes two vector iterators as input and then based on some conditions return either of the iterators. If none of the conditions are satisfied it needs to return something similar to null. Since null iterators are not possible what should I use?

We could pass a container as one of the arguments to the function and then initialize the return iterator to container.end(). Does it make sense to pass the container just to initialize the iterator?

std::vector<UserDefinedObj>::iterator getNecessaryIterator(std::vector<UserDefinedObj>::iterator f,std::vector<UserDefinedObj>::iterator s)
{
    std::vector<UserDefinedObj>::iterator r = ??; // How to initialize without adding any more function argument
    if(f->name == "Alex")
    { 
        r = f;
    }
    else if(s->name == "Matt")
    { 
        r = s;
    }
    return r;
}
Enthus3d
  • 1,727
  • 12
  • 26
PapaDiHatti
  • 1,841
  • 19
  • 26
  • Does Unitialized iterator can be compared against specificContainer.end() to validate that none of conditions are met in called function ? – PapaDiHatti Sep 14 '19 at 14:30
  • I believe an uninitialized iterator will throw an exception if you try to use it in any way, if you have a good iterator implementation. The code you show in your question will not work if `f` or `s` are at the end of their container by the way. – Mark Ransom Sep 14 '19 at 14:33
  • 2
    If the two iterators `f` and `s` are in the same container, simply pass a third argument that is the end iterator for that container. Return that iterator if you don't want to return either of the other two. (Also, check that `f` and `s` are not end iterators before using them). – Peter Sep 14 '19 at 15:02
  • @Peter I'd vote up that answer. – eerorika Sep 14 '19 at 15:14

1 Answers1

4

I'd suggest either std::end(the_vector) or change the return type to an std::optional<std::vector<UserDefinedObj>::iterator>. I prefer the former since it feels like it matches with existing functions in <algorithm>, but this is dealer's choice. Note that both options require changing the API, either to change the different return type or to add an extra argument; the return type change is probably easier to make.

Untested sample code using std::optional:

std::optional<std::vector<UserDefinedObj>::iterator> getNecessaryIterator(std::vector<UserDefinedObj>::iterator f,std::vector<UserDefinedObj>::iterator s)
{
    if(f->name == "Alex")
    { 
        return f;
    }
    else if(s->name == "Matt")
    { 
        return s;
    }
    return std::nullopt;
}
Stephen Newell
  • 7,330
  • 1
  • 24
  • 28