使用 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<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 已在本文中用作参考。
【讨论】:
以上是关于使用 c++11 创建唯一类型 ID的主要内容,如果未能解决你的问题,请参考以下文章