#include <bits/stdc ++.h>如何在C++中工作?

Jer*_*yal 108 c++ gcc g++ c++11

我从读codeforces博客,如果我们#include <bits/stdc++.h>在一个C++程序那么就没有必要包括任何其他的头文件.如何#include <bits/stdc++.h>工作,是否可以使用它而不是包括单独的头文件?

Zel*_*lix 101

它基本上是一个头文件,它还包括每个标准库和stl包含文件.我能看到的唯一目的是进行测试和教育.

Se例如GCC 4.8.0 /bits/stdc++.h源.

使用它会包含许多不必要的东西并增加编译时间.

编辑:正如Neil所说,它是预编译头文件的实现.如果将其设置为正确预编译,实际上可以根据您的项目加快编译时间.(https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html)

但是,我建议您花些时间来了解每个sl/stl标头并分别包含它们,除了预编译之外不要使用"超级标头".

  • @OllieFord从来没有,理想情况下.这是21世纪.编译器应该弄清楚我需要的标准库的哪些部分,以节省我编写重要内容的时间.但是当然人们应该了解标题,因为它是语言的一部分. (19认同)
  • 它适用于预编译头文件,可减少编译时间!(设置正确时) (10认同)
  • 我认为学习C++完全不知道你所使用的东西是什么定义的,这并不是很好.你在什么时候停下来想出来? (7认同)
  • 包含它的一个小缺点是它会导致命名空间中有许多名称。在极少数情况下,这可能会导致一些难以理解的错误(几秒钟)。例如,如果您的变量之一被命名为 `count`。但我现在想不出一个具体的令人困惑的错误例子...... (2认同)

abe*_*312 33

#include <bits/stdc++.h> 是预编译头的实现文件.

从软件工程的角度来看,最小化包含是个好主意.如果你使用它实际上包含很多文件,你的程序可能不需要,因此不必要地增加编译时间和程序大小.[编辑:@Swordfish在评论中指出输出程序大小不受影响.但是,除非是竞争激烈的竞争,否则最好只包括你真正需要的库.

但是在竞赛中,当你想减少做家务时浪费的时间时,使用这个文件是个好主意; 特别是当您的排名对时间敏感时.

它适用于大多数在线评委,编程竞赛环境,包括ACM-ICPC(次区域,地区和世界总决赛)和许多在线评委.

它的缺点是它

  • 增加编译时间.
  • 使用GNU C++库的内部非标准头文件,因此不会在MSVC,XCode和许多其他编译器中编译

  • @Swordfish 我刚刚用 2 个文件 a.cpp 和 b.cpp // a.cpp #include&lt;bits/stdc++.h&gt; int main(){ return 0; } // b.cpp int main(){ return 1; } // 在 mac 上编译 gcc。.out 大小 =&gt; 4248 字节。现在更新答案。:) (3认同)
  • 对于有clang的mac用户:你不会预先安装stdc ++.h,因为它不是标准的头文件.所以只需将以下要点粘贴到/ usr/local/include/bits中,就可以了.https://gist.github.com/abe312/a078b27b03b6e29f0a19a279ec3265cd (2认同)
  • @ abe312“如果使用它实际上包含很多文件,而您的程序可能不需要这些文件,因此不必要地增加了编译时间和程序大小。” 包括未使用的定义和声明,如果不使用,将不会影响程序的大小。 (2认同)

Rob*_*ahy 24

该头文件不是C++标准的一部分,因此是不可移植的,应该避免使用.

此外,即使标准中有一些catch-all标头,您也希望避免它代替特定标头,因为编译器必须实际读入并解析每个包含的标头(包括递归包含的标头)每次翻译单位编译.

  • 这就是预编译头文件的用途.我有一个几乎整个标准库.那就是滚动. (10认同)
  • 不,这不对.大多数编译器都可以选择加速它. (5认同)
  • 根据定义,"大多数编译器"是非标准的 - 如果它是标准的那么它将是"所有编译器"我在标准中没有看到任何地方它讨论如何预编译头文件...... (4认同)
  • @NeilKirk:对我来说听起来不标准。 (2认同)

650*_*502 6

不幸的是,这种方法还不能移植到 C++(到目前为止)。

所有标准名称都在命名空间中std,而且您无法知道哪些名称不是通过include 和 header 定义的(换句话说,实现std::string在使用时直接或间接声明名称是完全合法的#include <vector>)。

尽管如此,语言仍要求您了解并告诉编译器哪个标准头包含标准库的哪个部分。这是可移植性错误的一个来源,因为如果您忘记了示例#include <map>但使用了std::map程序,则程序可能会以静默方式进行编译,并且不会对特定编译器的特定版本发出警告,并且仅在稍后移植到另一个编译器或版本时才会出现错误。

在我看来,没有有效的技术借口来解释为什么这对于普通用户来说是必要的:编译器二进制文件可以内置所有标准命名空间,这实际上可以比预编译头更高地提高性能(例如,使用完美哈希进行查找,删除标准标头解析或加载/解组等)。

标准头文件的使用简化了构建编译器或标准库的人的工作,仅此而已。这不是帮助用户的东西。

然而,这就是语言的定义方式,您需要知道哪个标头定义了哪些名称,因此计划一些额外的神经元在毫无意义的配置中被烧毁,以记住这一点(或者尝试找到自动添加您使用的标准标头的 IDE删除那些你不知道的......一个合理的选择)。