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()编译并正常工作。(如果你搞砸了并从中派生StateHashingSolution<SomeOtherType>然后尝试一些涉及到调用的事情,derived()编译器会抱怨static_cast<>不满足要求。)

然后State像这样声明要使用的具体类:

typedef State<MyHashingSolution> MyState;

不幸的是,此解决方案具有副作用,您需要更改DummyHashingSolution(以及任何其他此类类型)为忽略其一个模板参数的模板,以使它们可用作模板模板参数。

于 2009-03-23T16:05:55.187 回答
0

作为在黑暗中的镜头,考虑到问题中几乎完全缺乏信息(见评论):模板有用吗?它们通常适用于编译时多态性。

要获得更多可能有用的信息,请进一步解释问题。看问题评论。告诉我们为什么您知道当您仍在进行基础设计时需要进行哪些微优化。如果有任何关于编译或执行环境的非主流,请给我们一些细节。

于 2009-03-23T14:19:40.183 回答