示例第一:
templatestruct 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%.内联对我来说至关重要.
正如jalf在评论中建议的那样,您可能想要使用奇怪的重复模板模式(CRTP)的变体.也就是说,创建MyHashingSolution
一个由派生类参数化的类模板:
templatestruct 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 (this); } };
在这种情况下,因为您希望派生State
类也是一个模板,所以您需要采取稍微不同寻常的步骤来声明State
为采用模板模板参数的类模板:
template class HashingSolution> struct State : public HashingSolution> { typedef HashingSolution > Parent; void Update(int idx, int val) { Parent::UpdateHash(idx, val); // g++ requires "Parent::" } int GetState(int idx) { return ...; } };
关键点在于,如果State
继承自HashingSolution
,Derived
则是一个派生类,HashingSolution
因此编译中的static_cast
向下转换HashingSolution
并正常工作.(如果你陷入困境并从中派生State
出来HashingSolution
,然后尝试一些涉及调用的东西,derived()
编译器会因为static_cast<>
不符合要求而抱怨.)
然后声明State
要使用的具体类,如下所示:
typedef StateMyState;
遗憾的是,此解决方案具有副作用,您需要将DummyHashingSolution
(以及任何其他此类类型)更改为忽略其一个模板参数的模板,以使其可用作模板模板参数.