简体   繁体   中英

C++ Enum inside a class - order of declaration matters?

I am using visual studio 2010, and can't quite get, how is this class wrong (syntax error : identifier 'EnumType ') and won't compile:

class BrokenClassWithEnum
{
private:
    void useEnum (EnumType enumType); //syntax error : identifier 'EnumType '
public:
    enum EnumType 
    {
        VAL1,
        VAL2,
        VAL3
    };
}

I don't think the order of definition (not declaration) matters but a forward declaration will resolve this error - at least in MSVC++ 6. Outside of MSVC++ 6 you should specify a storage type to forward declare an enum (the requirement for specifying the storage type in a forward enum was in the C++0x standard)

NOTE: VC++ 6 will allow the storage type to be omitted, but if you are forward declaring an enum, you should declare the storage type (SEE BELOW):

This will resolve the error in VC++6. However, VC++6 does not appear to support a STORAGE TYPE for an enum inside a class as required by the C++0x standard:

class BrokenClassWithEnum {
public:
    enum EnumType;

private:
    void useEnum (EnumType enumType); 
public:
    enum EnumType {
        VAL1,
        VAL2,
        VAL3
    };
};


Normally IE within a C++0x compliant compiler you would use something like:

class BrokenClassWithEnum {
public:
    enum EnumType : int;

private:
    void useEnum (EnumType enumType);
public:
    enum EnumType : int {
        VAL1,
        VAL2,
        VAL3
    };
};

Forward declaration of enums is possible in some but not all C++ versions: 在某些但不是所有C ++版本中都可以转发枚举声明:

Forward declaring an enum in c++

Within the class definition itself, items must appear in order (with dependent items appearing before the items that depend on them) like they do at any other scope. Inside a class method body (even if inlined) the entire definition of the class is available.

In C++ any referenced non-built-in name must have been declared somewhere earlier.

It might appear that this rule has an exception for class definitions, because the following works fine:

struct S
{
    void foo() { cout << x_ << endl; }
    int x_;
    S(): x_( 42 ) {}
};

However, the rule about declaration-before-use applies to the transformed code

struct S
{
    inline void foo();
    int x_;
    inline S();
};

void S::foo() { cout << x_ << endl; }
S::S() : x_( 42 ) {}

which is what the compiler "proper" sees. And here there is no use of anything that hasn't already been declared.

The proper C++03 solution to your problem is to define the enumeration type before its first use. With C++11 you can alternatively forward-declare it, but then an underlying type must be specified,

C++11 §7.2/3 :
“An opaque-enum-declaration is either a redeclaration of an enumeration in the current scope or a declaration of a new enumeration. [ Note: An enumeration declared by an opaque-enum-declaration has fixed underlying type and is a complete type. The list of enumerators can be provided in a later redeclaration with an enum- specifier . —end note ] A scoped enumeration shall not be later redeclared as unscoped or with a different underlying type. An unscoped enumeration shall not be later redeclared as scoped and each redeclaration shall include an enum-base specifying the same underlying type as in the original declaration.”

我相信可以在类中的声明之前访问成员变量,因为类验证或编译是在两遍中完成的。

"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM