我应该#include在我的库的命名空间中吗?

时间:2014-09-02 23:20:37

标签: c++ namespaces

我有一个存在于自己的命名空间中的库。每个文件都由此命名空间包装。当我使用标准库时,是否应将其包含在全局命名空间或我的库中?而且,图书馆实习生包括什么。它们应该进入命名空间的内部还是外部?

#include <vector> // This allows reuse

namespace library {
    #include <vector> // This would not leak anything
    #include "cart.h"
    using namespace std;

    class Train {
        vector<cart> carts;
    };
}

当用户需要向量时,包含到全局命名空间中也是有意义的,因此编译器不需要集成标准库的两个版本。另一方面,包含在库的命名空间中可以确保没有任何泄漏。

1 个答案:

答案 0 :(得分:2)

应用的“常识”表明您无法在自己的命名空间中可靠地包含C ++标准头文件。标准库代码应位于std命名空间中,而不是library::std命名空间中。如果存在任何非模板化函数,系统库将提供std::non_templated_function而不是library::std::non_templated_function,因此您的代码将不会链接。如果一切都是模板,你可能会侥幸逃脱,但它(不必要地)风险最多,所以不要这样做。

进一步(如T.C.中的comment所述),C ++ 11标准(ISO / IEC 14882:2011)标准在§17.6.2.2标题中明确说明[使用.headers]

  

¶3翻译单位应仅在任何外部声明或定义之外包括标题,并且应当   在该翻译单元中的第一个引用之前以词汇方式包含标题到声明的任何实体   在那个标题中。

当然,这是指来自C ++标准库的标题;它对你自己的标题没有这样的禁止。

理论上,如果您愿意,您的库的内部标题可以包含在library命名空间内(但它们不应该 - 见下文):

namespace library {
    #include "library/internal-header.h"
    …other declarations or definitions…
}

但是(如Matt McNabb中所述comment),这样做意味着内部标头不能包含任何新的标准标头,但内部标头需要的是合理的使用一些(额外的)标准标题。

您可能会考虑将它们包含在您自己的内部子命名空间中(例如,library::internal)。如果您的内部标头不包含自己的namespace library { … }块,请确保始终将它们包含在包含它们的标头中的命名空间library { … }括号范围内,但请注意,内部标头不再完整独立的。

或者,更可靠的是,您的库的内部头文件可以应该是独立的,其内容在library命名空间内定义(因为名称空间是可扩展的)。

#include "library/internal-header.h"
namespace library {
    …other declarations or definitions…
}

"library/internal-header.h"包含的地方:

namespace library {
    namespace internal {
        …internal declarations or definitions…
    }
}

其中namespace internal {和匹配}是可选的 - 您可能还需要using namespace library::internal;指令。

任何一种机制都可以起作用。但总的来说,独立标题更好(我同意πάντα ῥεῖ和他的comment以及Matt McNabb。)