我什么时候应该`#include <ios>`、`#include <iomanip>` 等等?

When should I `#include <ios>`, `#include <iomanip>`, etc.?

C++ 标准库提供以下与 iostream 相关的 headers:

<ios>
<iosfwd>
<istream>
<ostream>
<streambuf>
<iostream>
<fstream>
<sstream>
<strstream> [deprecated]
<iomanip>

什么时候最简单、最明智的规则是 #include 这些 headers 中的哪一个? (如果不同版本的 C++ 的答案不同,我对 C++17 最感兴趣。而且我最感兴趣的是什么 保证 可以工作,而不是 headers 碰巧在 libstdc++ 或其他任何东西中包含其他 headers。)

我愿意相信我总能通过 <iostream><fstream>(仅当我使用 fstreams)、and/or <sstream>(仅当我使用使用字符串流)。 似乎对 这样的简单程序有效

#include <iostream>

int main() {
    std::cout << std::hex << 42 << std::endl << std::flush;
}

但是如果我向该程序添加 std::setw(42),它就会停止编译;在这种情况下,我还需要包括 <iomanip>

所以规则似乎是"include <iostream>, <fstream>, and/or <sstream>; and additionally include <iomanip> if you're using any of these manipulators."

如果我虔诚地遵守这条规则,我会 运行 遇到我 需要 包括 <ios><iosfwd> 的情况吗? <istream><ostream>、and/or <streambuf> 在我的应用程序代码中?

If I follow this rule religiously, will I ever run into a case where I need to include <ios>, <iosfwd>, <istream>, <ostream>, and/or <streambuf> in my application code?

嗯,<iostream> 包括 <ios><streambuf><istream><ostream><iosfwd> 只是前向声明,所以你也不需要那个。所以……我想,是的。

<fstream> 为您提供所有与文件相关的内容:filebufifstreamofstreamfstream(以及它们的宽对应物)。

<sstream> 同样为您提供所有 stringstream 类型和 stringbuf.

您所要做的就是记住 <iomanip> 中的内容,这并不多,但您可以随时查找它。

Will I ever run into a case where I need to include <ios>, <iosfwd>, <istream>, <ostream>, and/or <streambuf> in my application code?

是的,你可能会:

<iosfwd> 当你有一个 header 声明但不定义你的类型的流输出运算符时节省编译时间:

#include <iosfwd>
std::ostream& operator<<(std::ostream& os, const MyType& my);

<istream><ostream> 在 cpp 文件中,然后定义此类运算符,再次节省编译时间并保持范围干净,包括 <iostream>.

<ios><streambuf> 可能仅当您编写定义自定义流 classes 的库时。或者,如果您想从某些实际上不执行 IO 的中央设置 class 调用 sync_with_stdio()