During programming courses I received a task - to write an analog std :: vector in C ++ with preservation of the function and interface, in order to make it at least twice as fast a million times more readable. In the course of execution, I was faced with the fact that Random access iterators have some
very strange interesting features that I wanted to change. Who cares - welcome under cat.
Briefly about iterators
On Habré there is already a good article about iterators
hereFrom myself I want to add only the definition from the
article about iterators on Wikipedia.Iterator - an object that abstracts a single interface access to the elements of the collection.
Create an iterator
So, create two vectors of integers:
vector<int> vector1; vector<int> vector2;
Fill both numbers from 0 to 14:
for ( int i = 0; i < 15; i++ ) { vector1.push_back(i); vector2.push_back(i); }
Create iterators for each vector:
vector<int>::iterator it1 = vector1.begin(); vector<int>::iterator it2 = vector2.begin();
Actually interesting features
The first thing that caught my eye was the presence of an overloaded operator "-" and the absence of an overloaded operator "+" for two iterators (the addition of an iterator with an int is provided for). Create an additional iterator for the first vector and do both:
vector<int>::iterator temp = vector1.begin() + 3; cout << temp - it1 << endl; <s> cout << temp + it1 << endl;</s>
In the first case, we obtain output 3, in the second, a compilation error.
Secondly, I was interested in the issue of equality of iterators. Based on the definition, the iterator must provide access to the elements of the collection. That is, if two iterators belong to different collections, cap suggests that you cannot compare them at all. But:
if ( it1 == it2 ) { cout << "Equal" << endl; } else { cout << "Not equal" << endl; }
At the exit, we have “Not equal”, which, given the strangeness of the very possibility of such a comparison, is very logical.
After I realized that it was possible to compare iterators of different objects, I decided to try to subtract one from the other:
cout << it1 - it2 << endl;
At the output we get 34. Immediately I remembered Pelevin and his "Numbers".
Brief annotationThe hero of Pelevin’s novel “Numbers” is a businessman Stepan. Even as a child, Stepa realized that he was not like everyone else. Stepa felt an inexplicable latent craving for number 7, but did not understand how to please this great number, which so many talented people worship. As a result, he realized that 7 is nothing more than 3 + 4 (which we will see later on), so he began to worship the number 34, subjugating to him all his life.
Taken from
pelevin.nov.ru/stati/o-lleo2/1.html The fact that at the output we get unpredictable int is connected with how the vectors are located in memory relative to each other. Having tried to fill both vectors with different numbers of numbers, I got a completely different result.
Well, the most interesting:
it2 += 34; if ( it1 == it2 ) { cout << "Equal" << endl; } else { cout << "Not equal" << endl; }
At the exit, as you already guessed "Equal". This leads to the following, disappointing from my point of view, conclusion that:
it2 = vector2.begin() + 34;
let us iterate the first vector, not the second.
')
findings
When creating the Random access iterator, the developers did not limit the use of the iterator only to the framework of the container for which it was created. I can understand their logic, although I personally don’t like it. Close comparison and subtraction of iterators pointing to different vectors would not be very difficult. And although, perhaps, such situations are rare, do not forget about these features.