Uniqueness of type_info

Hello all,

If I use typeid on two instance of the same execution type, can I assume safely that the type_info returned are at the same memory location?
In other words, in this code:
1
2
3
4
5
class A { virtual ~A() {} }; // make A polymorphic
class B : public A {}

A* a = new B;
B* b = new B;

can I assume that &typeid(*a) == &typeid(*b) will alway be true?

I need it to associate an unique identifier for types to use as a key in map for exemple. I could use the string in type_info but it's far less performant than the pointer to type_info if I can use it.
Last edited on
If I use typeid on two instance of the same execution type, can I assume safely that the type_info returned are at the same memory location?

AFAIK, the IS does not specify that it must be the same object.

> can I assume that &typeid(*a) == &typeid(*b) will alway be true?

std::type_info has an operator==,
We can safely assume that typeid(*a) == typeid(*b) will alway be true.
We can safely assume that typeid(*a) == typeid(*b) will alway be true.

Yes I know it but it doesn't resolve my problem.

If I can't rely on typeinfo to have an unique identifier for each type, I think of another solution but find it not very elegant:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct IIdentifiable
{
virtual int getTypeId() = 0;
}

class A : public IIdentifiable
{
public:
virtual int getTypeId() override { return typeId_; }
static void static_init(); // initailize typeid_ with an unique identifier
private:
static int typeId_;
}


Here I have to write some boilerplate code every time i need the class to be associated with an id. I could use macros... but i try to use it only if there is no alternative.

Someone has a idea on a better way of doing?
Last edited on
In C++11 std::type_info has the member function hash_code(). Maybe you can use that?
Thanks for type_index and hash_code(), this is what I need.

After some research, I found that the data in type_info is not required to be in the same memory location but it encouraged to make hash_code faster by just taking adress. Apparently Unix implementations do it that way, it would be great if it was the same with windows...
I wonder if const is requred in static const int typeId_;
will it not give errror if you try to change or increament .
Last edited on
Yes bluecoder right... I put it const first because it doesn't have to change but as it have to be inititialized in static_init to avoid static initialisation fiasco i added static_init and forgot to remove const. And that is another concern with this technique: I have to manually call static_init on each type.
Why shouldn't a static member variable initialized via a function have a const qualifier, if it logically is a const?

1
2
3
4
5
6
7
8
9
10
struct A
{
    static int init() { std::cout << "A::init\n" ; return std::rand() ; }
    static const int s ;
    static const std::type_index index ;
};

const int A::s = init() ;

const std::type_index A::index( typeid(A) ) ;

Why shouldn't a static member variable initialized via a function have a const qualifier, if it logically is a const

I i use typeid i can use const but in this case all the static variable stuff is useless.
If i need this static variable, it is indeed logically const but i don't see how i can initialize it directly because i will surely have to rely on other static datas to do it so to avoid static initialization fiasco i need to do it in a static function which will be called manually.
> to avoid static initialization fiasco i need to do it in a static function which will be called manually.

Never a good idea to rely on a function being called manually to initialize something. Someone, somewhere, at some time is going to make a mistake - forget to call the initialization function, or call it multiple times.

Making sure that an object with static storage duration is initialized once, only once, and before its first use is one of the oldest problems in the language. Jerry Schwarz encountered it while implementing the iostream library - to ensure that if <iostream.h> is included in a translation unit, and a standard stream object (say cout) is used in the initialization of a global variable, cout must be initialized before it is used.
1
2
3
4
5
#include <iostream.h> // pre-standard C++

int n = ( ( std::cout << "initializing n\n" ), 1234 ) ;  

// ... 


The technique that Schwarz used continues to be a usable one.
See: http://www-d0.fnal.gov/KAI/doc/tutorials/static_initialization.html
Thanks JLBorges, very useful technique
Topic archived. No new replies allowed.