Enumeration Scoping in C++
C++
The Problem
I spent way too much time trying to figure out what was wrong with this code:
#include <iostream>
using namespace std;
enum enum_1 { ok, warning, error };
enum enum_2 { ok, warning, error };
int main() {
= enum_1::ok;
enum_1 my_value1 = enum_2::error;
enum_2 my_value2
if (my_value1 == enum_1::ok) {
<< "my_value1 is OK!" << endl;
cout } else {
<< "my_value1 is not OK!" << endl;
cout }
if (my_value2 == enum_2::ok) {
<< "my_value2 is OK!" << endl;
cout } else {
<< "my_value2 is not OK!" << endl;
cout }
return (0);
}
Trying to build this code produces the following errors:
main.cpp:9:15: error: redefinition of enumerator 'ok'
enum enum_2 { ok, warning, error };
^
main.cpp:6:15: note: previous definition is here
enum enum_1 { ok, warning, error };
^
main.cpp:9:19: error: redefinition of enumerator 'warning'
enum enum_2 { ok, warning, error };
^
main.cpp:6:19: note: previous definition is here
enum enum_1 { ok, warning, error };
^
main.cpp:9:28: error: redefinition of enumerator 'error'
enum enum_2 { ok, warning, error };
^
main.cpp:6:28: note: previous definition is here
enum enum_1 { ok, warning, error };
^
main.cpp:13:30: error: no member named 'error' in 'enum_2'
enum_2 my_value2 = enum_2::error;
~~~~~~~~^
main.cpp:21:20: error: no member named 'ok' in 'enum_2'; did you mean simply 'ok'?
if (my_value2 == enum_2::ok) {
^~~~~~~~~~
ok
main.cpp:6:15: note: 'ok' declared here
enum enum_1 { ok, warning, error }; ^
A quick search of StackOverflow, and I learned that “old style” enumerations in C++ are unscoped. Since the individual members in enums are global, the member names have to be unique.
Solution 1 (C++11)
If your compiler supports the C++11 standard, the fix is easy. Just add “class” to your enum declarations:
#include <iostream>
using namespace std;
enum class enum_1 { ok, warning, error };
enum class enum_2 { ok, warning, error };
int main() {
= enum_1::ok;
enum_1 my_value1 = enum_2::error;
enum_2 my_value2
if (my_value1 == enum_1::ok) {
<< "my_value1 is OK!" << endl;
cout } else {
<< "my_value1 is not OK!" << endl;
cout }
if (my_value2 == enum_2::ok) {
<< "my_value2 is OK!" << endl;
cout } else {
<< "my_value2 is not OK!" << endl;
cout }
return (0);
}
Solution 2
Alternatively, you can wrap your enums in namespaces:
namespace scope1 {
enum enum_1 { ok, warning, error };
}
namespace scope2 {
enum enum_2 { ok, warning, error };
}
Then, you can access the members as scope1::enum_1::ok
, scope2::enum_2::warning
, etc.