8

在 C++ 标准库中的哪些标头保证包含另一个标头中有一个声明?:

C++ 标准库头文件可能以未指定的方式相互包含,因此程序员通常不应该依赖一个头文件包括另一个头文件。[...]

在实践中,情况往往如此。例如,<iostream>可能包含<string>,在其他情况下您需要<string>显式包含。但是,我似乎无法在 N4140 中找到这种情况。我看过:

  • §2.9 [lex.header]
  • §17.6.1.2 [标题]
  • §17.6.2.2 [using.headers]
  • §17.6.4.4 [alt.headers]
  • §17.6.5.2 [res.on.headers]

我能找到的最接近的是 [using.headers]:

2 翻译单元可以以任何顺序包含库头(第 2 条)。每个都可以被包含多次,与只包含一次没有任何不同的效果,除了每次包含一个<cassert>或的效果<assert.h>取决于NDEBUG的词汇当前定义。178

但这似乎适用于 C++ 程序,而不是标准库:

[using.overview]/1 本节描述 C++ 程序如何访问 C++ 标准库的功能。[...]

以及 [res.on.headers]:

1 C++ 标头可能包含其他 C++ 标头。C++ 头文件应提供出现在其概要中的声明和定义。在其概要中显示为包括其他 C++ 头的 C++ 头应提供出现在这些其他头的概要中的声明和定义。

我认为关键是第一句话,但它并没有明确说它是未指定的行为。它是否在任何地方说明这是未指定的行为,还是只是暗示?

4

1 回答 1

4

鉴于 [res.on.headers] 位于 C++14 标准中

17 图书馆介绍

17.6 图书馆范围的要求

17.6.5 一致性实现

17.6.5.2 标题

可以肯定地说,本段中的“C++ 头文件”是指 C++ 标准库头文件。该术语应被理解为与 C 标头(即从 C 标准库中提取的货物)相反,后者在这方面的自由度较低。[res.on.headers] 对他们说:

C 标准头文件 (D.5) 应仅包括其对应的 C++ 标准头文件,如 17.6.1.2 中所述。

由于 C++ 标准库头文件可能包含其他 C++ 标准库头文件,因此任何其他标准库头文件的内容在包含另一个头文件后可能会变得已知,但除非声明一个头文件必须包含另一个头文件,否则这是不可靠的。一个标头是否必须包含另一个标头是逐个标头定义的。例如,因为<iostream>它在 [iostream.objects.overview] (27.4.1) 中说:

标题<iostream>概要

#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>

(...)

在 [template.bitset] (20.7)

标题<bitset>概要

#include <string>
#include <iosfwd>        // for istream, ostream

(...)
于 2015-02-26T16:35:30.303 回答