WilliamKF
WilliamKF

Reputation: 43109

Are all end() iterators equivalent for a collection type?

Given a particular stl collection in C++, is the end() value equivalent for all instances of the same templatization? In other words, will the following work for all stl containers and circumstances (not just for std::map)?

std::map<Key, Value> foo(int seed);

std::map<Key, Value> instance1 = foo(1);
std::map<Key, Value> instance2 = foo(2);
std::map<Key, Value>::iterator itr = instance1.begin();
std::map<Key, Value>::iterator endItr = instance2.end(); // Comes from other collection!

for (; itr != endItr; ++itr) {
  // Do something on each key value pair...
}

Upvotes: 6

Views: 670

Answers (3)

Emanuele Paolini
Emanuele Paolini

Reputation: 10162

Try it yourself:

#include <map>
#include <iostream>
using namespace std;
map<int,int> m1;
map<int,int> m2;

int main() {
  cout<<(m1.end() == m2.end())<<endl;
}

http://ideone.com/o18DtQ

output:

0

Upvotes: 0

TemplateRex
TemplateRex

Reputation: 70516

No, because of the STL container and iterator requirements:

23.2.1 General container requirements [container.requirements.general]

6 begin() returns an iterator referring to the first element in the container. end() returns an iterator which is the past-the-end value for the container. If the container is empty, then begin() == end();

24.2.1 In general [iterator.requirements.general]

6 An iterator j is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == j. If j is reachable from i, they refer to elements of the same sequence.

The equality of begin() and end() for empty containers means that begin() and end() need to be part of the same container objects, and hence end() cannot be a static member of a container class. Note also that -except for forward iterators- applying operator-- on end() would be impossible to resolve with a static end() iterator.

Upvotes: 7

dhavenith
dhavenith

Reputation: 2048

In general, no, that is not portable. It may work by coincidence on some platform.

There are end-iterators that can be re-used for different ranges, such as the default-constructed istream_iterator:

ifstream a("foo.txt");
ifstream b("bar.txt");
istream_iterator<string> end;
istream_iterator<string> ia( a);
istream_iterator<string> ib( b);
// from here on both [ia, end> and [ib, end> are valid ranges.

Upvotes: 2

Related Questions