DEV Community

Swastik Baranwal
Swastik Baranwal

Posted on

Modern C++: enum class|struct

Following my series from less known features of Modern C++.

I saw this post the other day and I agreed with all his reasoning why enum in TypeScript aren't safe. (Read this article for more information.)

To solve these problems C++ 11 introduces enum class or enum struct. If you are lazy to read that post then the old enum had the following problems:

  • Conventional enums implicitly convert to int, causing errors when someone does not want an enumeration to act as an integer.
  • Conventional enums export their enumerators to the surrounding scope, causing name clashes.
  • The underlying type of an enum cannot be specified, causing confusion, compatibility problems, and makes forward declaration impossible.

Syntax



enum [class|struct] [identifier] [:type] {list};


Enter fullscreen mode Exit fullscreen mode

Both class and struct have the same meaning here (for no damn reason).

Usage



#include <iostream>

enum struct Num {One, Two, Three, Four, Five}; // default type is int

int main() {

    Num one = Num::One; // using :: operator for scope values

 std::cout << static_cast<int>(one) << std::endl; // using static_cast to obtain   the numerical value

   auto match_enum = [](Num one) {
       switch(one) {

        case Num::One:
         std::cout << "Num is one" << std::endl;
        break;

        case Num::Two:
         std::cout << "Num is two" << std::endl;
        break;

        case Num::Three:
         std::cout << "Num is one" << std::endl;
        break;

        default:
         std::`ncout << "Invalid" << std::endl;
        break;
       }

    };

  match_enum(one); // Using Num::One

  match_enum(Num(1)); // Casting the value to Num enum

}
```

Just like `enum` the values should be of literal type. There will be name clashes if we have `enum` and `enum class|struct` of the same name.


### `enum` V/S `enum class|struct`

- `enum` elements are accessed by `.` and `enum class|struct` are accessed by `::`.
- There can be clashes with other `enum` whereas `enum class|struct` are scoped so there are no clashes.
-  `enum` can be converted into other `enum` but this isn't the case for `enum struct|class`.

```cpp
#include <iostream>

enum class Day {Mon, Tues, Wed, Thur, Fri, Sat, Sun};

//enum Day {Mon, Tues, Wed, Thur, Fri, Sat, Sun}; // Error : Previous defination at line 2

enum Days {Mon, Tues, Wed, Thur, Fri, Sat, Sun};


int main() {

    Days day_scoped = Mon;
    int num = day_scoped; // Enum converted into int
    std::cout << num << std::endl;

    Day days;
    days = Day::Mon;
 //   int num2 = Day; // Error: Scoped Enum cannot be converted to int implicitly
    int num_scoped = static_cast<int>(days); // Valid: Scoped Enum converted to int explicitly
    std::cout << num_scoped << std::endl;


    return 0;
}
```

If we un-commented the some code above then the program will raise errors.

### Code 

All the code used in this article is available here.

{% github https://github.com/Delta456/modern_cpp_series %} 


If there is some mistake or confusion then please tell me by commenting below!
Enter fullscreen mode Exit fullscreen mode

Top comments (0)