【问题标题】:how to disambiguate namespace and class with identical names如何消除具有相同名称的命名空间和类的歧义
【发布时间】:2013-05-27 11:59:54
【问题描述】:

考虑以下代码:

struct foo {
    typedef int bar;
};

namespace foo {
    class baz {
        /* code */
    };
}

这分布在我必须处理的代码库中,有时它会起作用,但我不明白如何。

只要命名空间和类不在同一个源中(预处理后),它就可以工作(我理解那部分)。但是,如果突然间命名空间和类都被预处理器拖入同一个编译单元,它(可能)会发生冲突(我不知道这是否曾经发生在源代码中)。

是否存在允许编译器始终正确解析代码结构的约定?最合乎逻辑的是命名空间和类禁止使用相同的符号。应用的编码风格允许命名空间与类发生冲突,尽管存在歧义,因此我更喜欢一种告诉编译器使用的方法,而不是更改编码约定。

类似:

use_namespace(foo)::baz b; 
use_class(foo) b;

【问题讨论】:

  • 你不能同时让 foo 成为一个类/结构和命名空间,所以毫无疑问如何消除歧义。
  • 我以前遇到过这种情况,但不太确定解释。据我记得,认为编译器为它们分配了不同的名称(损坏的名称)en.wikipedia.org/wiki/Name_mangling。完全谈论 C++。
  • @Nanda:他们可能有不同的错位名称,但不能保证。给类和命名空间同名是错误的。
  • 感谢您的澄清。

标签: c++ c++11


【解决方案1】:

C++11 标准的第 7.3.1/2 段简单地禁止:

original-namespace-definition中的标识符之前不应在声明中定义 original-namespace-definition 出现的区域original-namespace-definition 中的标识符 是命名空间的名称。随后在该声明性区域中,它被视为 original-namespacename

关于你的这份声明:

只要命名空间和类不在同一个源中(预处理后),它就可以工作

这是不正确的。第 7.3.2/4 段(尤其是最后一句)告诉您为什么它似乎“工作”,尽管您的程序格式不正确:

namespace-namenamespace-alias 不应被声明为同一名称中的任何其他实体的名称 声明区域。在全局范围内定义的 namespace-name 不应被声明为任何 程序的任何全局范围内的其他实体。 不需要对违反此规则的行为进行诊断 不同翻译单元中的声明

这意味着您正在使用的代码库具有未定义的行为,这可能是一个定时炸弹,可能会以难以理解的方式爆炸。

【讨论】:

  • 其实我很害怕某种答案。尽管未定义的行为通常在单个编译器上表现出确定性。
  • @Alex:但是可能会改变发布版本中的行为,或者当您使用特定的编译器设置时,或者发布下一版本的编译器时,或者......(等等等等)。我真的建议重新设计
  • 我同意,但要指出:编译器工程师是人,他们知道程序员也是人!因此,虽然这是未定义的行为,但编译器编写者通常会尝试通过以下方式帮助有过错的程序员:故意在故障点使代码崩溃,尝试使编译崩溃,或者,如果可能的话,至少构建未定义行为不会的一致结果在你午睡的时候咬你。 (即:我还没有看到只在一个仍然符合标准的编译器/架构上测试过的代码。)
  • 关于引用中的“预处理后”,这是否意味着如果结构和原始命名空间在不同的 .h 文件中声明(如果一个文件包含另一个文件)将不起作用?
【解决方案2】:

只要命名空间和类不在同一个源中(预处理后),它就可以工作(我理解那部分)。

不,它没有。根据 C++11 3.3.1/4,为两个不同的实体声明相同的名称会产生未定义的行为:

给定单个声明区域中的一组声明,每个声明都指定相同的非限定名称,它们都应引用相同的实体

(除了一些不包括给类和命名空间同名的例外情况)。

由于声明位于单独的翻译单元中,许多编译器无法诊断错误,因此它可能看起来有效。

但是,如果突然间命名空间和类都被预处理器拖入同一个编译单元,它(可能)会发生冲突(我不知道这是否发生在源代码中)。

现在它们在同一个翻译单元中,可以诊断错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 2011-12-01
    • 2012-02-27
    • 2017-08-26
    • 2015-07-18
    • 1970-01-01
    相关资源
    最近更新 更多