使用c ++ 11创建唯一类型ID

时间:2014-06-16 21:24:22

标签: c++ c++11 language-lawyer unique-id

为什么以下代码保证是唯一的typeID?!

using TypeId = uintptr_t; 

template < typename T >
static TypeId GetTypeId()
{
   static uint32_t placeHolder;
   return (reinterpret_cast<TypeId>(&placeHolder));
} 

Source

我不明白为什么这不仅仅是一种随机的记忆位置,而是一种“误用”...感谢您提前回答。

1 个答案:

答案 0 :(得分:7)

简介

你是正确的,实现滥用块范围静态变量的&#34;随机存储器位置&#34; ,但这不是意味着您所谈论的保证并不成立:从GetTypeId<T>返回的内容对于每个实例都是唯一的。

  

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


独特的地址保证......

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

  

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

     
    

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

  

函数中的静态变量......

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

  

14.8p2 功能模板专精 [temp.fct.spec]

     
    

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

  

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

它必须是一个独特的对象,并且随之而来;它必须有一个独特的地址。


  

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