【问题标题】:Enum value collision with enum name枚举值与枚举名称冲突
【发布时间】:2012-07-06 14:02:26
【问题描述】:

让我们看一下我最近在项目某处发现的代码构造:

namespace Test
{
    enum EName
    {
        CoolEnum,
        NiceEnum
    };

    enum CoolEnum
    {
        CoolVal1,
        CoolVal2
    };

    enum NiceEnum
    {
        NiceVal1,
        NiceVal2
    };
}

我的问题是为什么编译器允许这样的事情。让我们在这里看一个代码示例:

Test::CoolEnum cEnum = Test::NiceVal1; // INVALID, as compiler refers to Test::CoolEnum value of Test::Ename enum

为什么允许这样的混淆?我理解为什么我必须添加 enum 关键字,所以编译器清楚地知道我正在声明给定枚举的变量,而不是使用同一命名空间中其他枚举的值。我只是不明白为什么一开始甚至可以进行这样的构造。

【问题讨论】:

  • 我猜是编译器定义的,因为 Ideone 上的代码会导致错误:ideone.com/4GDTF
  • 这就是我放置 gcc 的原因,但据我所知 vc 也允许这样的构造
  • @Kamil 您可能想要更改 NiceEnum 的枚举常量的名称,因为您从 CoolEnum 复制粘贴它并且它们发生冲突。

标签: c++ gcc enums


【解决方案1】:

C++11 的枚举类可以解决这个问题:

namespace Test
{
    enum class EName
    {
        CoolEnum,
        NiceEnum
    };

    enum class CoolEnum
    {
        NiceVal1,
        NiceVal2
    };

    enum class NiceEnum
    {
        NiceVal1,
        NiceVal2
    };
}

然后你可以使用合适的NiceVal1:

Test::CoolEnum cEnum = Test::CoolEnum::NiceVal1;

普通枚举是从 C 中继承而来的,在 C 中没有命名空间是什么的概念。如果普通枚举引入了某种命名空间,那么使用枚举的 C 代码将根本无法编译。这就是引入枚举类的原因,以免破坏向后兼容性。

【讨论】:

  • 很高兴知道,但这不是给定问题的答案。我很高兴他们在 C++11 中清除了问题,但我只是想知道为什么首先它是可能的
  • 我在命名空间之外放置了相同的结构,但它仍然对 C++ 完全有效
  • 我不明白你指的是什么,你能扩展或提供一个例子吗?
  • 我想我误解了你的说法:“如果普通枚举引入了某种命名空间,那么使用枚举的 C 代码将根本无法编译。”
  • 我的意思是,如果 C++ 普通枚举被修改并表现得像枚举类,那么 C 代码将无法编译。从 C 继承的这些特性无法更改。您只能添加新的来解决其中的问题。
【解决方案2】:

答案是因为标准规定了这种行为。见 3.3.7/2:

类名 (9.1) 或枚举名 (7.2) 可以通过名称隐藏 在同一作用域中声明的对象、函数或枚举器。如果一个 类或枚举名称和对象、函数或枚举器是 在相同范围内(以任何顺序)以相同的名称声明, 类或枚举名称隐藏在对象、函数或 枚举器名称可见。

大概是为了方便与C的机制兼容(枚举器不打开新的作用域),这个机制已经建立了很长时间了。

在您的情况下,至少对于 g++,您可以使用 typename 来表明您想要使用类型而不是枚举器 (typename Test::CoolEnum cEnum = Test::NiceVal1;)。

不过,一般来说,我喜欢将所有枚举限定在单独的命名空间或类中,以完全防止这些冲突。

【讨论】:

  • "typename Test::CoolEnum" 不正确 - GCC 碰巧接受了 but should reject it。请改用“enum Test::CoolEnum”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多