C++ #include - 只有部分#include

6
有时我会遇到这样的情况,我需要引入一个庞大的第三方文件,只是为了使用其中的一个函数或一个小类,这让我感到内疚,因为我知道这会增加编译时间,因为编译器会编译整个文件,而我只想要一个函数。有没有办法绕过这个问题,只包含我想要的那一个函数,而不必重写整个文件?

1
你真的确定你会大幅增加编译时间吗?一个单独的头文件通常不会有太大的影响。 - templatetypedef
4个回答

12

你有几个选项:

  • 只包含头文件。实际上,这不会显著增加您的编译时间。
  • 向第三方头文件提供商投诉。告诉他们要提供更小、更模块化的头文件。
  • 不包含头文件,但声明单个函数为 extern,像这样:extern int GetMeaningOfLife(int mice);

5
函数声明默认就是外部的,因此你不需要使用关键字 extern。请注意保持内容原义和简明扼要,不提供解释或其他信息。 - bames53
@bames53 这只是语义上的区别,在我看来,这在特定情况下增加了可读性,也就是说,你可以区分导入的函数(extern)和未指定的导出函数。 - Kotauskas

4
您不能只编译头文件的一部分。如果第三方头文件包含大量代码,则您无能为力。我能想到的最好的解决方案是使用预编译头文件,这可以消除一些编译开销,因为这些头文件只会完全编译一次。另一个选择是使用类的前向声明而不是包含其声明,如果其他翻译单位包含头文件,则只能将这些类用作指针。

2
有时简单编写自己的前向声明而不是包含头文件可能是合理的。但是,如果您没有定义该内容的权限,则可能遇到问题,因为定义更改后,您必须更新前向声明。
例如,一些 Boost 库尝试了在标准库中前向声明一些内容,以避免 #includes。最近,它们与 libc++ 实现的标准库遇到了问题,因为 libc++ 使用内联命名空间,所以幼稚的前向声明无法与 libc++ 一起使用。实际上,标准库实现可以执行符合标准但会破坏其他实现的前向声明的许多不同操作。
因此,手动前向声明具有脆弱性,而且可能不可移植,但对您可能有效。
另一个选择是使用预编译头文件。这可以减少包含头文件所需的处理。例如,我保留了一个简单项目,在其中包括标准库的每个头文件。如果不使用预编译头文件,编译空程序需要几秒钟。使用预编译头文件,编译空程序只需要一小部分秒钟。
您将不得不查看编译器如何处理预编译头文件。例如,gcc 和 clang 在使用 -x c++-header 或 -x c-header 处理头文件时会生成预编译头文件。然后,当您使用 -include 标志包含文件时,编译器将搜索该头文件的预编译版本(使用特定于编译器的命名约定),并可能包含该版本。

$ cat everything.h

#include <iostream>

$ cat main.cpp

int main() {
    std::cout << "Hello, World!\n";
}

$ clang++ -x c++-header everything.h -o everything.h.pch

$ clang++ main.cpp -include everything.h

$ ./a.out

Hello, World

Clang查找.pch文件,而gcc查找.gch文件。


1
当然不是。那太荒谬了。我使用 ed ;) - bames53
我理解了,只是想确认一下。如果你真的那样做了,我不认为我会听从你的建议 =P - Michael Dorst

1

头文件可能不会显著增加编译时间。这取决于其中的内容。当然,您可以编辑掉不需要的内容,但我不建议这样做。这很容易出错,而且通常需要付出很大的努力,回报却很少。头文件是否有包含保护?如果没有,如果您的编译速度较慢,可以考虑添加它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接