1

Is there a way to check that iterator (passed to function as parameter "last") is equal to end() in case I haven't the container itself?

template<typename ForwardIterator>
void MyFunc(ForwardIterator first, ForwardIterator last) {
...
}
5
  • 7
    MyFunc shouldn't need to know if last is the end of any given container or not, if it does then you should probably rethink its design. Commented Mar 20, 2015 at 9:50
  • 1
    So you're asking if you can compare to a value which you don't have? Commented Mar 20, 2015 at 9:50
  • 2
    No, the OP is asking whether the iterator can itself determine if it is equal to a value the OP doesn't have. Commented Mar 20, 2015 at 9:52
  • 1
    The code above can't even establish if the iterator is to a container ! Consider a stream iterator from an std::ifstream. Commented Mar 20, 2015 at 10:25
  • Generally, no. Iterators can be many things. Given int arr[7];, then arr and arr+7 are valid iterators. Commented Mar 25, 2015 at 17:19

2 Answers 2

1

AFAIK - no. If you don't have the container, you can't get the ::end() iterator, thus you can't do the comparison. Why not pass the container as reference?

Check out: Testing whether an iterator points to the last item?

Sign up to request clarification or add additional context in comments.

4 Comments

trying to write an algorithm in stl-style which are getting first and last iterators of the sequence
In which case you should use last as the end of the sequence
Last is not supposed to be the end of the sequence. It is supposed to be the iterator pointing to the last element in range you wish to get processed by algorithm. In other words - if you want to pass an iterator to the end, then do it, but don't force it.
In stl descriptions, I see typically: "....the range [first, last) ...." , so that means that "last" element is not included into algorithm logic?
1

Normally, MyFunc should consider the range including first and excluding last just as the standard algorithms do, too.

Which is done in the standard library for the exact reason (or problem) that you are stating. Typical calls to algorithm functions that take e.g. an entire container look like algoname(foo.begin(), foo.end()); where foo.end() is an iterator that points to an invalid element after the last valid one. The algorithm would thus need to somehow know whether it can dereference any given iterator (or, at the very least, the one given in last).

On the other hand, the problem is entirely avoided by defining that last is exclusive. So, for example iterating over the elements can be done in terms of for(... it != last), and this same code will work for any and every value of last, both ones that refer to valid objects, and the one returned by end(). The only thing the implementation needs to make sure is that first <= last, and nothing can go wrong.

5 Comments

acutally I'm writing a learning task to implement classic sort algorithms, e.g. for bubble sort: template<typename BidirectionalIterator> void BubbleSort(BidirectionalIterator first, BidirectionalIterator last) { while( first != --last ) for(BidirectionalIterator iter2 = first; iter2 != last ; ++iter2) if (*iter2 > *(iter2 + 1) ) std::swap(*iter2, *(iter2 + 1)); does it look ok in terms of iterating?
Since you decrement last you need to be sure that first != last (first == last is nonsensical for sorting, but nevertheless legal). Also, you need last > first for that loop. So alltogether a >= check is missing. While first > last doesn't make sense and isn't legal according to your API contract (given the names "first" and "last"), doing it wrong shouldn't cause your code to be trapped in an infinite loop.
so I can't use last > first because supposed that iterators are bidirectional, not a randomaccess
That's unluckily true, so equality is the best you can use in that case to guard against empty ranges (you can't protect yourself against reversed ranges).
Yeah, I see, the only issue can be safe is first== last initially. I'll add the condition. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.