-
Scoped
-
Generally declaring a name inside of curly braces limits scope to inside the braces.
-
Not so for C++98 style enums.
-
Names belong to scope containing the enum
-
Nothing else in that scope can have the same name
enum Color { black, white, red }; // black, etc in the same scope as color
auto white = false; // error! white already declared in this scope
-
Because the C++98 style enum names leak into the outer scope we call them unscoped
-
The new C++ style counterpart doesn't leak names in the same way scoped
enum class Color { black, white, red }; // black, white, red are scoped to color
auto white = false; // totally ok
Color c = white; // no enumerator named white in this scope
Color c = Color::white; // fine
auto c = Color::white; // better
-
Declared via "enum class" so sometimes referred to as enum classes
-
-
Strongly Typed
-
Enumerators for unscoped enums implicitly convert to integral types
enum Color { black, white, red }; // unscoped enum
std::vectorstd::size_t primeFactors(std::size_t x);
Color c = red;
if (c < 14.5) { // compare to double! auto factors = primeFactors(c); // compute primeFactors of a color! }
-
There are no implicit conversions from enumerators in a scoped enum to any other type
-
If you want to perform a conversion from Color to different type use
static_cast<type>()
-
-
Able to be forward declared enum Color; // error
enum class Color; // works!
-
In C++11 unscoped enums can also be forward declared
-
Compilers choose the underlying type (generally to use the least space, be fast)
-
C++98 only supports enum definitions where all enumerators are listed so that it can select an underlying type.
-
The inability to forward declare enums increases compilation dependencies. Consider a new value being introduced to an enumeration in a header.
enum Status { good = 0, failed = 1, incomplete = 100, corrupt = 200, indeterminate = 0xFFFFFFFF };
-
In C++11 enums can be forward declared because the underlying type is always known.
- For the unscoped enums it can be specified.
-
The default underlying type for scoped enums is int.
-
Unscoped enums have no underlying type.
enum class Status; // underlying type is int enum class Status: std::uint32_t // underlying type is uint32_t (cstdint)
enum Color: std::uint8_t; // fwd decl for unscoped enum;
enum class Status: std::uint32_t { good = 0, failed = 1, incomplete = 100, corrupt = 200, autdited = 500, indeterminate = 0xFFFFFFFF };
-
-
Sometimes the implicit conversion of an unscoped enum to another type (like an integral type can be useful.
using UserInfo = std::tuple< std::string, // name std::string, // email std::size_t // reputation
;
UserInfo uInfo; auto val = std::get<1>(uInfo);
enum UserInfoFields { uiName, uiEmail, uiReputation };
auto val = std::get(uInfo);
enum class UserInfoFields { uiName, uiEmail, uiReputation };
auto val = std::get<static_caststd::size_t(UserInfoFields::uiEmail)>(uInfo);
Last active
August 29, 2015 14:11
-
-
Save TylerBrock/1201aa0c3f48144d0811 to your computer and use it in GitHub Desktop.
Effective Modern C++ Items 10 + 11
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment