C++ Run-Time Type ID brain fart.

Started by
8 comments, last by Sc4Freak 14 years, 5 months ago
I was looking for a way to automatically generate a run-time ID for any and every types. I came up with this:

template < typename _Type >
struct TypeRTID
{
	static size_t const m_id;
};
template < typename _Type >
size_t const TypeRTID < _Type > ::m_id = (size_t const) &TypeRTID < _Type > ::m_id;
you can use it like this:

size_t const floatRTID = TypeRTID < float > ::m_id;
size_t const floatPtrRTID = TypeRTID < float * > ::m_id;
Advertisement
That's pretty nifty, seems to work on Visual C++ 2008 just fine..

I love that in C++, you learn something new all the time, regardless how long you've been using it [smile].

-Danu
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
What does that give you over the standard typeid operator?
Quote:Original post by Oiu1233
I was looking for a way to automatically generate a run-time ID for any and every types.
Why?

There are very few times that you need this kind of ID, and those few times (such as serialization) can be handled easily through a base class.
So, in short, you'd be using the address of the static member to identify the type at runtime?

Looks interesting. Are there any drawbacks to this?
[size="2"]I like the Walrus best.
From what I can tell, it would fall short of polymorphic types. TypeID has a dynamic component which incurs runtime cost but will give you a more useful result.

This method ensures static compilation, but because of that its probably a little limited in non-trival use-cases.
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Quote:Original post by owl
Are there any drawbacks to this?
There always are.


It creates a static instance of every object. This may be an issue if you have large objects or nontrivial constructors.

The type must allow external linkage. It is possible to give a typename that has no linkage or internal linkage, and experienced template metaprogrammers use those. They would break the system.

Dynamic linking will give different results. Each module will have a different static instance, so provide different answers.

The value may differ between builds. It is quite likely that the addresses will change, and an id from one build may refer to a completely different type in another build, or refer to no object whatever.

There is broad liberty for the compiler as to how to interpret template type names. It is possible to have names unexpectedly merged, or types that you would expect to be merged end up distinctively different. If you use template types or typedef names it may be expanded to various unkonwn degrees.

Don't discount compiler bugs: there are still some linkers out there that will not properly merge duplicate templates.




There are very few reasons where you need to get an actual type id at runtime, and most of those can be handled through more reliable solutions.
This is neat, thanks for sharing.

I use a similar system, but mine's based on doing a hash of typeid(t).name(), which still requires you to have RTTI enabled.
Quote:Original post by Codeka
What does that give you over the standard typeid operator?
typeid requires RTTI to be enabled in your compiler, which increases the size of your binaries. Not usually a problem, but some consoles do recommend disabling RTTI.

Also, MSVC is really slow at doing comparisons between type_info structures (lots and lots of strcmps!). Sometimes a lightning fast (but restricted -- no polymorphism) type compare comes in handy.
Quote:Original post by frob
There are very few times that you need this kind of ID, and those few times (such as serialization) can be handled easily through a base class.
What if you don't want to have the requirement of all serializable objects having a common base class? (e.g. I want my lightweight Vec4 class to be serializable...)

Like you point out above though, the fact that the IDs can change makes this unsuitable to serialization to files (still good for network replication though).

[Edited by - Hodgman on November 11, 2009 5:50:39 PM]
I think the biggest problem is that assignment of IDs isn't guaranteed to happen before they're used. So before main() they could be set to zero and if you have other code using implicit initialization like this that depends on your IDs you could have subtle, hard to debug issues emerge.
Quote:Original post by frob
Quote:Original post by owl
Are there any drawbacks to this?
There always are.

It creates a static instance of every object. This may be an issue if you have large objects or nontrivial constructors.


Does it really? Objects of type _Type are never actually instantiated. The only thing that will be constructed is the size_t - one for each different _Type you use. Large objects or nontrivial constructors for _Type don't really seem like issues here.
NextWar: The Quest for Earth available now for Windows Phone 7.

This topic is closed to new replies.

Advertisement