2012-04-20 2 views
0
Iがあれば、

それは相手イテレータ

class MyContainer; 

template <typename T> class myiterator :public iterator<bidirectional_iterator_tag, T> 
{ 
    friend class MyContainer; 
    private: 
    T *pointer; 

    myiterator(T *pt):pointer(pt) {} 

    public: 
    T& operator*() {return (*pointer);} 

    const myiterator<T>& operator++() 
    { 
     pointer->current_iterator++; 
     return *this; 
    } 

    bool isEnd(void) const 
    { 
     return pointer->current_iterator == pointer->data.end(); 
    } 
    }; 

class MyContainer 
{ 
    friend class myiterator<MyContainer>; 
    public: 
    typedef myiterator<MyContainer> iterator; 
    typedef myiterator<MyContainer const> const_iterator; 

    private: 
    map<int, int> data; 
    map<int, int>::const_iterator current_iterator; 

    public: 
    MyContainer() {current_iterator = data.begin(); } 

    void addDataPair(int key, int value) {data[key] = value;} 

    int first() const {return (*current_iterator).first;} 
    int second() const {return (*current_iterator).second;} 

    iterator begin() 
    { 
     current_iterator = data.begin(); 
     return iterator(this); 
    } 

    const_iterator begin() const 
    { 
     return const_iterator(this); 
    } 
    }; 

このコードの実行OK要素の動作について、より柔軟な制御を提供するように、私は自己定義されたコンテナとSTLコンテナを拡張しています

だからconst_iteratorのを定義するために失敗しました

MyContainer h; 

h.addDataPair(1, 1); 
h.addDataPair(2, 2); 
h.addDataPair(3, 3); 

for (MyContainer::iterator it=h.begin(); !it.isEnd(); ++it) 
{ 
    cout << (*it).first() << " " << (*it).second() << endl; 
} 

に従うとして、イテレータを使用しかし、私はconst_iteratorのにイテレータを変更した場合には、コンパイルされません。私は定数のイテレータを定義するために、value_typeをXからX constに置き換えるという記事を読んでいます。これが私のコードで行ったことです。しかし私はすぐに私のケースでは動作しないかもしれないことがわかります。なぜなら、イテレータによって返されたリファレンスは私のケースではコンテナ自体であるからです。私は、コーディングを重複させずにconst_iteratorを動作させる方法を知らない。

さらに、私のイテレータはstd :: iteratorから派生していますが、私はイテレータのコンストラクタ をオーバーライドできないことがわかりました。これは、T * pt以外のイテレータに複数のパラメータを渡すことができる方法ですか?ありがとう。

+0

これはちょっと奇妙です。 MyContainerはコンテナとイテレータの両方に表示されます。 –

+0

私は知っている:)私は、コードをマップの要素を直接変更しないようにするため、オペレータ[]、演算子++などでマップデータにアクセスしようとしている間にラッパーを制御して書きました。 std :: mapを継承するつもりですが、仮想デストラクタのためにそうすることはお勧めできません。とにかく、これは私が考えることができるインターフェイスをマップとして近くに保持し、いくつかのコントロールを追加する唯一の方法です。 – user1285419

+0

constマップが提供しないことを望んでいるのは何ですか? –

答えて

1

まず問題:

あなたはこの変更した場合:

for (MyContainer::const_iterator it=h.begin(); !it.isEnd(); ++it) 

for (MyContainer::iterator it=h.begin(); !it.isEnd(); ++it) 

を、あなたはbegin()end()から非const iteratorを取得し、からconst_iteratorを初期化してみてくださいそれは違うタイプで、あなたのmy_iteratorテンプレートにはコンストラクタがありません他のタイプからの建設も可能です。 、const_iterator

template<typename> friend class myiterator; 

template<typename T2> 
    myiterator(myiterator<T2> const& i) : pointer(i.pointer) { } 

あなたはまた、operator*のconstをしなければならない

をしかし、より大きな問題はまだあります(それはそれを逆参照するイテレータは変更されません。):

あなたは追加することによって、これを修正することができますconst MyContainerを指しますが、const_iterator::operator++はそのオブジェクトを変更する必要があります。そのオブジェクトはconstなので変更できません。したがって、あなたはあなたのconst_iteratorを増やすことができません。つまり、それを使って反復することはできません!そのデザインを考え直すことをお勧めします。

関連する問題