关于c ++:在类访问混乱中声明的枚举类型

enum type declared inside a class access confusion

在下面的MyClass内幕,enum MyType定义为类。

在主,我创建一个变量MyClass::MyType t)。这compiles精细。然而,当我想它值这么assign的开放有一个编译错误",这是不符合开放。"

首先,它可能不会让义declaring一类的枚举类型的内幕有限制其范围,然后创建一个枚举类型变量)的地方,但我只是想明白发生什么事。

在第一个地方,我如何能够创建一个变量在一MyType主对象时(甚至还没有被创建的T?enums和结构类型的定义是这样的implicitly静态类?

另外,在编译的代码枚举的蛛网膜下腔出血(SAH)的访问,是不是我,为什么它的"开放"?好的,谢谢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>

using namespace std;

class MyClass
{
    public:

        enum MyType
        {
            OPEN,
            CLOSED
        };

        struct MyStruct
        {
            int val1;
            int val2;
        };
};

int main()
{
    MyClass::MyType t;
    t = OPEN; // compilation error

    return 0;
}


(除了其他人写的以外)

如果编译器支持(因为C++ 11),最好使用enum class

1
2
3
4
5
enum class MyType
{
    OPEN,
    CLOSED
};

"枚举类"("新枚举"、"强枚举")解决了传统C++枚举中的三个问题:

1)常规枚举隐式转换为整数,当有人不希望枚举充当整数时会导致错误。

2)常规枚举将其枚举器导出到周围范围,导致名称冲突。

3)无法指定枚举的基础类型,从而导致混淆、兼容性问题,并且无法进行正向声明。"

isocpp faq-枚举类

-

在这种情况下,请使用以下语法:

1
2
3
4
5
6
7
8
int main()
{
    MyClass c;
    MyClass::MyType t;
    t = MyClass::MyType::OPEN;

    return 0;
}

您的枚举MyType在类中,因此它的值应该通过类和枚举来访问。您已经在不实例化类的情况下创建了MyType,但是还提供了通过类实例化的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class MyClass
{
    public:

    enum MyType
    {
        OPEN,
        CLOSED
    };

    struct MyStruct
    {
        int val1;
        int val2;
    };
};

int main()
{
    MyClass::MyType t; // Already a MyType value!
    MyClass c; // Building your class

    t = MyClass::MyType::OPEN; // No compilation error
    t = c.OPEN; // Accessing enum through instantiated class

    return 0;
}


就像雷米说的。值OPENMyClass类的一部分,只能在该类范围内访问。为了让编译器看到并使用它,您需要通过MyClass::OPEN访问它。


参见[decl.enum]/11:

Each enum-name and each unscoped enumerator is declared in the scope
that immediately contains the enum-specifier. Each scoped enumerator
is declared in the scope of the enumeration. These names obey the
scope rules defined for all names in [basic.scope] and [basic.lookup].
[?Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum direction { left='l', right='r' };

void g()  {
  direction d;                  // OK
  d = left;                     // OK
  d = direction::right;         // OK
}

enum class altitude { high='h', low='l' };

void h()  {
  altitude a;                   // OK
  a = high;                     // error: high not in scope
  a = altitude::low;            // OK
}

—?end example?] An enumerator declared in class scope can be referred
to using the class member access operators (?::?, . (dot) and ->
(arrow)), see [expr.ref]. [?Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct X {
  enum direction { left='l', right='r' };
  int f(int i) { return i==left ? 0 : i==right ? 1 : 2; }
};

void g(X* p) {
  direction d;                  // error: direction not in scope
  int i;
  i = p->f(left);               // error: left not in scope
  i = p->f(X::right);           // OK
  i = p->f(p->left);            // OK
  // ...
}

—?end example?]