是否未指定标准库标头是否包含任意标头

Is it unspecified whether a standard library header includes arbitrary headers?

本文关键字:是否 包含任 未指定 标准      更新时间:2023-10-16

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

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

在实践中,情况往往是这样的。例如,<iostream>可能包含<string>,在其他情况下,您需要显式包含<string>。然而,我似乎找不到N4140中的情况。我看过:

  • §2.9[法律标题]
  • §17.6.1.2【标题】
  • §17.6.2.2[使用页眉]
  • §17.6.4.4[替代标题]
  • §17.6.5.2[关于标题]

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

2翻译单元可以按任何顺序包含库头(第条2) 。每个可以包含一次以上,与只包含一次,但包含的效果除外<cassert><assert.h>每次都依赖于词汇NDEBUG的当前定义178

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

[using.overview]/1本节介绍C++程序如何获得访问权限到C++标准库的设施。[…]

以及[res.on.headers]:

1一个C++标头可以包括其他C++标头。C++标头应提供其概要中出现的声明和定义。一个C++标头,在其概要中显示为包括其他C++标头应提供其他标题的概要。

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

假设在下的C++14标准中可以找到[res.on.headers]

17图书馆简介

17.6图书馆范围内的要求

17.6.5符合要求的实施

17.6.5.2标题

似乎可以肯定地说;C++标题";本段中的意思是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
(...)