今天看到一篇文章,讲的是 C++ 的 bits/stdc++.h 库(链接在这里

内容写的很好,我在这篇文章的基础上总结一下,并且延伸一点。

观察

任何一个技术或写法都具有两面性,在减轻显性复杂度的过程中,一定会带来隐性的成本。(废话)

优势

这里列举几点:

  • 一个库搞定所有 STL 函数的库引入

  • 写起来快,省时间

  • 减轻记忆负担

  • 便于快速形成程序原型

  • 方便测试新的 STL 函数

而这些,几乎就是这个库所有的优点了。

这决定了这个库只有在完全依赖 STL 的程序中才可以大放异彩,而工程中,这个要求就显得很不近人情——几乎没有一个工程项目不使用非 STL 提供的库。这样的现状,决定了只有尝试新特性或在编程比赛中,该库才有用武之地。

劣势

而劣势就相当明显了,这里也可以列举一二。

  • 拖慢编译速度

  • 可移植性差

  • 是 GNU C++ 库的非标准头文件,在部分版本编译器中甚至不支持

  • 引入过多的库,在使用过程中容易误将库函数或对象的名称误做为变量名,造成编译错误。

分析

C/C++ 的库并不是跨平台一致的,使用一个库之前,要先搞清楚在什么平台上可以用。

对于 bits/stdc++.h 而言,它是 GNU C++ 库的非标准头文件,所以在使用时要注意编译器能不能支持。

为什么编译慢?

实践研究

使用:<bits/stdc++.h>

#include <bits/stdc++.h>

int main(){
	printf("Well!");
	return 0;
}
编译结果...
--------
- 错误: 0
- 警告: 0
- 输出文件名: C:\Users\devel\AppData\Local\Temp\out.exe
- 输出大小: 1.91989707946777 MiB
- 编译时间: 0.55s

使用:<iostream>

#include <iostream>

int main(){
	printf("Well!");
	return 0;
}
编译结果...
--------
- 错误: 0
- 警告: 0
- 输出文件名: C:\Users\devel\AppData\Local\Temp\out.exe
- 输出大小: 1.88790321350098 MiB
- 编译时间: 0.39s

上面的两个结果是在完全遵守控制变量法的状态下进行的测试

源码分析

在 gcc-11.2.0 官方文档发布的 stdc++.h 中是这样的:

不难看出,他实现引入全部 STL 库的方法就是单纯的引入 + 对一些情况做特判。

对于 #include ,引入的库内容是被直接复制到该预处理器指令的所在之处的,这样操作,势必会造成代码在编译时的膨胀,造成不必要的编译处理。

解决(其实没有)

很有趣,很多文章从来没有提到怎么缓解 bits/stdc++.h 编译慢的问题,而是单纯的列举优缺点,这样的文章无疑是没有任何营养的。

我在 codeforces 的一篇博文上(原文链接)看到了一种解决方法:通过预编译来缓解编译时的时间花销。

我感觉很有意思,就小小的研究了一下:

然后就没有然后了...... qwq

我真的不会一点,搞不起来(Windows上无论如何都没办法达到文章里面的6倍加速)

不能理解.gif

结语

关于该不该用,其实上面已经回答了,只有尝试新特性或在编程比赛中,该库才有用武之地。