Some container member functions only accept iterator as parameters, rather than const_iterator. If you only have one const_iterator
To insert new elements in the container location? That is, how to convert const_iterator to iterator? It does not exist from const_iterator
Implicit conversions between iterator, so you must be the main character of this operation.
I know what you're thinking. You are thinking, "whenever there is no way to go, raise the sledgehammer !". In the C ++ world, what you mean is
Yes: ing. This idea is shameful. I really don't know where you learned it.
Let's face the problems that plague you. Let's see what happens when you map a const_iterator to an iterator: Typedef deque < Int > Intdeque; // Convenient typedef
Typedef intdeque: iterator ITER;
Typedef intdeque: const_iterator constiter;
Constiter ci; // CI is const_iterator
Iter I (CI ); // Error! No const_iterator Implicit conversion to iterator
Iter I (const_cast < ITER > (CI )); // Still an error! Cannot start with const_iterator Ing to iterator!
Here we only use deque as an example, but use other container classes-list, set, Multiset, MAP, multimap, or even hash containers. Using the ing line may be in the vector or stringCodeCan be compiled, but this is a very special situation that we will discuss soon.
The reason that the code containing the ing cannot be compiled is that for these containers, iterator and const_iterator are completely different classes. They are not similar to strings.
And complex <float>. It is ridiculous to map const_cast between two unrelated classes, so
Reinterpret_cast, static_cast, and even c-style ing will also result in the same result.
Alas, codes that cannot be compiled may be compiled by the vector and string containers. This is because most implementations usually adopt
Use real pointers as the iterators of those containers. In this implementation, vector <t>: iterator is the typedef of T *, while
Vector <t>: const_iterator is const
T *'s typedef, string: iterator is char *'s typedef, while string: const_iterator is const
Char * typedef. In this case, you can use const_cast to map const_iterator to iterator.
Because the const_cast ing between const_iterator and iterator is finally interpreted as const
T * to T * ing. However, even in this implementation, reverse_iterator and const_reverse_iterator are real classes, so you still
However, you cannot directly use const_cast to map const_reverse_iterator to reverse_iterator. In addition, these implementations are usually
In the release mode, pointers are used to represent the iterators of vector and string. All these facts indicate that it is pathological to map the const iterator into the iterator, even if
The same is true for vector and string, because portability is very doubtful.
If you get a const_iterator and can access the container to which it points, there is a safe and portable way to get
Iterator, and do not need to fall into the Type System Conversion. The following is the essence of the solution, although it must be slightly repaired before Compilation
Change: Typedef deque < Int > Intdeque; // Same as before
Typedef intdeque: iterator ITER;
Typedef intdeque: const_iterator constiter;
Intdeque D;
Constiter ci;
// Point CI to d
Iter I (D. Begin ()); // Initialize I to D. Begin ()
Advance (I, distance (I, CI )); // Move I to the CI location (But pay attention to the following The reason to adjust it before compilation)
This method looks very simple, straightforward, and surprising. To obtain the iterator that points to the same position as const_iterator, first point iterator
The starting position of the container, and then move it forward to the same position as the const_iterator offset from the starting position of the container! This task obtains two function templates: Advance and
Distance help, which are declared in <iterator>. Distance returns the distance between two iterator pointing to the same container;
Advance is used to move an iterator to a specified distance. If I and CI point to the same container, the expression advance (I, distance (I,
(CI) will move the I to the same position as the CI.
If this code can be compiled, it can complete this conversion task. But it seems that things are not so smooth. For more information, see
See the distance definition:
Template < Typename inputiterator >
Typename iterator_traits < Inputiterator > : Difference_type distance (inputiterator first, inputiterator last );
do not get stuck with the 56-character return type of the function, or ignore what difference_type is. Instead, focus on the parameter type inputiterator:
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> template typename inputiterator >
typename iterator_traits inputiterator > :: difference_type
distance ( inputiterator first, inputiterator last);
When distance is called, your compiler must deduce the inputiterator type based on the real parameter type used. Let's take a look at the distance call that is not correct: Advance (I, distance (I, CI ));//Adjust I to point to the CI location
Yes
Two parameters are passed to distance, I, and CI. The I type is ITER, that is, deque <int>: typedef of iterator. For the Compiler
This indicates that the inputiterator that calls distance is deque <int >:: iterator. But Ci is constiter, that is
Deque <int>: typedef of const_iterator. This indicates that the inputiterator is deque <
Int>: const_iterator. Inputiterator cannot have two different types at the same time, So calling distance fails. Generally
Some lengthy error information may or may not indicate that the compiler cannot determine the type of inputiterator.
To call distance smoothly, you need to exclude ambiguity. The simplest way is to explicitly specify the type of the template parameter called by distance, so that the compiler can avoid obtaining their own types: Advance (I, distance<Constiter>(I, CI ));
Now we know how to get the corresponding iterator of const_iterator through advance and distance. But the other one, which we keep avoiding, is worth it.
The actual problem is: how efficient is this technique? The answer is simple. It depends on what type of iterator you are converting. For randomly accessed iterators (such as vector, string, and
In deque), this is a constant time operation. For bidirectional iterators (that is, all other containers and some implementations including hash containers), this is a linear time operation. Because it may consume lines
The cost of time to generate an iterator equivalent to const_iterator, And because if you cannot access the container to which const_iterator belongs
Unable to complete. From this perspective, you may need to review the design of iterator generated from const_iterator.