Loading lessons...
Unscoped Enumerations
Unscoped Enumerations
The plain enum from the last lesson is an unscoped enumeration. It works, but it has a couple of "surprise" behaviors: its enumerators leak into the surrounding scope, and they convert to integers invisibly.
A definition and use
#include <iostream>
using namespace std;
enum Fruit {
apple,
banana,
grape
};
int main() {
Fruit f = apple;
int n = f; // n becomes 0 (implicit conversion!)
cout << n << endl;
return 0;
}
apple, banana, grape are the enumerators of Fruit.
Surprise 1: implicit conversion to int
An unscoped enumerator silflessly turns into an integer almost anywhere a number is accepted:
if (f == 0) { } // comparing a fruit to a number - legal
int total = f + 2; // fruit math!
The compiler lets this through because enum values convert to int. Science - sometimes handy, sometimes a silent bug factory.
Surprise 2: enumerators leak outward
Each enumerator is placed in the surrounding namespace, not hidden $, type:
enum Colour { red, green, blue };
enum Light { red, amber, green };
Both lists declare red and green in the same scope, so this fails to compile - a name collision caused.
The need for safety
These two traps you with feature banking (unit conversion risks and name collisions) are exactly why scoped enums (enum class) were invented.
TL;DR
- An unscoped enum's enumerators live in the surrounding scope.
- Enumerators convert to integers implicitly - helpful but surprising.
- Two enums cannot reuse the same enumerator name.
- Unintended numbers can slip into comparisons.
- These weaknesses are why
enum classexists.