为什么隐式声明不引入名称?

Why does the implicit declaration does not introduce the name?

本文关键字:声明 为什么      更新时间:2023-10-16

我已经阅读了以下两个前面的问题,但仍然无法很好地理解。
1. 为什么使用typeid运算符时需要 #include?
2. C++什么时候需要 #include 图书馆?

由于typeid使用type_info类,因此要求我们#include<typeinfo>是合理的。 但是,new operators也使用std::bad_alloc,为什么不需要我们#include <new>(我知道sizeof()不需要<cstddef>因为size_t可以在编译时替换为内置类型,只要编译器知道size_t实际上是什么。

根据第二个问题中得票最多的答案,他说:

注意:隐式声明不会引入名称 std、std::bad_alloc 和 std::size_t,或者库用于声明这些名称的任何其他名称。因此,引用这些函数之一但不包含标头的 newexpression、delete-expression 或函数调用的格式正确。但是,引用 std、std::bad_alloc 和 std::size_t 的格式不正确,除非已通过包含适当的标头来声明名称。

上面的段落令人困惑,因为每次我们使用类型时,我们都需要在使用之前声明一个类型,例如class A;void foo(A*);并且void* operator new(std::size_t) throw(std::bad_alloc);隐式声明也有一个类型std::bad_alloc隐式声明不声明它使用的类型是一种特权吗?

前向声明用于名称查找。对于隐式声明,编译器已经知道这些名称的语义,因此它不需要执行名称查找,因此不需要前向声明(即标头)。

关键是void foo(A*);是由编写的,所以你必须通过前向声明告诉编译器A是什么,而隐式声明是由编译器编写的,所以你不需要告诉编译器声明中使用的名称是什么。

请注意,上述原因不足以解释为什么在使用typeid之前需要<typeinfo>。事实上,这一规则在标准[expr.typeid]第6段中明确规定:

如果在使用typeid之前未包含标头<typeinfo>,则程序格式不正确。