为什么似乎没有必要包含一些STL标头

时间:2015-02-26 14:50:17

标签: c++ stl

我认为需要包含一些标题以使用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>());

也许我误解了包含头文件的机制......任何提示?

2 个答案:

答案 0 :(得分:6)

标头通常包含其他标头。标题x包含的标题将包含在包含x的任何文件中。一旦你用另一种方法掌握包含文件,这应该是微不足道的。在这种情况下,其中一个标准标题恰好包含在另一个标题中。

标头包含的文件可以在不同版本之间更改。如果您没有包含必需的标题,那么您的程序可能会破坏另一个(版本)标准库,即使它似乎在当前实现中有效。当然,这也适用于其他图书馆。

答案 1 :(得分:2)

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

  

C ++标头可能包含其他C ++标头。

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

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

  

在其概要中显示的C ++标头包含其他C ++标头   应提供出现在中的声明和定义   那些其他标题的概要。

  

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

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

<utility>标头是C ++标头的一个示例,保证包含另一个标头。其概要 explitly 包括<initializer_list>。这意味着符合标准的编译器必须接受以下内容:

#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头从不包括   另一个标准标题。

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