Reputation: 43109
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
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;
}
output:
0
Upvotes: 0
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
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