typeid运算符忽略cv限定符的基本原理是什么 < >从C++语言标准,从ISO/IEC 1488~2003中引用5.2.8,引用,
左值表达式的顶级cv限定符或typeid的操作数类型id始终被忽略typeid运算符忽略cv限定符的基本原理是什么 < >从C++语言标准,从ISO/IEC 1488~2003中引用5.2.8,引用,,c++,typeid,typeinfo,C++,Typeid,Typeinfo,左值表达式的顶级cv限定符或typeid的操作数类型id始终被忽略 这一决定的理由是什么。它在打字系统上打了一个洞,这是违反直觉的。常量信息(或易失性部分)在编译时是已知的,因此如果typeid只考虑cv限定符,就不会有开销。尽管可以使用const、volatile和const volatile变量重载非静态成员函数(请参见[class.mfct.nonstatic]),类型D,const D,volatile D,和const volatile D(对于某些非cv限定类型D)并非无关;本标准在
这一决定的理由是什么。它在打字系统上打了一个洞,这是违反直觉的。常量信息(或易失性部分)在编译时是已知的,因此如果typeid只考虑cv限定符,就不会有开销。尽管可以使用
const
、volatile
和const volatile
变量重载非静态成员函数(请参见[class.mfct.nonstatic]),类型D
,const D
,volatile D
,和const volatile D
(对于某些非cv限定类型D
)并非无关;本标准在[basic.type.qualifier]中规定,对于每个cv不合格类型,都有一个具有相同表示和对齐要求的不同类型的const
-qualified、volatile
-qualified和const volatile
-qualified“版本”。如果D
和const D
可能彼此不相关(例如,通过具有不同的表示、存储要求,或者在类的情况下,具有不同的成员),那么许多语言都会崩溃
例如,类型为D&
的对象可以隐式转换为const D&
、volatile D&
和const volatile D&
(请参见[conv.qual])。但是,如果允许D
与const D
无关,则此转换没有意义
还要考虑标准中的许多地方指定忽略顶级cv限定符:
- [过载]指定:
仅在存在或不存在
和/或const
时不同的参数声明是等效的。也就是说,在确定要声明、定义或调用哪个函数时,忽略每个参数类型的volatile
和const
类型说明符volatile
- [温度参数]指定: 在确定模板参数的类型时,将忽略模板参数上的顶级cv限定符
- [basic.life]在指定如何重用生命周期结束的对象的存储时提到: 新对象与原始对象的类型相同(忽略顶级cv限定符)
- [over.best.ics]指定:
顶级cv资格认证中的任何差异均包含在初始化中,不构成转换。[示例:
类型的参数可以从a
类型的参数初始化。这种情况下的隐式转换序列是标识序列;它不包含从const a
到const a
的“转换”]a
- [临时扣减调用]指定:
如果
是cv限定类型,则在类型扣除时忽略A
类型的顶级cv限定符 以及: 如果A
是cv限定类型,则在类型扣除时忽略p
类型的顶级cv限定符 ([temp.Decrete.conv]具有类似的语言。)p
- [except.throw]指定:
throw表达式初始化临时对象,其类型是通过从
的操作数的静态类型中删除任何顶级cv限定符,并将类型从“T数组”或“返回throw
的函数”调整为“指向T
的指针”来确定的;或分别指向返回T
的函数的指针T
- [except.handle]指定:
处理程序与类型为
if的对象的抛出表达式匹配 -处理程序的类型为cvE
或cvT
和T&
和E
是同一类型(忽略顶级cv限定符),或T
如果允许
D
、const D
、volatile D
和const volatile D
为不相关类型,则所有这些都必须更改。因为typeid
在操作数为a时返回动态类型。Cv限定符被设计为编译时间限制,必须记录附加信息rded在运行时检索动态类型的cv限定符,因此忽略顶级cv限定符是合理的
对于类型或非多态对象的操作数,typeid
忽略一致性的顶级cv限定符。否则,例如,以下assert
将意外触发:
struct Base {
virtual ~Base() {}
};
struct Derived : public Base {};
const Derived *d = new Derived;
const Base *b = d;
assert(typeid(*b) == typeid(decltype(*d))); // should not fire
因此,对于那些抱怨RTTI膨胀的人,您的反应是生成四倍的数据?您可以使用
decltype
进行编译时分析;RTTI的要点是进行无法在编译时确定的运行时分析-time@M.M引用“注意,这是N1607中提出的规则的改变,其中CV限定符,或者L或Rouple对DeCype结果没有贡献。”(来自N1705)。CV限定符与C++的其他部分很好地匹配是不容易的。然而,F(t&)和f(const t&)是不同的函数。为了保持一致,这两个应该被认为是相同的。然后我们可以一致地说cv限定符不引入子类型,它们只引入和属性到该类型的特定对象。它们当然是不同的类型。您第2段中的逻辑也不好;派生的&
可以隐式转换但我怀疑是否有人会认为这没有意义,或者它们是同一类型。派生表示基的一个子类型,使派生和隐式转换为基&正如预期的那样。考虑函数f(int)、f(const int)、f(int&)a