How to convert const_iterators to iterators using std::distance and std::advance

A short posting demonstrating how to remove the const-ness of a const_iterator, given that it is not possible to use re-casting along the lines of const_cast<> to convert from const_iterator to iterator. Consider the following example: [code language="cpp"] #include <iostream> #include <vector> class A { public: A( int x ) { val = x; } void DoStuff() { std::cout << "val = " << val << std::endl; } private: int val; }; int main() { // Initialise vector with pointers to A objects A* a[] = { new A( 1 ), new A( 2 ), new A( 3 ), new A( 4 ) }; std::vector<A*> v( a, a + 4 ); // Iterate over the elements for ( std::vector<A*>::const_iterator cit = v.begin(); cit != v.end(); ++cit ) { std::vector<A*>::iterator it = cit; } return 0; } [/code] Which results in the following compilation error: error C2440: 'initializing' : cannot convert from 'std::_Vector_const_iterator<_Myvec>' to 'std::_Vector_iterator<_Myvec>' One approach, already explained in much detail over at Dr Dobbs' site is that of defining an iterator which is made to move linearly until it reaches the element to which const_iterator points. First define some suitable typedefs for your iterators and const_iterators (iter and const_iter), and use std::advance and std::distance to access the iterators. Like so: [code language="cpp"] #include <iostream> #include <vector> class A { public: A( int x ) { val = x; } void DoStuff() { std::cout << "val = " << val << std::endl; } private: int val; }; // Define our iterators typedef std::vector<A*>::iterator iter; typedef std::vector<A*>::const_iterator c_iter; int main() { // Initialise vector with pointers to A objects A* a[] = { new A( 1 ), new A( 2 ), new A( 3 ), new A( 4 ) }; std::vector<A*> v( a, a + 4 ); // Iterate over the elements iter it = v.begin(); for ( c_iter cit = v.begin(); cit != v.end(); ++cit ) { std::advance (it, std::distance<c_iter>(it, cit ) ); (*it)->DoStuff(); } return 0; } [/code] This solving the problem of compilation and giving us access to the iterators we want:

Comments

Popular posts from this blog

Using the Supervisor Controller Pattern to access View controls in MVVM

Getting started with client-server applications in C++

How to send an e-mail via Google SMTP using C#