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

Creation of unique type ID with c++11

本文关键字:类型 ID 唯一 创建 c++11 使用      更新时间:2023-10-16

为什么下面的代码保证是唯一的类型id ?

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

来源

我不明白为什么这不仅仅是一种随机的内存位置作为一种"滥用"…

简介

你是正确的,实现滥用"随机内存位置"块作用域静态变量的,但这并不意味着你正在谈论的保证不持有:从GetTypeId<T>返回的将是唯一的每个实例化。

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


不同的地址保证…

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

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

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


函数中的静态变量

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

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

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

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

它必须是唯一对象,并且;它必须有一个不同的地址


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