2

我正在使用 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);
}

班级范围发生了什么?

4

4 回答 4

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
    };
};


通常在符合 C++0x 的编译器中的 IE,你会使用类似的东西:

class BrokenClassWithEnum {
public:
    enum EnumType : int;

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

注意:枚举的前向声明在某些但不是所有 C++ 版本中是可能的:

在 C++ 中转发声明一个枚举

于 2013-01-12T00:16:09.547 回答
3

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

于 2013-01-12T00:16:37.263 回答
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 声明的枚举具有固定的底层类型,并且是完整的类型。枚举器列表可以在稍后的重新声明中使用枚举说明符提供。—结束注释] 以后不应将范围枚举重新声明为无范围或具有不同的基础类型。以后不应将无范围的枚举重新声明为有范围的枚举,并且每个重新声明都应包括一个枚举库,指定与原始声明中相同的基础类型。”

于 2013-01-12T01:35:29.923 回答
-1

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

于 2022-02-03T22:54:52.453 回答