Martin Drozdik
Martin Drozdik

Reputation: 13313

How to correctly use C++ strongly typed enumerations?

I want to use the C++11 scoped enums with the default int implementation:

enum class Color
{
    gray          = 1,  
    red           = 2
};

This compiles with gcc, but:

Color color = Color::red;  // 'Color' is not a class or a namespace
Color color = red;         // 'red' was not declared in this scope

What am I doing wrong?

EDIT:

This should be compilable, but it isn't, at least for me. I am using gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3). When I try:

 make -std=c++0x -w in /home/martin/Projects/StrongTypedEnums-build-desktop 

I get

:-1: error: invalid option -- '='. 

I am doing everything via IDE and have no idea about passing compiler arguments whatsoever.

enum class Color
{
    gray          = 1,
    red           = 2
};

int main(int argc, char *argv[])
{
    Color color = Color::red; // 'Color' is not a class or a namespace
    return 0;
}

Upvotes: 1

Views: 4397

Answers (2)

Peter Rankin
Peter Rankin

Reputation: 733

I had the same problem using Code::Blocks 10.05 using GCC.

What I had to do was go to Project > Build Options, select my project name on the left pane (not "Debug" or "Release"). Then, under the selected compiler "GNU GCC Compiler", under "Compiler Settings", "Compiler Flags", I checked "Have g++ follow the coming C++0x ISO C++ language standard [-std=c++0x]."

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 473447

Strongly-typed enums require scoping. You must prefix them with EnumName::, just as though they were static members of a class. Regular enums in C++11 can optionally be prefixed, but strongly-typed ones require it.

C++11 essentially three new features added to enums:

  • Explicit typing (enum class EnumName : int)
  • lexical scoping (EnumName:: syntax)
  • strong typing.

You can get the first two with regular enums (backwards compatibility makes both of them optional for non-class enums). But the only way to get strong typing is with enum class, which requires both of the others (if you don't specify an explicit type for enum class declarations, I believe it uses int).

The enforced scoping means that you generally don't need to ALL_CAPS enumerator names for enum classes, since you have to explicitly scope them anyway.

Upvotes: 4

Related Questions