6

共有イテレータ インターフェイスの実装について質問があります。

postix 演算子の一般的な方法として、関数は次のようになります。

IteratorClass operator ++(int) {
  IteratorClass temp = *this;

  //increment stuff

  return temp
}

そして、ほとんどの場合、これで問題ありません。私の場合、1 つのクラスに 3 つのイテレータを実装しようとしています。各反復子はローカル コレクション クラスにデータをロードしますが、各派生反復子は異なる方法でデータをロードします。コレクション クラスは同じであり、演算子 (接尾辞/接頭辞 ++/--, *) のすべてのコードも同じであるため、これを実装する良い方法は継承だと思いました。

struct iterator {
  protected:
  Collection collection;
  public:
  operator++(int);
  operator++;
  operator--(int);
  operator--;

  virtual load() = 0;

}

struct iterator1 : public iterator {
  virtual load() { custom load function }
}

struct iterator2 : public iterator {
  virtual load() { custom load function }
}

問題は後置演算子です...彼らは抽象型のオブジェクトを作成してからそれを返そうとしています。回避策や構造の変更に関する提案はありますか?

4

1 に答える 1

10

基本クラスに最終クラスを認識させるには、 CRTP イディオムを使用します。例えば:

template<typename T>
struct iterator_base {
  public:
  T operator++(int) {
    T temp = static_cast<T&>(*this);
    ++*this;
    return temp;
  }
  T& operator++() {
    // ++ mutation goes here
    return *this;
  }
  // ... likewise for --, etc.
};

struct iterator1: public iterator_base<iterator1> {
  // ... custom load function
};

このアプローチは静的ポリモーフィズムと呼ばれ、(場合によっては) 完全に回避virtualしてオブジェクトを小さくすることができます。load基本クラスから宣言を省略して、T::loadasを呼び出すことができstatic_cast<T&>(*this).load()ます。

于 2013-08-11T14:22:19.253 に答える