7

I want to initialize a strongly-typed enum in C++11 from its underlying type, which is a value I read from serialized stream and which I have to check for a correct number range.

Something like:

enum class MyEnum {
    FOO, BAR
};

MyEnum test = static_cast<MyEnum>(1);

This works as expected, but the problem is:

MyEnum test2 = static_cast<MyEnum>(42);

also works and give no indication of an Error. As far as I see an enum class also does not have any notion of bounds or other indicators on how to check if the input is valid. In "old style" enums, we would include a MIN and MAX value and compare against those, but adding these values to the strongly-typed enum would add invalid values to this type again, undermining its purpose.

Any ideas how I could check the bounds or force an error in case the value is out of bounds?

Update:

I just tried std::numeric_limits, but this also does not work for enum classes:

cout << static_cast<unsigned int>(numeric_limits<MyEnum>::min()) << endl;
cout << static_cast<unsigned int>(numeric_limits<MyEnum>::max()) << endl;

both return 0.

VolkA
  • 34,983
  • 7
  • 37
  • 37
  • If you do `enum class MyEnum: unsigned int { FOO = 1, BAR = 2 };` What happens if you then try `MyEnum test2 = static_cast(42);`? – shuttle87 Jun 12 '14 at 12:24
  • seems like a duplicate of http://stackoverflow.com/questions/8221745/validate-integer-is-some-enum-class-item-c11?lq=1 – dragosht Jun 12 '14 at 12:28
  • The behavior (on gcc 4.6.2) is the same for unsigned int. I can output the enum using "cout << static_cast(test);" and get 42, so it just assigns without any checks. – VolkA Jun 12 '14 at 12:29
  • dragosht: yes, that's exactly the same question. Thanks for pointing this out, I did not find this one. So there does not seems to be a useful answer for this question ... – VolkA Jun 12 '14 at 12:31
  • 1
    Unfortunatly enum classes support no user defined methods or constructors. So the most clean thing I can imagine would be a freestanding method that checks the value and returns an enum: `MyEnum MyEnumFromValue(int v) {...}` – Matthias247 Jun 12 '14 at 12:45
  • 3
    The underlying type for your enumeration is `int`. Any value in the range of `int` is valid as far as C++ is concerned. If you want a limited range with checking then you have to implement that as a class type. – Cheers and hth. - Alf Jun 12 '14 at 13:08
  • Yes, the point is it would not be a problem to provide the min/max values for an enum class as type traits, and that would make the validation routines much more robust, but they don't seem to be available. Probably something that should be added to the standard... – VolkA Jun 13 '14 at 07:58

2 Answers2

6

There's currently no way to extract an enum's minimum or maximum enumerators, but http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3815.html proposes enough new type traits to implement a library that can do this. The Reflection group was interested, but asked the authors to come back with a proposal that more clearly generalized to other reflection features. I believe http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4027.pdf is the result of that generalization, and it'll get discussed at the meeting this coming week.

Jeffrey Yasskin
  • 5,171
  • 2
  • 27
  • 39
  • Thanks, that's a great answer for the "currently not possible" situation. The documents are indeed interesting to follow, let's see when/if this will become available. – VolkA Jun 15 '14 at 21:16
0

std::numeric_limits returns the max possible value of enum (depends on datatype) and not the maximum existing enum value.

Examples:

enum class MyType : uint8_t
{
    eType1    = 0,
    eType2    = 1,
    COUNT,
    MAXVAL    = std::numeric_limits<decltype(COUNT)>::max()
};

MAXVAL = 255

enum class MyType
{
    eType1    = 0,
    eType2    = 1,
    COUNT,
    MAXVAL    = std::numeric_limits<decltype(COUNT)>::max()
};

MAXVAL = 2147483647

  • 2
    whatever your answer is ok it would be better to improve it by adding some description. Please follow the [link](https://stackoverflow.com/help/how-to-answer) to know how. – Yuriy Tsarkov Nov 21 '18 at 09:59