0

要素の操作をより柔軟に制御できるように、stl コンテナーを自己定義コンテナーで拡張しています。

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

次のようにイテレータを使用すると、このコードは正常に実行されます

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 以外に複数のパラメーターをイテレーターに渡す方法はありますか? ありがとう。

4

1 に答える 1

1

最初の問題:

これを変更した場合:

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

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

iterator次に、から非constを取得し、そこから初期化しようとしますがbegin()、これは別のタイプであり、テンプレートには別のタイプからの構築を可能にするコンストラクターがありません。end()const_iteratormy_iterator

次を追加することで修正できます。

template<typename> friend class myiterator;

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

また、constを作成する必要がありますoperator*(イテレータを間接参照するように変更することはありません)。

しかし、さらに大きな問題があり、はをconst_iterator指しますが、そのオブジェクトを変更する必要const MyContainerconst_iterator::operator++あります。これは、constであるため変更できません。したがって、インクリメントすることはできません。const_iteratorつまり、反復するために使用することはできません。そのデザインを再考することをお勧めします。

于 2012-06-16T02:35:33.387 に答える