3

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

And this is OK:

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

What happened to the class scope?

JockX
  • 1,928
  • 1
  • 16
  • 30
  • 5
    It doesn't have anything to do with scope -- you have to declare what `EnumType` is before you use it. That's just how C++ is. – Travis Gockel Jan 12 '13 at 00:14
  • 1
    The `enum` here is a red herring, any kind of type would do, including `typedef int EnumType;`. – GManNickG Jan 12 '13 at 00:18

4 Answers4

5

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 I.E. 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
    };
};

NOTE:Forward declaration of enums is possible in some but not all C++ versions:

Forward declaring an enum in c++

Community
  • 1
  • 1
A B
  • 4,068
  • 1
  • 20
  • 23
  • "I don't think the order of definition (not declaration) matters" it does. "a forward declaration will resolve this error" non-standard without a storage class (and C++03 didn't have that). however, it can work as a microsoft visual c++ specific solution. – Cheers and hth. - Alf Jan 12 '13 at 01:16
  • Why even mention MSVC 6.0 anyway? That's dead and gone. – GManNickG Jan 12 '13 at 01:18
3

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.

Mark B
  • 95,107
  • 10
  • 109
  • 188
3

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.”

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
-1

I believe member variables can be accessed before declarations within the class because class validation or compilation is done in two pass.

Kumar
  • 9
  • 2
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 04 '22 at 08:41