I think std::type_index is what you are supposed to use here. Assuming C++11.
IIRC its implemented as a pointer to the type info so if you dont have C++11 you can read if the standard says anything about directly using a pointer to the type info structure as the key. EDIT: though it says nothing about how the comparison is done so its possible that internally it just compares the string names or other such complicated operation.
Why would the hash_code() or name() functions ever return the same for two different types? And why could they change on different invocations of the program?
Hashes compress a large amount of information into a smaller amount of information so by the pigeonhole principle some pieces of information will 'compress' to the same hash. These are called hash collisions and are inevitable unless you specifically find a hash function for a set of known data that has no collisions. That could be done here, but if its not in the standard, its not.
The reason the name might be same for different types is probably the same. For some reason, it wasnt thought necessary to require that. Perhaps the intended purpose of the method is different and does not require uniqueness.