6

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.

4

1 回答 1

8

介绍

您是正确的,该实现滥用了块范围静态变量的“随机内存位置”,但这并不意味着您所谈论的保证不成立:返回的 from对于它的每个实例化都是唯一的.GetTypeId<T>

注意:但是应该注意的是,uintptr_t不能保证每个平台都可用。实现该函数的一种完全可移植的方法是返回 a void*,它保证能够保存程序中每个对象的每个地址。


独特的地址保证...

C++中,保证每个对象都必须驻留在唯一的地址,除非我们谈论的对象如果是另一个对象,则它是子对象。在这种情况下,它们可能具有相同的地址(并且在需要共享地址的情况下,如标准布局类及其第一个数据成员)。

1.8p6 C++ 对象模型 [intro.object]

除非对象是位域或大小为零的基类子对象,否则该对象的地址就是它占用的第一个字节的地址。如果一个对象是另一个的子对象,或者如果至少一个是大小为零的基类子对象并且它们属于不同类型,则两个不是位域的对象可能具有相同的地址;否则,它们将具有不同的地址


函数中的静态变量...

我们还有一个明确的子句,表示包含静态变量的函数模板的每个特化都有其自己的所述静态变量的唯一副本:

14.8p2 函数模板特化 [temp.fct.spec]

从模板实例化的每个函数模板特化都有它自己的任何静态变量的副本。

由于声明为static的变量对于 的每个实例都是唯一的GetTypeId<T>,其中T是任意类型,placeHolder因此在此模板特化中命名的每个对象都必须是唯一对象。

它必须是一个独特的对象,并且与之相伴;它必须有一个不同的地址。


注 1)C++11中,我们有std::type_index满足您所追求的保证。
注 2) C++11标准草案n3337已在本文中用作参考。

于 2014-06-16T21:40:29.397 回答