Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I assign an unsigned integer to an enum in C++?

In a C++ library whose internals I'm rewriting I have some unsigned integer variables that I want to convert to enums:

enum InitType {
    INIT,
    NON_INIT
};

and I have a variable of this type:

InitType InitVar;

The library is called from another section that of the code whose variables are plain integers:

uint32_t UnsignedIntVar;

I want to assign the unsigned version that was passed from the caller to the libraries internal enum:

InitVar = UnsignedIntVar;

But the compiler doesn't like this:

error: invalid conversion from 'uint32_t' to 'InitType'

What is the cleanest way to perform this conversion?


Here are some ideas that I had:

If the enum has only two values, I can do it like this:

    InitVar = UnsignedIntVar ? Init : NonInit;

This is a lot of writing anytime I want to make such an assignment.

If it has more values, I can create a translation table:

InitType Uint2InitTypeConv = {INIT_0, INIT_1, INIT_2...};

Where INIT_x are just the names of the enums. Then I can translate using the table:

InitVar = Uint2InitTypeConv[UnsignedIntVar];

This seems pretty clean. However, I figure I should be able to overload operator= for this, but I can't seem to be get that right. That would easily encapsulate any other ugliness I can come up with.

like image 703
Nathan Fellman Avatar asked Dec 10 '22 04:12

Nathan Fellman


2 Answers

You can convert to enums explicitly:

InitType i = InitType(UnsignedIntvar);

If the integer doesn't have a value that corresponds to a known enum value, that is your problem.

A typical case where this is perfectly acceptable is a looping over enums:

enum ESomething { Default = 0, Something, SomeOtherThing };
for (int i = 0; i != 3; ++i)
{
  ESomething e = ESomething(i);
  // do something with "e"
}
like image 125
Kerrek SB Avatar answered Jan 15 '23 02:01

Kerrek SB


InitVar = UnsignedIntVar ? Init : NonInit;

This is a lot of writing anytime I want to make such an assignment.

Yes, but since the meaning of a uint32_t differs from that of your enum, I would do it anyway. As they say in the Python community, "explicit is better than implicit". I wouldn't do a cast, and the table approach suffers from the drawback that you'd have to enumerate all uint32_t values to get full coverage, which would be practically impossible.

Why not introduce a function with an appropriate name to do the conversion? Something like InitType init_type(uint32_t), implemented as a switch?

like image 36
Fred Foo Avatar answered Jan 15 '23 01:01

Fred Foo