[英]How to have a static counter for global types?
我想要一个 static 计数器,每次创建另一种类型 class 时都会递增。 这是我尝试过的:
template <typename Type>
class Sequential_ID_Dispenser
{public:
static inline int nextDispensed = 0;
static int getID() { return nextDispensed++; }
};
struct DummyTypeForComponentIDs {}; // So that the same type is passed to getID()
template <typename T>
struct Component {
static inline int componentTypeID = Sequential_ID_Dispenser<DummyTypeForComponentIDs>::getID();
};
// The reason I've made it inherit like this is so that any time I add a new Component type/struct it'll automatically get an ID for that type
struct Hat : Component<Hat> {};
struct Tie : Component<Tie> {};
int main()
{
int id = Hat::componentTypeID; // = 0
id = Tie::componentTypeID; // = 1
}
这行得通。 但我想选择轻松地从任何其他组件继承,但它不能像这样工作,例如:
template <typename T>
struct Component {
static inline int componentTypeID = Sequential_ID_Dispenser<DummyTypeForComponentIDs>::getID();
};
struct Hat : Component<Hat> {};
struct Tie : Component<Tie> {};
struct BlueHat : Hat {};
int main()
{
int id = Hat::componentTypeID; // = 0
id = Tie::componentTypeID; // = 1
id = BlueHat::componentTypeID; // = 0, gets the same number as struct Hat : Component<Hat>{}
}
有没有好的解决方案? 理想情况下,我想在不将 arguments 传递给基本构造函数的情况下定义任何新结构。 我意识到我为此使用了 CRTP,这正是我为使其工作所做的工作,但必须有更简单的方法,对吧?
编辑:实际上我很惊讶解决方案并不容易,我想要的只是我在全局命名空间中创建的每个 class 以获得新的 ID,我猜是编译时间或运行时。
对于类型上的(运行时)计数器,您不需要 inheritance。
您甚至可以使用模板变量 (C++14):
std::size_t getId()
{
static std::size_t counter = 0;
return counter++;
}
template <typename T>
std::size_t Id = getId();
演示。
我看不到一个简单的方法来扩展你当前的解决方案来做到这一点,除非你想开始在每个 inheritance 声明器上抛出virtual
,并且记住每次都这样做。
无论如何,“计数类型”似乎有点反模式。 我们已经有了唯一的类型标识符,通过typeid
。
如果您真的需要一个int
,您可以让一些经理 class 接受std::type_info
并为您提供该类型独有的int
,可能使用 map 为其供电。 但是,如果您可以首先存储std::type_info
,那就更好了。 缺点是这些信息不会静态可用(即“在编译时”)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.