Search code examples
c++11iteratorconst-iterator

How can I implements "iterator classes" with enable conversion between "const_iterator" to "iterator"?


Given the following code:

template< class T , class SIZE >
class Set {
   T* a;  
public:  
   ...
   ...
   class iterator {  
      ..
      ..
   };
   class const_iterator {  
       ..
       ..
   };
   iterator begin();
   iterator end();
   const_iterator begin() const;
   const_iterator end() const;
};

How can I implement the iterator classes so that the following code will be valid?

Set<std::string, 5> set;
Set<std::string, 5>::const_iterator it=set.begin();   

Namely, how can I implement the classes of the iterators so that I will be able to convert const_iterator to iterator?


Solution

  • You could use a converting constructor defined as such:

    class const_iterator {  
    public: 
        const_iterator(iterator it) { /*...*/ }
    };
    

    or use a conversion operator as such:

    class iterator {  
    public:
        operator const_iterator() { return const_iterator(/*...*/); }  
    };
    

    The most common way to implement the iterator/const_iterator pair though is by using a template like this:

    template<typename T2>
    class iterator_impl {
    private:
        // iterator info
    public:
        // conversion for const to non-const
        operator iterator_impl<const T2>() { return iterator_impl<const T2>(/*...*/); } 
    };
    
    // define the typedefs for const and non-const cases
    typedef iterator_impl<T> iterator;
    typedef iterator_impl<const T> const_iterator;
    

    Obviously the last approach is the best, because you only have to implement the iterator functions one and since they only differ in the fact that one is const and the other isn't, then the argument T2 will take care of that.

    Note. I haven't tested the above code, it's for viewing purposes only, but I believe it conveys the idea.