lif*_*fPI 5 c++ language-lawyer unique-id c++11
为什么以下代码保证是唯一的typeID?
using TypeId = uintptr_t;
template < typename T >
static TypeId GetTypeId()
{
static uint32_t placeHolder;
return (reinterpret_cast<TypeId>(&placeHolder));
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这不仅仅是一种随机的记忆位置作为一种"误用"...提前感谢您的答案.
你是正确的,实现滥用块范围静态变量的"随机内存位置",但这并不意味着你所讨论的保证不成立:返回的每个实例都是唯一的.GetTypeId<T>
注:然而,人们应该知道的是,其实
uintptr_t是不保证是适用于所有平台.实现该功能的一种完全可移植的方式是返回avoid*,保证能够保存程序中每个对象的每个地址.
在C++中,保证每个对象必须驻留在一个唯一的地址,除非我们讨论的是一个对象,如果是另一个对象则是一个子对象.在这种情况下,它们可能具有相同的地址(并且在需要共享地址的情况下,与标准布局类及其第一个数据成员一样).
1.8p6C++对象模型[intro.object]除非对象是零字段或零大小的基类子对象,否则该对象的地址是它占用的第一个字节的地址.如果一个是另一个的子对象,或者如果至少一个是零大小的基类子对象并且它们是不同类型的,则不是位字段的两个对象可以具有相同的地址; 否则,他们应有不同的地址.
我们还有一个显式子句,说包含静态变量的函数模板的每个特化都有自己的静态变量的唯一副本:
14.8p2功能模板专业化[temp.fct.spec]从模板实例化的每个函数模板特化都有自己的任何静态变量的副本.
由于声明为static的变量对于每个实例化都是唯一的GetTypeId<T>,其中T是任意类型,因此placeHolder在此模板特化中命名的每个对象都必须是唯一的对象.
它必须是一个独特的对象,并且随之而来; 它必须有一个独特的地址.
注1)在C++ 11中,我们
std::type_index可以满足您的要求.
注2)本文中使用了C++ 11标准草案n3337作为参考.
| 归档时间: |
|
| 查看次数: |
1088 次 |
| 最近记录: |