问题 使用typeid运算符时,为什么需要#include ?


typeid 表示C ++ RTTI运算符也是C ++关键字。它返回一个 std::type_info 保存(动态)类型特定信息的对象。

根据我从各种来源的理解,必须包括 <typeinfo> 使用时 typeid,否则该计划是不正确的。事实上,如果我不包含前面提到的标题,我的gcc5.2编译器甚至不编译程序。我不明白为什么要使用C ++的头部包含 关键词。我理解每当我们使用在该头中声明/定义的对象时强制标题,但是 typeid 不属于班级类型。那么包含标题的执行背后的原因是什么呢? <typeinfo>


12936
2017-11-14 04:02


起源

对于类似的东西, <initializer_list> 也可能需要包含在您可能或可能不期望的案例中。 - chris
@chris我想只有当你明确使用时 std::initializer_list,从而更有意义 std::initializer_list 虽然核心语言隐式使用,但它是一个自己的类,而不是关键字。 - vsoftco
是的,虽然有一些棘手的案例,如 auto list = {1, 2, 3}; 和 for (auto x : {1, 2, 3}) {}。 - chris
@chris是的,但您是否必须在刚才提到的案例中加入标题?据我所知,该类型被推断为 initializer_list 无需包含标题。从某种意义上讲,这更奇怪 list现在是一个对象类型 std::initializer_list。哦,是的,你需要包括它...奇怪和丑陋的设计imo。 - vsoftco
是的, 如果在使用std :: initializer_list之前未包含头<initializer_list> - 即使是未命名类型的隐式用法(7.1.6.4) - 程序也是格式错误的。 ([dcl.init.list] / 2)该链接指向 auto。至于第二个,有 这个问题。 - chris


答案:


下一段:

typeid表达式是lvalue表达式,它引用一个对象   具有静态存储持续时间的多态类型const   std :: type_info或从中派生的某种类型。

因为它是一个左值表达式,它使用 参考初始化 声明一个初始化器 std::type_info<typeinfo> 包含的定义 那个对象


7
2017-11-14 04:22



可能这就是原因,虽然我找到了语言的设计......让我们说奇怪,因为它允许关键字依赖于标题...... - vsoftco


typeid 并不是唯一需要标题的人

new 还需要标题 <new> 在某些情况下

注意:隐式声明不会引入名称std,std :: bad_alloc和std :: size_t,或者库用于声明这些名称的任何其他名称。因此,在不包括头部的情况下引用这些函数之一的新表达式,删除表达式或函数调用是格式良好的。但是,引用std,std :: bad_alloc和std :: size_t是不正确的,除非通过包含适当的头声明了名称。 - 注意

请参阅abhay关于新关键字的答案

另一个运营商 sizeof 返回std :: size_t(它实际上不需要包含头,但我的观点是它使用了一个别名,它也在头文件中定义)

C ++§5.3.3

sizeof和sizeof ...的结果是std :: size_t类型的常量。 [注意:std :: size_t在标准头中定义 <cstddef>(18.2).-结束说明]

typeid 使用在中声明的类 <typeinfo> 头

<typeinfo> 概要

namespace std {
class type_info;
class bad_cast;
class bad_typeid;
}

有关iso cpp纸的信息,请参见第18.7节

IMO,它的C ++标准设计技术,保持编译器整洁,干净和轻量级


5
2017-11-14 06:09



size_t是一个类型别名,因此您不需要包含标头来使用sizeof的结果 - vsoftco
是的我没有说它需要包含标题。 - Abdul Rehman
@AbdulRehman说“typeid不是唯一需要标题的人”,然后引入“sizeof”似乎就像你说sizeof也需要标题。 - M.M
new T 不需要 <new>,只有某些用途 new 做。正如你的报价所解释的那样 - M.M