Generic Way to Cast Int to Enum in C++

Generic way to cast int to enum in C++

The obvious thing is to annotate your enum:

// generic code
#include <algorithm>

template <typename T>
struct enum_traits {};

template<typename T, size_t N>
T *endof(T (&ra)[N]) {
return ra + N;
}

template<typename T, typename ValType>
T check(ValType v) {
typedef enum_traits<T> traits;
const T *first = traits::enumerators;
const T *last = endof(traits::enumerators);
if (traits::sorted) { // probably premature optimization
if (std::binary_search(first, last, v)) return T(v);
} else if (std::find(first, last, v) != last) {
return T(v);
}
throw "exception";
}

// "enhanced" definition of enum
enum e {
x = 1,
y = 4,
z = 10,
};

template<>
struct enum_traits<e> {
static const e enumerators[];
static const bool sorted = true;
};
// must appear in only one TU,
// so if the above is in a header then it will need the array size
const e enum_traits<e>::enumerators[] = {x, y, z};

// usage
int main() {
e good = check<e>(1);
e bad = check<e>(2);
}

You need the array to be kept up to date with e, which is a nuisance if you're not the author of e. As Sjoerd says, it can probably be automated with any decent build system.

In any case, you're up against 7.2/6:

For an enumeration where emin is the
smallest enumerator and emax is the
largest, the values of the enumeration
are the values of the underlying type
in the range bmin to bmax, where bmin
and bmax are, respectively, the
smallest and largest values of the
smallest bit-field that can store emin
and emax. It is possible to define an
enumeration that has values not
defined by any of its enumerators.

So if you aren't the author of e, you may or may not have a guarantee that valid values of e actually appear in its definition.

How do I cast int to enum in C#?

From an int:

YourEnum foo = (YourEnum)yourInt;

From a string:

YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);

// The foo.ToString().Contains(",") check is necessary for
// enumerations marked with a [Flags] attribute.
if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(","))
{
throw new InvalidOperationException(
$"{yourString} is not an underlying value of the YourEnum enumeration."
);
}

From a number:

YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum), yourInt);

Cast Int to Generic Enum in C#

The simplest way I have found is to force the compiler's hand by adding a cast to object.

return (T)(object)i.Value;

Can not cast integer to Enum in Generic method

As a workaround, instead of (T)x.ToInteger() you should be able to do: (T)(object)x.ToInteger().

This involves boxing and unboxing the value but that most likely is not a significant performance issue here.

Cast int to enum

Either use:

   result = (T)Enum::ToObject(T::typeid, 0);

or the slightly "uglier":

   result = (T)(Object^)0;

How to cast a variable of an enum generic type to int and back

You may add IConvertible to generic constraint and use ToInt32 method, something like

class EnumWrapper<T>
where T : Enum, IConvertible
{
void DoSomething(T arg)
{
int a = arg.ToInt32(null);
}
}

Have a look at the Enum constraint for details. Also, as mentioned in comments, it isn't necessary that your enum is based on int type

Can I cast from a generic type to an enum in C#?

Like this:

return (T)(object)value;

How to cast my own enum type to generic enum type?

The simplest way to cast your custom enum type MyEnum to generic enum type TEnum is to use the next approach:

case MyEnum _: return (TEnum) (object) MyEnum.First;

Here are links to similar problems:

  • Value of type 'T' cannot be converted to
  • How do I cast a generic enum to int?
  • Cast Int to Generic Enum in C#

How do I cast a generic enum to int?

try this,

public void SetOptions<T>()
{
Type genericType = typeof(T);
if (genericType.IsEnum)
{
foreach (T obj in Enum.GetValues(genericType))
{
Enum test = Enum.Parse(typeof(T), obj.ToString()) as Enum;
int x = Convert.ToInt32(test); // x is the integer value of enum
..........
..........
}
}
}


Related Topics



Leave a reply



Submit