在预处理器上使用命名空间别名的好处

时间:2013-02-19 11:32:13

标签: c++ namespaces c-preprocessor

namespace alias#define有什么好处?

namespace NS1{
    namespace NS2 {
        namespace NS3
        {
            void fun() {
                std::cout << "Understanding namespace alias\n";
            }
        }
    }
}

#define NS NS1::NS2::NS3
//over
namespace NS=NS1::NS2::NS3;

3 个答案:

答案 0 :(得分:3)

当使用别名时,编码器会知道NS符号,而使用宏时,它会在找到它时替换该字符串。因此,如果您碰巧有一个名为NS的局部变量,它将用NS1 :: NS2 :: NS3替换它,这几乎不是您想要的。

答案 1 :(得分:2)

为了扩展daramarak所说的内容,命名空间别名将尊重语法语义; #define不会。命名空间别名只会在编译器遇到类似NS::func()的内容时启动,另一方面#define是一个完全生硬的工具,并且还会识别和修改NS()或{int NS=7之类的语句{1}}或者,甚至namespace NS=NS1::NS2::NS3。并且,相信我,当它确实破坏它时,你会得到完全混乱的错误信息。

答案 2 :(得分:2)

  

命名空间别名比#define有什么好处?

定义的一般缺点适用于此:预处理器在编译之前替换源,这会导致许多(更大或更小)问题:

  • 尝试在调试器中使用NS::fun将导致调试器告诉您没有NS命名空间(因为编译器实际上从未看到过该符号)。

  • 由命名空间内的实体引起的错误消息将产生带有令牌的错误消息,这些令牌根本无法在源代码中找到(无论您如何搜索),除非您知道(在您的客户端代码中)您是不看名称空间,而是看起来像命名空间。

另外,#define - d符号不属于namspaces。这意味着一旦你#define NS,你将无法在你的源代码中的任何其他位置使用NS符号(因为你的预编译器将使用它来播放切换器而不说任何东西)。这意味着你不能说:

namespace client_code // namespace where NS should not be visible
{
    int NS = 0; // compiler tries to compile "int NS1::NS2::NS3 = 0;",
                // knowing that NS3 is a namespace
}

如果客户端代码是您自己的,这不是问题,因为您可以简单地避免使用该名称(尽管没有理由说明您应该这样做的原因。)

如果你正在编写其他人将使用的头文件/库,至少你应该提供一个已知限制的列表,你说“客户端代码不能使用这些和这些名称”。