I'm writing the iterator classes for a custom container (some hash map class), let's call this container Map
.
For a couple of reasons it seems handy to derive iterator
from const_iterator
and I already did this in some other custom container (an array class), which works great, so I want to stick to this pattern.
But now that leads to the following problem (which is quite general/abstract, I'm sorry):
Whatever const_iterator
's critical data member is (it might be a Map
reference, or a pointer to Map::Elements
, many ways are possible), it needs to be non-const so both const_iterator
and the derived iterator
can utilize it meaningfully in their methods.
But how can this non-const data member, in a proper way, be initialized when dealing with a const Map
object (e.g. calling the method const_iterator Map::Begin( void ) const
)?
To illustrate my question bit, I wrote some example code that solves the problem by using const_cast which, I suppose, is bad style:
#include <vector>
template< typename K, typename T >
class Map
{
public:
class const_iterator
{
public:
const_iterator( Map const & a_Map, int a_Index ) :
m_Index( a_Index ),
m_Map( const_cast< Map & >( a_Map ) ) // Note the use of const_cast
{
}
private:
Map & m_Map;
int m_Index;
};
class iterator : public const_iterator
{
public:
T & operator * ( void )
{
return m_Map.mElements[ m_Index ];
}
};
public:
const_iterator Begin( void ) const { return const_iterator( *this, 0 ); }
iterator Begin( void ) { return iterator( *this, 0 ); }
private:
std::vector< T > m_Elements;
};
std::map
which will probably perform better than astd::vector
being wrapped into a custom map.m_Elements
of the Map that provided the iterator). Whatever approach I use the problem is always the same.