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

Posted

技术标签:

【中文标题】使用 c++11 创建唯一类型 ID【英文标题】:Creation of unique type ID with c++11 【发布时间】:2014-08-06 19:06:14 【问题描述】:

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

using TypeId = uintptr_t; 

template < typename T >
static TypeId GetTypeId()

   static uint32_t placeHolder;
   return (reinterpret_cast<TypeId>(&placeHolder));
 

Source

我不明白为什么这不仅仅是一种随机内存位置作为一种“滥用”......提前感谢您的回答。

【问题讨论】:

编译器将为您调用它的每种类型实例化模板函数的副本,并且这些实例中的每一个都有自己唯一的placeHolder,因此您会为每种类型获得不同的地址。 “我不明白为什么这不仅仅是一种随机内存位置” 可以这么说。但这没关系。它对每种类型都是独一无二且一致的。 所以我确实理解正确,它只是一个保证唯一的随机数......这样做有什么好处吗?不使用 RTTI 有什么好处吗? I used this technique 早在那篇 CodeProject 文章之前,我不是第一个。 【参考方案1】:

简介

您是正确的,该实现滥用了块范围 static 变量的 “随机内存位置”,但这并不意味着您所说的保证about 不成立:从 GetTypeId&lt;T&gt; 返回的值对于它的每个实例都是唯一的。

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


不同的地址保证...

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

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

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


函数中的静态变量...

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

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

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

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

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


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

【讨论】:

以上是关于使用 c++11 创建唯一类型 ID的主要内容,如果未能解决你的问题,请参考以下文章

使用另一个表中的唯一值创建一个表

为类类型 C++ 创建唯一 ID

C生成唯一ID

使用 jquery 创建唯一 id 以在 bxslider 中使用

创建一个具有唯一 ID 1 小时的会话 - PHP

mysql删除表中重复数据创建唯一索引。