【问题标题】:Why it seems not necessary to include some STL headers为什么似乎没有必要包含一些 STL 标头
【发布时间】:2015-02-26 14:50:16
【问题描述】:

我认为需要包含一些头文件才能使用 gcc(4.9) 进行编译,

#include <algorithm> // for std::transform
#include <numeric>   // for std::adjacent_difference

但是,我发现根本不需要包含它们,我仍然可以调用 比如下面的函数

std::adjacent_difference (V1.begin(), V1.end(), V2.begin());
std::transform(V2.begin(), V2.end(), V3.begin(), V4.begin(), std::divides<double>());

也许我误解了包含头文件的机制...有什么提示吗?

【问题讨论】:

  • 那么您很幸运,您包含了一些 other 头文件,其中包含所需的头文件。
  • 如果你使用它,包括它。
  • @JoachimPileborg 是正确的。你应该总是包含你需要的头文件。有时您包含的某些标头本身包含其他 STL 标头,这就是您看到此行为的原因。您已经包含的一些文件可能包括&lt;algorithm&gt;&lt;numeric&gt;;但这是一个实现细节。你不应该依赖它:)
  • V1 - V4 实际上是什么?普通数组?

标签: c++ stl


【解决方案1】:

一个标题包含其他标题是很典型的。标题 x 包含的标题将包含在任何包含 x 的文件中。一旦您掌握了 include 文件的其他含义,这应该很容易理解。在这种情况下,其中一个标准头恰好包含在另一个中。

标题包含的文件可以在版本之间更改。如果您不包含必需的标头,则您的程序可能会在另一个(版本)标准库下中断,即使它可能在当前实现中似乎可以工作。当然,这也适用于其他库。

【讨论】:

  • 作为一个具体的例子,最近几个版本的 g++ 一直在尝试从标准库中删除不必要的头文件,以加快编译用户代码(因为所有这些头文件都必须被解析),我看到了这个没有包含足够标题的破坏代码。
  • 如果一个标题(A.h)包含其他标题(B.h,C.h),那么所有内容都将在包含 A.h 的 .cpp 文件中可见,对吗?真的很奇怪,我可以使用 std::vector 而不指定 include...
  • @lorniper 是的,你是对的。这并不奇怪,它只是意味着当前包含的标题之一确实包含&lt;vector&gt;
【解决方案2】:

C++ 标准在第 17.6.5.2 [res.on.headers] 节中说明了以下内容:

一个 C++ 头文件可能包含其他 C++ 头文件。

对于您的问题,这意味着编译器可以像您包含其他 C++ 头文件一样工作。在您的示例中,如果您包含 &lt;algorithm&gt;,则允许编译器包含 &lt;numeric&gt; 标头,反之亦然。

但这还不是全部。该标准还说:

概要中显示的 C++ 标头包括其他 C++ 标头 应提供出现在 其他标题的概要。

还有:

C 标准头文件 [...] 应仅包括其对应的 C++ 标准头文件 [...]

(请注意,我引用了上一个免费的 C++11 草案。ISO 标准的最终版本不是免费的。请参阅 https://isocpp.org/std/the-standard。)

&lt;utility&gt; 标头是 C++ 标头的示例,它保证包含另一个标头。它的概要明确地包括&lt;initializer_list&gt;。这意味着符合标准的编译器必须接受以下内容:

#include <utility>
// #include <initializer_list> // not needed

int main()
{
    std::initializer_list<int> x = {};
}

相比之下,对于 C 头文件,这意味着以下不得编译:

#include <stdio.h>

int main()
{
    std::cout << "\n"; // must not compile
}

您的实施文档肯定会确认该标准所说的内容。例如,documentation for Visual C++ 2013 表示:

C++ 库头文件包括它需要的任何其他 C++ 库头文件 定义所需的类型。 (始终明确包含任何 C++ 库 但是,翻译单元中需要标题,以免您猜错 关于它的实际依赖关系。)标准 C 标头从不包含 另一个标准标题。

这里给出的建议很好;不依赖于自动包含。明确包含您需要的所有内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-02
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-25
    • 2016-02-06
    • 2012-11-07
    相关资源
    最近更新 更多