Rule A7-2-3 (required, implementation, automated)
Enumerations shall be declared as scoped enum classes.
Rationale
If unscoped enumeration enum is declared in a global scope, then its values can redeclare constants declared with the same identifier in the global scope. This may lead to developer’s confusion. Using enum-class as enumeration encloses its enumerators in its inner scope and prevent redeclaring identifiers from outer scope. Note that enum class enumerators disallow implicit conversion to numeric values.
Example
// $Id: A7-2-3.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
enum E1 : std::int32_t // Non-compliant
{
E10,
E11,
E12
};
enum class E2 : std::int32_t // Compliant
{
E20,
E21,
E22
};
// static std::int32_t E1_0 = 5; // E1_0 symbol redeclaration, compilation
// error
static std::int32_t e20 = 5; // No redeclarations, no compilation error
extern void F1(std::int32_t number)
{
}
void F2()
{
F1(0);
F1(E11); // Implicit conversion from enum to std::int32_t type
// f1(E2::E2_1); // Implicit conversion not possible, compilation error
F1(static_cast<std::int32_t>(
E2::E21)); // Only explicit conversion allows to
// pass E2_1 value to f1() function
}
See also
C++ Core Guidelines [11]: Enum.3: Prefer class enums over "‘plain"’ enums.