Hi, Christian Bauer wrote:
How about:
typedef const void * tinfo_t; struct tinfo_static_t {};
class SOMECLASS { public: static const tinfo_static_t tinfo_static;
SOMECLASS() : tinfo_key(&tinfo_static) {} SOMECLASS(tinfo_t ti) : tinfo_key(ti) {}
tinfo_t tinfo() const { return tinfo_key; }
protected: tinfo_t tinfo_key; };
const tinfo_static_t SOMECLASS::tinfo_static = {};
template<class T> inline bool is_exactly_a(const SOMECLASS & obj) { return obj.tinfo() == &T::tinfo_static; }
This looks promising. No explicit specializations of is_exactly_a<> are needed any more.
Why don't you want to use char* as a static source of address? Is it just a matter of taste? (If the class name is moved out of registered_class_options there is no duplication.) Or is something more involved I don't see? Is it guaranteed that no smart optimizer will merge all static tinfo_static_t into one (there are all the same, aren't they?) with the effect that all tinfo_keys will be the same? The char* version again (I just wrote it from memory. I hope I didn't make some silly mistakes): typedef const char* tinfo_t; class SOMECLASS { public: static tinfo_t tinfo_name; SOMECLASS() : tinfo_key(tinfo_name) {} SOMECLASS(tinfo_t ti) : tinfo_key(ti) {} tinfo_t tinfo() const { return tinfo_key; } protected: tinfo_t tinfo_key; }; const tinfo_t SOMECLASS::tinfo_name = "SOMECLASS"; template<class T> inline bool is_exactly_a(const SOMECLASS & obj) { return obj.tinfo() == T::tinfo_name; } BTW, maybe some disadvantage of both of the new ways: in order to avoid as much as possible hash clashes, which are costly, the seed for the hash calculation should be unique. With the new tinfos the bit pattern for them in most cases has just changing least significant bits. With a seed setup like tinfo^serial (serial a small number) for symbols as an example, one is likely to get more hash clashes, I guess. So the seed setup has to be changed for some classes as well, I think. Regards, Jens