Arm*_*yan 9 c++ coding-style include
考虑这个翻译单位:
#include <map>
#include <string>
int main()
{
std::map<std::string, std::size_t> mp;
mp.insert(std::make_pair("hello", 42));
}
Run Code Online (Sandbox Code Playgroud)
这个翻译单元有两件事困扰着我,他们是
我刚才假设<cstddef>和<utility>必须已#include被D <string>和<map>.
这个假设有多合适?至少make_pair我认为有一个非常强大的保证,因为地图成员接口使用std::pair.因为std::size_t没有正式的保证,但是一旦你包括map或者,它很可能是可用的string.第一个风格问题是,您是否明确包含<cstddef>并<utility>在此翻译单元中?
这部分部分处理了已经包含的一些标题的不确定性.但是,问题的第二部分.假设我们有这个
//f.h
#ifndef BIG_F_GUARD
#define BIG_F_GUARD
#include <string>
std::string f();
#endif
//f.cpp
#include "f.h"
std::string f()
{
std::string s;
return s;
}
Run Code Online (Sandbox Code Playgroud)
第二个问题是:你明确#include <string>到f.cpp吗?
我想我的问题很明确.顺便说一句.这两个问题后面都是一个很大的WHY:)谢谢.
在第一种情况下,我可能不会,但如果我希望我的代码能够正确移植,我应该这么做。没有要求map::size_type,size_t因此没有必要<map>包含 的定义size_t。就此而言,size_t可以是类型别名而不是不同的类型,因此即使size_type is size_t,也不需要在<map>使用该名称时进行定义。正如您所说,很可能但不能保证<map>包括<cstddef>.
对于第二种情况,我绝对不会,因为我知道我不需要。IMO .cpp 文件有权依赖其相应 .h 文件包含的标头,因为您希望如果修改 .h 文件,您也可能需要修改 .cpp 文件 - 更改接口意味着更改大多数时候它的实施。即使您觉得我没有资格,我也可以随时记录fh include <string>,在这种情况下我可以信赖它。
关于<utility>,我不知道是否<map>允许std::pair在不定义的情况下定义(因为它需要它)std::make_pair(来自相同的标准标头,并且为了论证,我们假设不需要定义<map>)。如果实现版本本身<utility>包含一堆其他文件,用于不同的位,并且<map>只包含它需要的位,则这是可能的。为标头授予了包含其他标头的特定权限,但我不知道是否为标头授予了将内容放入命名空间std而不包含整个相应标头的特定权限。问题是,在实践中,很难注意到您忘记了在这些情况下包含的标准,因为实现不会检查您,这就是为什么我知道在实践中我很可能不会这样做。幸运的是,对于移植到具有不同标头依赖项的实现的任何人来说,这应该是任何简单的修复。