I have written the following class to allow me to uniquely identify classes in C++, and I was wondering if there are any better ways of going about it.
#ifndef _TYPE_IDENTIFIER_H_
#define _TYPE_IDENTIFIER_H_
typedef std::size_t Identifier;
class TypeIdentifier {
public:
template<class T>
static Identifier get_identifier() {
static const Identifier current_identifier = ++next_identifier;
return current_identifier;
}
private:
static Identifier next_identifier;
};
Identifier TypeIdentifier::next_identifier = 0;
#endif
And an example of using it:
class MyFirstClass {};
class MySecondClass {};
printf("%zu", TypeIdentifier::get_identifier<MyFirstClass>()); // 1
printf("%zu", TypeIdentifier::get_identifier<MySecondClass>()); // 2
printf("%zu", TypeIdentifier::get_identifier<MySecondClass>()); // 2
printf("%zu", TypeIdentifier::get_identifier<MyFirstClass>()); // 1
I'm using it in an ECS, where there can only be one instance of a certain component in an Entity. I store a vector of structs containing a void pointer to the component and an Identifier
type of the component. Using TypeIdentifier::get_identifier<ComponentType>()
, I can check the type of a passed component and check if it's already present in the Entity.
1 Answer 1
Well you can use typeid
.
printf("%zu", typeid(MyFirstClass).hash_code());
Not sure how
TypeIdentifier::get_identifier<MyFirstClass>()
// ^^^^^^^^^^^^ Compile time type.
// This will not help with runtime
// type checking.
is going to help you.
Assuming the above is in a single header file (because of include guards).
Then this:
Identifier TypeIdentifier::next_identifier = 0;
Is in the wrong place. It will be defined for every compilation unit that includes the header. Personally I would use a function rather than a static value.
class TypeIdentifier {
public:
template<class T>
static Identifier get_identifier() {
static const Identifier current_identifier = getNext();
return current_identifier;
}
private:
static Identifier getNext() {
static Identifier next_identifier = 0;
return next_identifier++; //
}
};
-
\$\begingroup\$ I figure he has good reasons for prefering a compile-time solution, but it will be necessary to use a static local in a static member function to store his
next_identifier
, just like you have here. \$\endgroup\$Christopher Oicles– Christopher Oicles2016年02月19日 02:19:06 +00:00Commented Feb 19, 2016 at 2:19
Explore related questions
See similar questions with these tags.
MyFirstClass
is 1 and the type ID ofMySecondClass
is 2 (or the other way round, depending on the order of invocation). \$\endgroup\$