如何使用const数据构造自定义const_iterator?

时间:2011-12-12 20:30:54

标签: c++

我正在为自定义容器(一些哈希映射类)编写迭代器类,让我们调用此容器Map

由于几个原因,从iterator派生const_iterator似乎很方便,我已经在其他一些自定义容器(一个数组类)中做了这个,这很好用,所以我想坚持这种模式。

但现在这导致了以下问题(非常笼统/抽象,我很抱歉):

无论const_iterator的关键数据成员是什么(可能是Map引用,还是指向Map::Elements的指针,都有很多方法可以实现),需要非const ,因此const_iterator和派生的iterator都可以在其方法中有意义地使用它。

但是,在处理const Map对象时(例如调用方法const_iterator Map::Begin( void ) const),如何以正确的方式初始化这个非常量数据成员?


为了说明我的问题,我编写了一些示例代码,通过使用const_cast来解决问题,我认为这是一种糟糕的风格:

#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;
};

1 个答案:

答案 0 :(得分:2)

当我过去玩这个时,我确信继承并不是一个好主意。虽然iteratorconst_iterator可能会共享大量代码,但它们在界面中并没有太多共享。

相反,我使用模板来重用代码,因此iteratorconst_iterator只是同一模板的两个版本。提供适当的隐式转换运算符。

但是如果你坚持继承模型,并且不希望你的迭代器有自己的非const引用(即它的构造函数初始化它的非const版本和基类的const版本),那么{{1我想是唯一真正的选择。