我从一篇Codeforces博客中了解到,如果在一个C++
程序中添加#include <bits/stdc++.h>
,那么就不需要再包含其他任何头文件。 #include <bits/stdc++.h>
如何工作,并且使用它代替单独包含头文件是否可行?
我从一篇Codeforces博客中了解到,如果在一个C++
程序中添加#include <bits/stdc++.h>
,那么就不需要再包含其他任何头文件。 #include <bits/stdc++.h>
如何工作,并且使用它代替单独包含头文件是否可行?
这基本上是一个头文件,也包括了所有标准库和STL包含文件。我能看到的唯一目的就是用于测试和教育。
例如,参见 GCC 4.8.0 /bits/stdc++.h source。
使用它会包括很多不必要的内容,并增加编译时间。
编辑:正如Neil所说,这是预编译头文件的实现。如果您正确地设置了预编译,它实际上可以加快编译时间,具体取决于您的项目。(https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html)
然而,我建议您花时间学习每个sl/stl头文件并单独包含它们,不要使用“超级头文件”,除非是为了预编译。
#include <bits/stdc++.h>
是一个预编译头文件的实现文件。
从软件工程的角度来看,最好尽量减少包含文件。如果你使用 <bits/stdc++.h>,它实际上会包含很多你的程序可能不需要的文件,从而不必要地增加编译时间和程序大小。[编辑:正如@Swordfish在评论中指出,输出程序大小并不受影响。但是,最好只包括你实际需要的库,除非它是一些竞争性比赛]
但在比赛中,使用这个文件是一个好主意,当你想要减少做琐事的时间时;特别是当你的排名与时间紧密相关时。
它适用于大多数在线评测系统、编程竞赛环境,包括ACM-ICPC(分区赛、区域赛和世界总决赛)和许多在线评测系统。
它的缺点是:
那个头文件不是C++标准的一部分,因此不具备可移植性,应该避免使用。
此外,即使标准中有某个通用头文件,您也应该选择特定的头文件来代替,因为编译器必须每次编译翻译单元时都读取和解析每个包含的头文件(包括递归包含的头文件)。
遗憾的是,这种方法在现阶段还不是可移植的C++。
所有标准名称都在命名空间std
中,并且您无法知道哪些名称没有通过包括头文件而定义(换句话说,当使用#include <vector>
时,实现可以直接或间接地声明名称std::string
)。
尽管如此,根据语言要求,您需要告诉编译器每个标准头文件包含标准库的哪个部分。这是可移植性bug的来源,因为如果您忘记了#include <map>
,但仍然使用std::map
,程序可能会在特定版本的特定编译器上默默地编译而没有警告,而您只有在将其迁移到另一个编译器或版本后才可能出现错误。
在我看来,没有有效的技术借口可以解释为什么对于一般用户而言这是必需的:编译器二进制文件可以内置所有标准命名空间,这实际上甚至比使用预编译头更可以提高性能(例如使用完美哈希进行查找、删除标准头文件解析或加载/反序列化等)。
使用标准头文件可简化编译器或标准库构建者的工作,仅此而已。这并不是为了帮助用户。
然而,这就是语言的定义方式,您需要知道哪个头文件定义了哪些名称,因此要计划额外的神经元来记住这一点(或尝试找到一个自动添加您使用的标准头文件并删除不需要的头文件的IDE...这是一个合理的替代方案)。
bits/stdc++.h
包含了所有的 C++ 头文件。 - 101010/agree
- Marco A.