使用STL类而不包括其适当的标头

时间:2013-12-14 06:06:05

标签: c++ header include language-lawyer

考虑以下代码:

#include <vector>

struct S { };

int main()
{
    std::vector<int> v;
    // Do whatever work I need to with v

    // Oh, by the way, I also need std::allocator for something else...
    std::allocator<S> a;
    S s;
    a.construct(&s, S());
    a.destroy(&s);
}

std::allocator<memory>中声明,但我 包含该标题。

问题:

  1. 通过加入std::allocator,我仍然可以依靠<vector>完全可用吗?为什么/为什么不呢?

  2. 如果是这样,我可以依赖间接包含哪些其他类,以及在什么条件下?
    (某个地方是否有列表,或者我是否必须手动计算出来?)

  3. 如果您已经包含了另一个标题,意味着包含您需要的课程,那么避免包含特定标题(例如<memory>)是不错的做法?为什么/为什么不呢?

2 个答案:

答案 0 :(得分:4)

C ++标准允许任何标准标头包含任意数量的其他标准标头。然而,实际上几乎从未需要它。

例如,将实现细节放在detail命名空间中,然后从那里拉取名称以便公开访问是相当普遍的,当且仅当用户包含需要使其可见的标头时。

换句话说,如果您正在使用某些内容,请添加标题。这实际上是一个非常常见的问题来源。对于较旧的编译器,包括一个标题通常最终定义了很多标题不需要定义。较新的编译器往往更精细,因此许多旧代码需要进行少量修补才能在正确工作之前包含正确的标头。虽然不是最大的可移植性问题,但这是非常令人讨厌的,如果可以的话,最好避免使用它。

即使在少数几个地方,也有文件要求一个标题包含另一个标题(或者至少要做同等标题),我认为依赖标题是一个相当糟糕的主意。首先,因为#include行充当一种文档,并且取决于间接包含意味着任何使用它们作为文档的人都必须考虑所有间接定义。其次,因为很容易认为因为包含一个标题必须定义一些通常在另一个标题中定义的特定项目,所以它将自动定义该标题中的所有内容,这不一定是真的。

答案 1 :(得分:0)

标准提供保证或不保证。如果没有,那么你无法保证。你的“暗示包含”参数失败了,因为编译器不需要包含它所需的任何类,并且显然你对该类所做的任何事情都需要更多。