0

I wrote a basic program to show the issue I'm dealing with.

#include <iostream>
using namespace std;

class SomeClass {
    private:

    public:
    enum class SomeEnum : int {a, b, c};

    void print() {
        cout << "test";
    }
};

int main() {
    SomeClass::SomeEnum test1 = SomeClass::SomeEnum::a;
    SomeClass::SomeEnum test2 = SomeClass::SomeEnum::b;
    SomeClass::SomeEnum test3 = SomeClass::SomeEnum::c;
}

Basically, there's an enum class that is nested within another class. When I try compiling this on Linux, I have no problem. Compiling this on MacOS throws this at me:

test.cpp:8:10: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions]
    enum class SomeEnum : int {a, b, c};
         ^
test.cpp:8:10: error: reference to enumeration must use 'enum' not 'enum class' [-Welaborated-enum-class]
    enum class SomeEnum : int {a, b, c};
         ^~~~~~
test.cpp:8:31: error: expected '(' for function-style cast or type construction
    enum class SomeEnum : int {a, b, c};
                          ~~~ ^
test.cpp:16:5: error: no type named 'SomeEnum' in 'SomeClass'; did you mean simply 'SomeEnum'?
    SomeClass::SomeEnum test1 = SomeClass::SomeEnum::a;
    ^~~~~~~~~~~~~~~~~~~
    SomeEnum
test.cpp:8:16: note: 'SomeEnum' declared here
    enum class SomeEnum : int {a, b, c};
               ^
test.cpp:16:44: error: 'SomeEnum' is not a class, namespace, or enumeration
    SomeClass::SomeEnum test1 = SomeClass::SomeEnum::a;
                                           ^
test.cpp:17:25: error: use of undeclared identifier 'test2'; did you mean 'test1'?
    SomeClass::SomeEnum test2 = SomeClass::SomeEnum::b;
                        ^~~~~
                        test1
test.cpp:16:25: note: 'test1' declared here
    SomeClass::SomeEnum test1 = SomeClass::SomeEnum::a;
                        ^
test.cpp:17:24: error: expected ';' after expression
    SomeClass::SomeEnum test2 = SomeClass::SomeEnum::b;
                       ^
                       ;
test.cpp:17:16: error: no member named 'SomeEnum' in 'SomeClass'
    SomeClass::SomeEnum test2 = SomeClass::SomeEnum::b;
    ~~~~~~~~~~~^
test.cpp:17:44: error: 'SomeEnum' is not a class, namespace, or enumeration
    SomeClass::SomeEnum test2 = SomeClass::SomeEnum::b;
                                           ^
test.cpp:18:25: error: use of undeclared identifier 'test3'; did you mean 'test1'?
    SomeClass::SomeEnum test3 = SomeClass::SomeEnum::c;
                        ^~~~~
                        test1
test.cpp:16:25: note: 'test1' declared here
    SomeClass::SomeEnum test1 = SomeClass::SomeEnum::a;
                        ^
test.cpp:18:24: error: expected ';' after expression
    SomeClass::SomeEnum test3 = SomeClass::SomeEnum::c;
                       ^
                       ;
test.cpp:18:16: error: no member named 'SomeEnum' in 'SomeClass'
    SomeClass::SomeEnum test3 = SomeClass::SomeEnum::c;
    ~~~~~~~~~~~^
test.cpp:18:44: error: 'SomeEnum' is not a class, namespace, or enumeration
    SomeClass::SomeEnum test3 = SomeClass::SomeEnum::c;
                                           ^
1 warning and 12 errors generated.

I'm not totally sure what the issue is. Am I not allowed to nest enum classes inside other classes? Why does it compile with no warnings on Linux but completely break in MacOS?

Additionally, what is the difference between an enum class? My understanding is that enum classes are generally better practice, but I don't understand when you'd want to use one over the other.

1 Answers1

0

In order to have support for scoped enumerations (enum class) you must compile with -std=c++11 (or higher: c++14/c++17/c++20) since C++11 introduced them. This is what the first warning is telling you. The declaration is ill-formed pre-C++11 which is why you then get the following errors. This is not specific to the enum class being nested in another class.

Except for quite old versions, GCC defaults to -std=c++14 or -std=c++17, which is why you don't see an error or warning on Linux. Apple clang (which is what g++ really is a misleading alias for on Mac) defaults to -std=c++98, which is why you must manually enable C++11 or later. (Upstream clang also defaults to a more recent standard revision in non-obsolete versions.)

In C++11 or later mode there is nothing wrong with your code.

The reasons to prefer enum class over plain enum can be found e.g. in the question Why is enum class preferred over plain enum?.

user17732522
  • 53,019
  • 2
  • 56
  • 105