我应该在库的命名空间中 #include 吗?
Should I #include in my library's namespace?
我有一个库,它位于自己的命名空间中。每个文件都由这个命名空间包装。当我使用标准库时,我应该将它包括在全局命名空间中还是我的库中?此外,图书馆实习生还包括。它们应该进入命名空间内部还是外部?
#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)。
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 在命名空间中定义函数还是限定函数
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- CUDA内核和数学函数的显式命名空间
- 嵌套的匿名命名空间
- CMakeLists.txt中的命名空间表示法
- 类是C++中的命名空间吗
- 在命名空间中使用全局命名空间中的函数
- 是否可以将一个命名空间类 #include 到另一个命名空间中
- 比较C++中的#include和使用命名空间std与Python中的import
- 在命名空间中放入一个标准的纯C头#include指令可以吗
- C++:在'#include <files>'之前是否允许命名空间定义。
- 我应该在库的命名空间中 #include 吗?
- 哪个更重要?头守卫、命名空间和include
- 在命名空间块中包装#include是个好主意吗?
- Java到C++命名空间和#include
- #include < windows.h> 在全局命名空间中定义了许多符号,例如 Polygon