将命名空间声明为宏 - C++

7

在标准库中,我发现命名空间std被声明为一个宏。

#define _STD_BEGIN  namespace std {
#define _STD_END        }
  1. 在使用命名空间时,这是最佳实践吗?
  2. 这个宏是在Microsoft Visual Studio 9.0\VC\include\yvals.h中声明的。但我找不到包含它的STL文件。如果没有包含它,它怎么能被使用呢?

有什么想法吗..?

5个回答

7

这可能不是最佳实践,因为与普通的namespace声明相比,它可能难以阅读。尽管如此,请记住规则并不总是适用于所有情况,我相信在某些情况下,宏可能会大大简化事情。

"但我找不到包含这个的STL文件。 如果没有包含它,该怎么使用?"。

使用此宏的所有文件都以某种方式包括yvals.h。例如,<vector>包括<memory>,后者包括<iterator>,后者包括<xutility>,后者包括<climits>,后者包括<yvals.h>。链可能很深,但它在某个时刻确实包含它。

我想澄清的是,这仅适用于标准库的这个特定实现;这在任何方面都不是标准化的。


在C++11及以上版本中,使用内联命名空间对库进行版本控制非常有用。基本上,当ABI兼容性被破坏时,您的宏将更改内联命名空间的名称。 - Louis Dionne

3
  1. 一般来说不需要。宏可能是在某些编译器尚未实现命名空间时使用的,或者为了与特定平台兼容。
  2. 不确定。该文件可能会被包含在STL文件中的其他文件中。

谢谢。我检查了一下,没有找到其他文件,包括这个文件。 - Navaneeth K N

2

我最近使用的一个库中看到的一种方法是:

BEGIN_NAMESPACE_XXX()

其中XXX是命名空间级别的数字,例如:

BEGIN_NAMESPACE_3(ns1, ns1, ns3)

会带三个参数并扩展为:
namespace ns1 {
    namespace ns2 {
        namespace ns2 {

相应的,匹配的END_NAMESPACE_3将被扩展为

        }
    }
}

(我已经添加了换行和缩进,仅为了清晰起见)


1
我想唯一这样做的原因是,如果您想要轻松更改应用程序/库使用的命名空间,或出于兼容性原因禁用命名空间。

0

我可以看到这样做适用于C++通过引用包含的C库(例如,C调用的头文件string.h和C++调用的cstring)。在这种情况下,宏定义将取决于#ifdef _c_plus_plus

一般情况下我不会这样做。我想不出有任何值得使用的编译器不支持命名空间、异常、模板或其他“现代”C++特性(“现代”加引号是因为这些特性是在90年代中后期添加的)。事实上,根据我的定义,只有当编译器对其相应的语言提供良好的支持时才值得使用。这不是一个语言问题;这只是一个简单的情况,“如果我选择语言X,我更喜欢使用它今天的形式,而不是二十年前的形式。”例如,我从来没有理解为什么有些项目花时间尝试支持ANSI C之前的编译器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接