确定#include的标准头文件

ana*_*lyg 2 c++ portability header-files

假设我正在编辑一些大型C++源文件,并添加了几行恰好使用的代码,auto_ptr如下例所示.

#include <string>

// ... (much code here)

void do_stuff()
{
    std::string str("hello world");
    // ... (much code here too)
    std::auto_ptr<int> dummy; // MY NEW CODE
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这个例子在gcc 3.4.4(cygwin)上编译,因为标准头部<string>恰好包括<memory>编译所需的头部auto_ptr.但是,这不适用于gcc 4.5.0(mingw); 他们似乎已经清理了他们的头文件或其他东西.

所以,当我添加使用的代码时,我auto_ptr应该立即查看该文件是否包含#include <memory>在开头,这个答案意味着什么?我从来没有这样做(我觉得太烦人了); 我总是依赖编译器来检查是否有任何#include缺失.

是否有任何选项不会破坏编码,并确保我的代码的可移植性?

是否有一个C++标准库实现,其标题不是必需的彼此包含?

dap*_*wit 10

如果在标准库中使用某些内容,则应包括定义它的标头.这是唯一的便携式选择.这样你就可以避免你引用的实例,其中一个标题恰好包含在一个版本或编译器中,而不是另一个. auto_ptr是在中定义的<memory>,因此如果您使用它,请包含该标头.

[编辑...]

回答你的评论......你是否在询问编译器是否可以帮助检测何时使用标准头文件中没有直接包含的内容?这会有所帮助,但我认为这有点太多了.这将要求编译器知道哪些标准库头包含哪些标准库定义,然后检查是否包含了所使用定义的正确库头.

确切地确定如何包含标题也是一项艰巨的任务.如果您使用的是标准库定义,则必须以某种方式包含标题.编译器必须告诉您是否自己包含标头(可能通过您自己的标头或第三方库)或者是否通过另一个标准库标头.(例如,在你的榜样,它必须能够告诉之间的差异<memory>被列入通过<string>或者被列入你的代码中).

它必须处理标准库的不同版本(例如C++ 03 vs C++ 0x)和不同的供应商.如果那些第三方stdlib的供应商不完全遵循标准,那么你可能会收到关于要包含哪些标头的错误警告.

我只是这样说试图解释(用我有限的编译器/ stdlib知识)为什么我不认为编译器有这个功能.我同意,这会有所帮助,但我认为成本超过了收益.