在没有 <iomanip> header 的情况下使用 std::setw()

Using std::setw() without <iomanip> header

即使我没有包含 <iomanip>,这段代码怎么可能编译?

#include <iostream>
#include <fstream>

int main()
{
    std::cout << std::setw(5) << "test" << std::endl;
    return 0;
}

编译为:

clang++ test.cpp

但是如果没有 <fstream> 它会抛出错误:

test.cpp:5:20: error: no member named 'setw' in namespace 'std'
        std::cout << std::setw(5) << "test" << std::endl;
                     ~~~~~^
1 error generated.

我的朋友 Mac 在这两种情况下都会抛出错误。

标准 C++ headers 可能包含其他标准 headers,如果这样便于实现。您的 <fstream> 作为实施细节包含 <iomanip>,但在 Mac 中显然没有包含。

规则:包含您需要的内容,不要依赖意外包含。这不会增加开销;标准 headers 都可以安全地包含多次。

header 内部包含它们自己,具体取决于标准库实现。

除非您包含某个文件,否则该标准不保证符号未定义 - 相反,它保证如果您包含某个符号,该符号将被定义。

在这种情况下,fstream header 包含恰好也具有 std::setw 定义的内部代码。

在你的编译器上编译的代码是你的标准库实现的特殊性。

在我们当前的项目中,缺少 header 是构建失败的常见原因之一(构建在 Windows 上有效,但在 Mac 上无效,反之亦然) .

通常,在代码中为您需要的所有内容包含指定的 header,即使代码在没有包含的情况下编译正常。