有时我遇到这样的情况,我发现我需要为大型第三方文件创建一个#include,以便我可以使用一个函数或一个小类,这让我感到内疚,因为我知道这已经消失了,增加了我的编译时间当我只想要一个功能时,它会编译整个文件。有没有办法解决这个问题,只包含我想要的一个函数而不重写整个事情?
4 回答
你有一些选择:
- 只需包括标题。真的,它不会增加你那么多的编译时间。
- 向您的第 3 方标头提供商投诉。告诉他们运送更小、更模块化的接头。
- 不要包含标题,而是声明为
extern
您关心的单个函数,就像这样extern int GetMeaningOfLife(int mice);
您不能只编译部分标头。如果该第 3 方的标头提取了大量代码,那么您将无能为力。我能想到的最好的解决方案是使用预编译的头文件,这应该可以消除一些编译开销,因为这些头文件只会被完全编译一次。如果其他一些翻译单元确实包含标题,另一种选择是使用类的前向声明而不是包含它们的声明。不过,这只会让您将这些类用作指针。
有时,简单地编写自己的前向声明而不是包含标题可能是合理的。尽管如果您不负责定义事物,那么您可能会遇到定义更改的问题并且您必须更新您的前向声明。
例如,一些 Boost 库试图在标准库中转发声明一些东西以避免#includes。最近他们遇到了标准库的 libc++ 实现的问题,因为 libc++ 使用内联命名空间,所以天真的前向声明不适用于 libc++。事实上,标准库实现可以做很多符合标准的不同事情,但可以打破适用于不同实现的前向声明。
因此,手动前向声明很脆弱,并且可能不可移植,但可能对您有用。
另一种选择是使用预编译的头文件。这可以减少包含标题所需的处理。例如,我有一个临时项目,我在其中包含标准库中的每个标头。如果没有预编译的头文件,编译一个空程序需要几秒钟的时间。使用预编译的头文件,一个空程序只需要几分之一秒。
你必须看看你的编译器如何处理预编译的头文件。例如,当您使用 -x c++-header 或 -x c-header 处理头文件时,gcc 和 clang 会生成预编译的头文件。然后,当您使用 -include 标志包含文件时,编译器将搜索该头文件的预编译版本(使用编译器特定的命名约定)并可能包含该文件。
$猫一切.h
#include <iostream>
$猫 main.cpp
int main() { std::cout << "Hello, World!\n"; }
$ clang++ -x c++-header Everything.h -o Everything.h.pch
$ clang++ main.cpp -包括一切.h
$ ./a.out
你好世界
Clang 查找 .pch 而 gcc 查找 .gch
标头可能不会大大增加您的编译时间。这取决于里面有什么。当然可以编辑掉你不需要的东西,但我不推荐它。它很容易出错,通常需要付出很多努力才能获得很少的回报。标题是否包含警卫?如果没有,如果你的编译速度很慢,你可以考虑添加它们。