【发布时间】:2012-05-29 06:28:43
【问题描述】:
使用 CRTP(奇怪的重复模板模式),您可以为基类提供从它派生的类的知识。创建一个数组来存储从基类派生的每个类的实例并不难(参见示例)
class Base{
public:
static std::vector<Base *> m_derivedInstances;
};
template <class Derived>
class CRTPBase : public Base {
public:
static bool m_temp;
static bool addInstance()
{
m_derivedInstances.push_back(new Derived);
return true;
}
};
template <class Derived>
CRTPBase<Derived>::m_temp = CRTPBase<Derived>::addInstance();
我想知道是否可以创建所有派生类类型的类型列表(请参阅http://www.research.ibm.com/designpatterns/pubs/ph-jun00.pdf)。问题是每次编译器看到一个派生自Base 的新类时,它都需要将新类型附加到列表中,但类型列表是不可变的(可以创建一个附加新类型的新列表,但据我所知,向列表中添加元素是不可能的。最后我想要这样的东西:
struct DerivedClassHolder {
typedef Loki::TL::MakeTypeList</*list all derived classes here*/>::Result DerivedTypes;
};
最终目标是能够遍历所有派生自Base 的类。
【问题讨论】:
-
“遍历所有类”是什么意思?
-
如果你一直在谈论“
Base”,你可能走错了路。您没有基类。您有一个模板,每个新的派生类都可以从中获得自己的个人基类型。 -
另外,你想如何保证
m_derivedInstances在你在全局范围内调用addInstance时已经被初始化了? -
最后,我想遍历所有派生类型并对它们做一些事情(例如,使用 dynamic_cast 检查指向 Base 的指针到底是哪个派生类型。
-
m_derivedInstances 实际上并不是公共的,唯一可以访问它的是 addInstance ,它也是私有的,因此在初始化 m_temp 时唯一可以更改它的地方。我所要做的就是确保在 m_temp 之前初始化 m_derivedInstances。静态变量的初始化顺序只有在跨多个编译单元时才定义。
标签: c++ template-meta-programming crtp loki typelist