【问题标题】:Declaring namespace as macro - C++将命名空间声明为宏 - C++
【发布时间】:2010-02-25 04:05:14
【问题描述】:

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

#define _STD_BEGIN  namespace std {
#define _STD_END        }
  1. 这是使用命名空间时的最佳做法吗?
  2. 宏在Microsoft Visual Studio 9.0\VC\include\yvals.h 中声明。但是我找不到包括这个的 STL 文件。如果不包含,如何使用?

有什么想法吗?

【问题讨论】:

    标签: c++ macros namespaces


    【解决方案1】:

    可能不是最佳实践,因为与普通的 namespace 声明相比,它可能难以阅读。也就是说,记住规则并不总是普遍适用,而且我敢肯定在某些情况下宏可能会大大清理内容。

    “但是我找不到包含这个的STL文件。如果不包含,如何使用?”。

    所有使用这个宏的文件都包含yvals.h。例如<vector> 包括<memory>,其中包括<iterator>,其中包括<xutility>,其中包括<climits>,其中包括<yvals.h>。链条可能很深,但它确实在某个点包含它。

    我想澄清一下,这只适用于标准库的这个特定实现;这绝不是标准化的。

    【讨论】:

    • 在 C++11 及更高版本中,这对于使用 inline namespaces 对库进行版本控制非常有用。基本上,只要 ABI 兼容性被破坏,您的宏就会更改内联命名空间的名称。
    【解决方案2】:
    1. 一般来说不会。这些宏可能是在某些编译器未实现命名空间时使用的,或者是为了与特定平台兼容。
    2. 不知道。该文件可能会被包含在 STL 文件中的某个其他文件包含在内。

    【讨论】:

    • 谢谢。我检查并找不到包括此文件在内的其他一些文件。
    【解决方案3】:

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

    BEGIN_NAMESPACE_XXX()
    

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

    BEGIN_NAMESPACE_3(ns1, ns1, ns3)
    

    将接受三个参数并扩展为

    namespace ns1 {
        namespace ns2 {
            namespace ns2 {
    

    匹配的END_NAMESPACE_3 将扩展为

            }
        }
    }
    

    (为了清楚起见,我添加了换行符和缩进)

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        我可以看到通过引用包含在 C++ 中的 C 库执行此操作(例如,C 调用 string.h 和 C++ 调用 cstring 的标头)。在这种情况下,宏定义将取决于#ifdef _c_plus_plus

        我一般不会这样做。我想不出任何不支持命名空间、异常、模板或其他“现代”C++ 特性的编译器值得使用(现代在引号中,因为这些特性是在 90 年代中后期添加的)。事实上,根据我的定义,编译器只有在为各自的语言提供良好支持时才值得使用。这不是语言问题;这是一个简单的例子,“如果我选择语言 X,我更愿意使用它现在的样子,而不是十年或两年前的样子。”例如,我一直不明白为什么有些项目会花时间尝试支持 pre-ANSI C 编译器。

        【讨论】:

          猜你喜欢
          • 2011-06-14
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多