在标准库中,我发现命名空间std
被声明为一个宏。
#define _STD_BEGIN namespace std {
#define _STD_END }
- 在使用命名空间时,这是最佳实践吗?
- 这个宏是在
Microsoft Visual Studio 9.0\VC\include\yvals.h
中声明的。但我找不到包含它的STL文件。如果没有包含它,它怎么能被使用呢?
有什么想法吗..?
在标准库中,我发现命名空间std
被声明为一个宏。
#define _STD_BEGIN namespace std {
#define _STD_END }
Microsoft Visual Studio 9.0\VC\include\yvals.h
中声明的。但我找不到包含它的STL文件。如果没有包含它,它怎么能被使用呢?有什么想法吗..?
这可能不是最佳实践,因为与普通的namespace
声明相比,它可能难以阅读。尽管如此,请记住规则并不总是适用于所有情况,我相信在某些情况下,宏可能会大大简化事情。
"但我找不到包含这个的STL文件。 如果没有包含它,该怎么使用?"。
使用此宏的所有文件都以某种方式包括yvals.h
。例如,<vector>
包括<memory>
,后者包括<iterator>
,后者包括<xutility>
,后者包括<climits>
,后者包括<yvals.h>
。链可能很深,但它在某个时刻确实包含它。
我想澄清的是,这仅适用于标准库的这个特定实现;这在任何方面都不是标准化的。
我最近使用的一个库中看到的一种方法是:
BEGIN_NAMESPACE_XXX()
其中XXX是命名空间级别的数字,例如:
BEGIN_NAMESPACE_3(ns1, ns1, ns3)
namespace ns1 {
namespace ns2 {
namespace ns2 {
相应的,匹配的END_NAMESPACE_3
将被扩展为
}
}
}
(我已经添加了换行和缩进,仅为了清晰起见)
我可以看到这样做适用于C++通过引用包含的C库(例如,C调用的头文件string.h
和C++调用的cstring
)。在这种情况下,宏定义将取决于#ifdef _c_plus_plus
。
一般情况下我不会这样做。我想不出有任何值得使用的编译器不支持命名空间、异常、模板或其他“现代”C++特性(“现代”加引号是因为这些特性是在90年代中后期添加的)。事实上,根据我的定义,只有当编译器对其相应的语言提供良好的支持时才值得使用。这不是一个语言问题;这只是一个简单的情况,“如果我选择语言X,我更喜欢使用它今天的形式,而不是二十年前的形式。”例如,我从来没有理解为什么有些项目花时间尝试支持ANSI C之前的编译器。