1

最初の例:

template <class HashingSolution> 
struct State : public HashingSolution {

  void Update(int idx, int val) {
    UpdateHash(idx, val);
  }

  int GetState(int idx) {
    return ...;
  }
};

struct DummyHashingSolution {
  void UpdateHash(int idx, int val) {}
  void RecalcHash() {}
};

struct MyHashingSolution {
  void UpdateHash(int idx, int val) {
    ...
  }

  void RecalcHash() {
    ...
    UpdateHash(idx, GetState(idx)); // Problem: no acces to GetState function, can't do recursive application of templates
    ...
  }
};

この例では、MyHashingSolutionをStateクラスに渡して、StateがHashingSolutionのメソッドにアクセスできるようにすることができますが、HashingSolutionはGetStateを呼び出すことができません。これを回避することは可能ですか?

これは最も深いループにあります。ここでの仮想関数は、パフォーマンスを25%以上低下させます。インライン化は私にとって非常に重要です。

4

2 に答える 2

5

jalf がコメントで示唆しているように、Curiously Recurring Template Pattern (CRTP) のバリアントを使用することをお勧めします。つまりMyHashingSolution、派生クラスによってパラメーター化されたクラス テンプレートを作成します。

template <typename D>
struct MyHashingSolution {
    typedef D Derived;

    void UpdateHash(int idx, int val) {
        ...
    }

    void RecalcHash() {
        ...
        UpdateHash(idx, derived().GetState(idx));
        ...
    }

private:
    // Just for convenience
    Derived& derived() { return *static_cast<Derived*>(this); }
};

この場合、派生Stateクラスもテンプレートにする必要があるため、テンプレート テンプレート パラメーターStateを受け取るクラス テンプレートとして宣言するという、少し変わった手順を実行する必要があります。

template <template <class T> class HashingSolution>
struct State : public HashingSolution<State<HashingSolution> > {
typedef HashingSolution<State<HashingSolution> > Parent;

    void Update(int idx, int val) {
        Parent::UpdateHash(idx, val);   // g++ requires "Parent::"
    }

    int GetState(int idx) {
        return ...;
    }
};

重要な点は、提供された はStateから継承されHashingSolution<State<HashingSolution> >Derivedの派生クラスであるHashingSolution<State<HashingSolution> >ため、 のstatic_cast<Derived*>(this)ダウンキャストがHashingSolution<State>::derived()コンパイルされ、正しく動作することです。State(失敗して代わりにから派生しHashingSolution<SomeOtherType>、 への呼び出しを含む何かを試みるとderived()、コンパイラは の要件が満たされstatic_cast<>ていないとして文句を言います。)

次に、使用する具象Stateクラスを次のように宣言します。

typedef State<MyHashingSolution> MyState;

DummyHashingSolution残念ながら、このソリューションには、テンプレートのテンプレート引数として使用できるようにするために、1 つのテンプレート引数を無視するテンプレート (および他のそのような型) に変更する必要があるという副作用があります。

于 2009-03-23T16:05:55.187 に答える