Terms 27: Translate const_iterator into iterator with distance and advance
Terms 26 pointed out that some container member functions accept only Iterator as a parameter, not const_iterator. So, if you only have a const_iterator, and you want to insert a new element in the container location it points to? That is, how do you convert the const_iterator to iterator? Because as explained in terms 26, there is no implicit conversion between const_iterator to iterator, so you must be the protagonist of this action.
I know what you are thinking. You are thinking, "When you don't have a road, just raise your big hammer!" In the world of C , you mean only: mapping. This idea is very shameful. I really don't know where you are learning.
Let us face problems in front of you. See what happens when you map a const_iterator mapping to iTerator:
Typedef deve
TYPEDEF INTDEQUE :: item;
TypedEf INTDEQUE :: Const_Iterator constitr;
Constiter Ci; // CI is const_iterator
...
ITer i (ci); // error! No from Const_Iterator
/ / The way to Iterator implicit conversion
ITer I (const_cast
// Map to Iterator!
Here is just as an example, but the result of the Hash table container [1]-of the other container -LIST, SET, MultiSet, Map, MultiMap, and even clause 25. Using the map of the map perhaps when you can compile when the version of Vector or String, this is the very special situation we have to discuss immediately.
The code containing the map cannot be compiled with the reason for these containers, Iterator and Const_Iteerator are completely different classes. They are not more blood relationships than String and Complex
Oh, the code that cannot be compiled may be able to compile by the vector and String container. That is because most implementations will use real pointers as an iterator of those containers. For this implementation, Vector
Typedef Deque
TYPEDEF INTDEQUE :: item;
TypedEf INTDEQUE :: Const_Iterator constitr;
INTDEQUE D;
CONSTITER CI;
... // Let CI point D
ITer I (D. Segin ()); // Initialization I is D.BEGIN ()
Advance (i, distance (i, ci)); // Adjust I, point to CI
// (But please pay attention to why
// The reason for modification before it compiles)
This method looks very simple, straightforward, it is also very shocked. To get the Iterator pointing to the same location to the same location, first point the item to the starting position of the container, and let it move to the position of the offset from the const_iterator to the starting position of the container! This task gets the help of two practical algorithms Advance and Distance, which are declared in
If this code can be compiled, it can complete this conversion task. But it seems that things are not so smooth. Want to know why, let's take a look at the definition of distance:
Template
TypeName Iterator_Traits
Distance (InputITerator First, InputITerator Last); Don't be trapped by this function of 56 characters, and you don't have to pay for Difference_Type. Instead, the focus is concentrated in the type of parameter inputiterator:
Template
TypeName Iterator_Traits
Distance (InputITerator First, InputITerator Last);
When you encounter a distance call, your compiler needs to infer the type of InputItemrator based on the parameter type used. Let's take a look at what I said is less right. Distance call:
Advance (i, distance (i, ci)); // Adjust I, point to CI
There are two parameters to deliver to Distance, I and CI. The type of i is iTer, namely Deque
To call Distance, you need to exclude ambiguity. The easiest way is to explicitly specify the type of template parameters called by Distance, which avoids the compiler yourself to get their type:
Advance (I, Distance
We now know how to get the corresponding Iterator through Advance and Distance. But another actual problem we have always avoided is very valuable is: What is the efficiency of this skill? The answer is simple. Depends on what iterators you are converting. This is a constant time operation for random access iters (such as Vector, String, and Deque). For bidirectional iterators (that is, all other containers and some implementations including Hash containers [3] (see Terms 25), this is the operation of linear times.
Because it may cost the price of linear time to generate one and const_iterator equivalent Iterator, and because if it is not possible to access the container to which the Const_Iiterator belongs, it cannot be completed. From this perspective, maybe you need to re-examine you from const_iterator to generate the design of Iterator. In fact, considering the provision of terms 26, it is recommended that you try to use Iterator as much as possible when handling the container.
[1] Two most common HASH-based STL containers are implemented from Dinkumware and SGI. You can find an overview of a Dinkumware method from the Cuj column "Hash table" in P. J.Plauger in November 1998. Amade the unique SGI implementation method of SGI from the clause of Effective STL 25, but its interface describes the SGI STL website.
[2] This happens when using Stlport debug mode. You can learn from Stlport's website to Stlport and its debug mode.