Why is the following code guaranteed to be a unique typeID ?!
using TypeId = uintptr_t;
template < typename T >
static TypeId GetTypeId()
{
static uint32_t placeHolder;
return (reinterpret_cast<TypeId>(&placeHolder));
}
Source
I don't understand why this is not just a kind of random memory location as a kind of "misused"... Thanks for answers in advance.
You are correct that the implementation abuses the "random memory location" of a block-scope static variable, but that doesn't mean that the guarantee you are talking about doesn't hold: the returned from GetTypeId<T>
will be unique for each instantiation of it.
Note: One should however be aware of the fact that
uintptr_t
is not guaranteed to be available for every platform. A fully portable way to implement the function would be to return avoid*
, which is guaranteed to be able to hold every address of every object in a program.
In C++ there's a guarantee that every object must reside at a unique address, unless we are talking about an object which is a subobject if another. In such case they may have the same address (and in cases the sharing of address is required, as with standard-layout classes and their first data-member).
1.8p6
The C++ object model[intro.object]
Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects that are not bit-fields may have the same address if one is a subobject of the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they shall have distinct addresses.
We also have an explicit clause saying that every specialization of a function-template that includes a static variable has its own unique copy of said static variable:
14.8p2
Function template specializations[temp.fct.spec]
Each function template specialization instantiated from a template has its own copy of any static variable.
Since a variable that is declared static is unique to every instantiation of GetTypeId<T>
, where T
is an arbitrary type, every object named placeHolder
in this template specialization must an unique object.
It must be an unique object, and with that; it must have a distinct address.
Note 1) In C++11 we have
std::type_index
which fulfils the guarantee you are after.
Note 2) The C++11 standard draft n3337 has been used as a reference in this post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With