Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++17: still using enums as constants? [duplicate]

Tags:

c++

enums

c++17

I am used to using enum as constants -- they're quick to write, can be placed in .h files, and work fine.

enum {BOX_LEFT=10, BOX_TOP=50, BOX_WIDTH=100, BOX_HEIGHT=50};
enum {REASONS_I_LIKE_ENUM_AS_CONSTANTS = 3};

Is this no longer a good idea?

I see good reasons to prefer enum class (conventional enums implicitly convert to int; conventional enums export their enumerators to the surrounding scope), but those are reasons to prefer old enum in this case.

I see in a thread on static constexpr int vs old-fashioned enum that old-style enum is better because with a static constexpr member you have to declare it outside the class as well. But this is apparently no longer true in C++17, and may only apply to class members anyway.

What's the preferred way in c++17?

like image 462
Topological Sort Avatar asked Jan 31 '19 17:01

Topological Sort


People also ask

Can enum have duplicate values in C?

CA1069: Enums should not have duplicate values.

Why do we use enum when constants are there?

You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time—for example, the choices on a menu, command line flags, and so on.

Can we have enum containing enum with same constant?

The values assigned to the enum names must be integral constant, i.e., it should not be of other types such string, float, etc. All the enum names must be unique in their scope, i.e., if we define two enum having same scope, then these two enums should have different enum names otherwise compiler will throw an error.

Can 2 enums have the same value?

Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.


2 Answers

This is subjective.

However, this was always an abuse of enums. You're not enumerating anything; you're just stealing the enum feature to get some unrelated with arbitrary integer values which are not intended to have their own logical "type".

That's why enum class is not appropriate here either (because, as you pointed out, enum class enforces the properties of an enum that should be there but which you do not actually want).

Since there's no longer any problem with static constexpr int, I'd use that (or constexpr inline int, or whatever it is this week).

like image 126
Lightness Races in Orbit Avatar answered Oct 05 '22 04:10

Lightness Races in Orbit


The example that you give for using enum's can be rewritten as:

struct Point
{
    int x;
    int y;
};

struct Box
{
    Point p;

    int width;
    int height;
};

constexpr Box b = { { 1, 2 }, 3, 4 };

int f()
{
    return b.p.x;
}

Using strong types instead of int could even be a benefit.

For me this is more legible. I could even add some functions into that.

like image 32
Robert Andrzejuk Avatar answered Oct 05 '22 03:10

Robert Andrzejuk