简体   繁体   English

"类中的 C++ 枚举 - 声明的顺序很重要?"

[英]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:我正在使用visual studio 2010,但不太明白,这个类怎么错了(语法错误:标识符'EnumType')并且无法编译:

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) 我不认为定义(非声明)的顺序很重要,但前向声明将解决此错误 - 至少在MSVC ++ 6中。在MSVC ++ 6之外,您应该指定一个存储类型来转发声明一个枚举(指定的要求)前向枚举中的存储类型是在C ++ 0x标准中)

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): 注意:VC ++ 6将允许省略存储类型,但如果您正在声明枚举,则应声明存储类型(见下文):

This will resolve the error in VC++6. 这将解决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: 但是,VC ++ 6似乎不支持C ++ 0x标准所要求的类内枚举的存储类型:

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: 通常在符合C ++ 0x的编译器中使用IE,您可以使用以下内容:

class BrokenClassWithEnum {
public:
    enum EnumType : int;

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

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

Forward declaring an enum in c++ 转发在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. 在C ++中,任何引用的非内置名称必须先于某处声明。

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. 适合您的问题的C ++ 03解决方案是在首次使用之前定义枚举类型。 With C++11 you can alternatively forward-declare it, but then an underlying type must be specified, 使用C ++ 11,您可以替代地向前声明它,但是必须指定基础类型,

C++11 §7.2/3 : 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. opaque-enum-declaration是对当前作用域中枚举的重新声明或新枚举的声明。 [ Note: An enumeration declared by an opaque-enum-declaration has fixed underlying type and is a complete type. [ 注意: opaque-enum-declaration声明的枚举具有固定的底层类型,并且是完整类型。 The list of enumerators can be provided in a later redeclaration with an enum- specifier . 可在随后的重声明中提供有enum-符枚举的列表。 —end note ] A scoped enumeration shall not be later redeclared as unscoped or with a different underlying type. -end note ]范围内的枚举不得在以后重新声明为无范围或具有不同的基础类型。 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.” 未作明目的的枚举不得在以后重新声明为范围,每次重新声明应包括一个枚举基础,指明与原始声明中相同的基础类型。“

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

"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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