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
Dereferencing One Past the End Pointer to Array Type
Why C++11 Compiler Support Still Requires a Flag
Appending Std::Vector to Itself, Undefined Behavior
When Does an Incomplete Type Error Occur in C++
Auto Keyword Behavior with References
Access to Method Pointer to Protected Method
Using Sendmessage to Send Wm_Close to Another Process
Questions Regarding C++ Non-Pod Unions
Are Lambdas Inlined Like Functions in C++
Problems with Scanf("%D\N",&I)
How to Implement Interfaces in C++
Defining Operator< for a Struct
Is 'Volatile' Needed in This Multi-Threaded C++ Code
How to Log Stack Frames with Windows X64
Specifying a Concept for a Type That Has a Member Function Template Using Concepts Lite