C ++枚举在一个类中 - 声明顺序很重要?

时间:2013-01-12 00:11:24

标签: c++ visual-studio-2010

我正在使用visual studio 2010,并且不能完全搞定,这个类怎么错(语法错误:标识符'EnumType')并且不会编译:

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

这没关系:

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

班级范围发生了什么变化?

3 个答案:

答案 0 :(得分:5)

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

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

这将解决VC ++ 6中的错误。但是,VC ++ 6似乎不支持C ++ 0x标准所要求的类内枚举的存储类型:

class BrokenClassWithEnum {
public:
    enum EnumType;

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

<小时/>

通常是I.E.在符合C ++ 0x的编译器中,您可以使用类似:

class BrokenClassWithEnum {
public:
    enum EnumType : int;

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

注意:在某些但不是所有C ++版本中都可以转发枚举声明:

Forward declaring an enum in c++

答案 1 :(得分:3)

在类定义本身中,项必须按顺序出现(依赖项出现在依赖于它们的项之前),就像在任何其他范围一样。在类方法 body 中(即使内联),该类的整个定义也可用。

答案 2 :(得分:3)

在C ++中,任何引用的非内置名称必须先于某处声明。

这个规则似乎有一个类定义的例外,因为以下工作正常:

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

但是,关于声明使用前的规则适用于转换后的代码

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

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

这是编译器“正确”看到的内容。在这里没有使用任何尚未宣布的东西。

解决问题的正确C ++ 03解决方案是在首次使用之前定义枚举类型。使用C ++ 11,您可以替代地向前声明它,但是必须指定基础类型,

  

C ++11§7.2/ 3
  “ opaque-enum-declaration 是对当前作用域中枚举的重新声明或声明   一个新的枚举。 [注意: opaque-enum-declaration 声明的枚举具有固定的基础   类型并且是完整类型。可以在稍后的重新声明中使用 enum-提供枚举器列表。   符 -end note ]范围内的枚举不得在以后重新声明为无范围或不同的   基础类型。未编入范围的枚举不得在以后重新声明为范围和每次重新声明   应包括 enum-base ,指定与原始声明中相同的基础类型。“