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

Should I #include in my library's namespace?

本文关键字:#include 命名空间 我应该      更新时间:2023-10-16

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

#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;
    };
}

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

应用的"常识"表明您不能可靠地将C++标准头包含在自己的命名空间中。标准库代码应该在std命名空间中,而不是在library::std命名空间中。如果有任何非模板化函数,系统库将提供std::non_templated_function而不是library::std::non_templated_function,因此您的代码不会链接。如果一切都是一个模板,你可能会逃脱惩罚,但这充其量是(不必要的)风险,所以不要这么做

此外(正如T.C.在评论中所指出的),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在评论中指出的那样),这样做意味着内部标头不能包括任何新的标准标头,但内部标头需要使用一些(额外的)标准标头是很有可能的。

您可能需要考虑将它们包含在自己的内部子命名空间(例如,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;指令。

任何一种机制都可以发挥作用。然而,总的来说,独立的报头要好得多(我同意πάΓταῥεῖ以及他的评论和Matt McNabb)。