C++ 枚举值的行为是否类似于全局变量?

C++ 枚举值的行为是否类似于全局变量?,c++,enums,C++,Enums,我有两个枚举,如果一个枚举中有一个值与另一个枚举中的值同名: enum A {joe, bob, doc}; enum B {sunday, monday, doc}; 编译器(VisualStudio)抱怨重新定义了doc,这意味着它将其视为一个全局变量。是这样吗?这不是我期望的行为,它迫使我管理项目中所有枚举元素的名称 任何见解都会有所帮助 C++03中的枚举数与枚举数的作用域相同 enum xxx { yyy, zzz };

我有两个枚举,如果一个枚举中有一个值与另一个枚举中的值同名:

enum A {joe, bob, doc};
enum B {sunday, monday, doc};
编译器(VisualStudio)抱怨重新定义了
doc
,这意味着它将其视为一个全局变量。是这样吗?这不是我期望的行为,它迫使我管理项目中所有枚举元素的名称


任何见解都会有所帮助

C++03中的枚举数与枚举数的作用域相同

enum     xxx    {    yyy,       zzz       };
          ^           ^          ^ 
    enumeration    enumerator enumerator
这有时是方便的,有时不是真的


在C++0x中,我们将有
enum类
es,它们更像C#的
enum
。同时,只需假设(因为这是语言规则)
yyy
zzz
的作用域与
xxx

的作用域完全相同,即枚举的值具有枚举本身的作用域,即它的声明作用域。例如:

enum A {value = 30};

int main()
{
   enum B {value = 32};
   int x = value;
}
enum A {joe, bob, doc};
namespace C { enum B {sunday, monday, doc}; }

x将是32。

枚举的值存在于
枚举
声明的任何范围内

例如,以下工作:

enum A {value = 30};

int main()
{
   enum B {value = 32};
   int x = value;
}
enum A {joe, bob, doc};
namespace C { enum B {sunday, monday, doc}; }


如果希望它们是全局的,请将
enum
s放入命名空间中,以解决问题并避免命名空间污染:

namespace A
{
    enum A {joe, bob, doc};
}
namespace B
{
    enum B {sunday, monday, doc};
}

A::doc;
B::doc;

它不是一个全局变量。它被视为全局标识符

更准确地说,它被视为
enum
在任何名称空间中声明的标识符。在您的例子中,这是全局名称空间

要了解全局标识符和全局变量之间的区别,请尝试获取枚举的地址。;)

通常,在定义枚举时,我会在前面加上标识符名称的缩写版本。像这样:

enum InstrumentType { itStock, itEquityOption, itFutureOption };

这有助于避免碰撞。

怀亚特·安德森已经建议

namespace A
{
    enum A {joe, bob, doc};
}
namespace B
{
    enum B {sunday, monday, doc};
}
作为“枚举值与枚举本身在同一范围内”问题的修复,允许您编写

A::doc;
B::doc;
但是,当您想要类的
enum
本地时,此解决方案不可用,至少在类之外引入人工名称空间时是不可用的

一个简单的解决方案是将每个
enum
包装在一个结构中,如下所示:

struct A
{
    enum Enum {joe, bob, doc};
};
struct B
{
    enum Enum {sunday, monday, doc};
};
这允许使用与命名空间解决方案相同的使用表示法

A::doc;
B::doc;
但它还允许

  • 类中的定义

  • 通过继承将枚举名称直接引入类,以及

  • 通过
    typedef
    对限定符进行本地类内重命名

此外,上面例举的命名约定允许

  • 在我看来,在引用枚举类型时需要更加清晰,例如编写
    a::enum
好的,命名约定也可以用于基于名称空间的解决方案


干杯&hth.,

假设我们要声明图形窗口的纵横比。然后按照建议定义枚举值:

struct __aspect_ratio__
{
    enum values
    {
        ASPECT_RATIO_16_9,  // HD video
        ASPECT_RATIO_16_2,  // *for testing purposes*
        ASPECT_RATIO_4_3,   // standard monitor
        ASPECT_RATIO_3_2,   // classic film
        ASPECT_RATIO_21_9,  // cinemascope
        ASPECT_RATIO_1_1    // quadratic window
    };
};

typedef __aspect_ratio__::values AspectRatio;
最后的
typedef
允许我们使用
AspectRatio::ASPECT\u RATIO\u 16\u 9
作为缩写,例如函数签名:

void SetAspectRatio(AspectRatio aspect)
{
    switch(aspect)
    {
    case AspectRatio::ASPECT_RATIO_16_9:
    // ...
    default:
            std::cerr << "Undefined aspect ratio enum value!" << std::endl;
        }
    }
}

这是一个类型安全的替代方案,不会污染封闭范围。

我们能看到更多代码吗?也许问题就在附近。这不是编译器的正常行为,抱歉,我不知道!对于C?@ykatchou也是一样的:如果上面的两行是正在编译的cpp文件中的唯一行,则会发生这种情况。不,但是代码中会有11个错误。尝试编译它,但如果将
enum 1
更改为
enum A
并将
enum 2
更改为
enum B
,则代码将编译,您仍将显示范围。双赢?如果在这个问题的所有答案中没有一个解决了这个可变的问题,我会大笑不止+1我觉得“变量”不是正确的术语,但我没有更好的术语(现在我有了…)