== Why is this an issue?

There are two kinds of enumeration:

* The unscoped ``++enum++`` inherited from C
* The scoped enumeration ``++enum class++`` or ``++enum struct++`` added in {cpp} 11

Unscoped enumerations have two major drawbacks that are fixed by scoped enumerations:

* ``++enum++`` elements are visible from their enclosing scope instead of requiring the scope resolution operator (ex: ``++Red++`` instead of ``++Color::Red++``)
* ``++enum++`` elements convert implicitly to ``++int++``, so that heterogeneous comparisons such as ``++Red == Big++`` don't result in compile errors.

This rule raises an issue when an unscoped enumeration is used.


=== Noncompliant code example

[source,cpp]
----
enum Color { // Noncompliant: replace this "enum" with "enum class".
  Red   = 0xff0000,
  Green = 0x00ff00,
  Blue  = 0x0000ff
};

enum ProductType { // Noncompliant: replace this "enum" with "enum class".
  Small   = 1,
  Big     = 2
};

void printColor(int color);
void printInt(int value);

void report() {
  printColor(Red); // correct
  printColor(Big); // clearly buggy
  printInt(Red);   // conversion is implicit
}
----


=== Compliant solution

[source,cpp]
----
enum class Color { // declared using "enum class"
  Red   = 0xff0000,
  Green = 0x00ff00,
  Blue  = 0x0000ff
};

enum class ProductType { // declared using "enum class"
  Small   = 1,
  Big     = 2
};

void printColor(Color color); // requires "Color" instead of "int"
void printInt(int value);

void report() {
  printColor(Color::Red);       // correct
  // printColor(ProductType::Big); => Compilation error, no known conversion from 'ProductType' to 'Color'
  printInt(static_cast<int>(Color::Red)); // conversion never occurs implicitly and must be explicit
}
----


=== Exceptions

When the enum is a private class member, the class encapsulates its use, and the drawbacks of unscoped enums can be avoided. Therefore, the rule does not raise an issue in that case.


== Resources

=== Documentation

* {cpp} reference - https://en.cppreference.com/w/cpp/language/enum[Enumeration declaration]

=== External coding guidelines

* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#enum3-prefer-class-enums-over-plain-enums[Enum.3: Prefer class enums over "plain" enums]


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Replace this "enum" with "enum class".


=== Highlighting

``++enum++`` keyword


'''
== Comments And Links
(visible only on this page)

=== on 17 Jun 2016, 09:39:02 Ann Campbell wrote:
\[~alban.auzeill] I've edited the description. Please double-check me.


Also, I'm confused by this part of the Noncompliant example:

----
void report() {
  printColor(Color::Red);       // correct
  printColor(ProductType::Big); // clearly buggy
  printInt(Color::Red);         // conversion is implicit
}
----

I thought part of the point was that plain ``++enum++``s don't require the scope resolution operator...?

=== on 17 Jun 2016, 10:44:00 Alban Auzeill wrote:
\[~ann.campbell.2] You're right, I removed the qualifiers in the Noncompliant example.

endif::env-github,rspecator-view[]
