C++ 枚举类可以转换为底层类型吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14589417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can an enum class be converted to the underlying type?
提问by edA-qa mort-ora-y
Is there a way to convert an enum class
field to the underlying type? I thought this would be automatic, but apparently not.
有没有办法将enum class
字段转换为基础类型?我认为这会是自动的,但显然不是。
enum class my_fields : unsigned { field = 1 };
unsigned a = my_fields::field;
That assignment is being rejected by GCC. error: cannot convert 'my_fields' to 'unsigned int' in assignment
.
该任务被 GCC 拒绝。error: cannot convert 'my_fields' to 'unsigned int' in assignment
.
回答by Nawaz
I think you can use std::underlying_typeto know the underlying type, and then use cast:
我认为您可以使用std::underlying_type来了解底层类型,然后使用强制转换:
#include <type_traits> //for std::underlying_type
typedef std::underlying_type<my_fields>::type utype;
utype a = static_cast<utype>(my_fields::field);
With this, you don't have to assumethe underlying type, or you don't have to mention it in the definition of the enum class
like enum class my_fields : int { .... }
or so.
有了这个,您就不必假设底层类型,或者不必在enum class
诸如此类的定义中提及它enum class my_fields : int { .... }
。
You can even write a genericconvert function that should be able to convert anyenum class
to its underlying integraltype:
您甚至可以编写一个通用的convert 函数,它应该能够将any转换enum class
为它的底层整数类型:
template<typename E>
constexpr auto to_integral(E e) -> typename std::underlying_type<E>::type
{
return static_cast<typename std::underlying_type<E>::type>(e);
}
then use it:
然后使用它:
auto value = to_integral(my_fields::field);
auto redValue = to_integral(Color::Red);//where Color is an enum class!
And since the function is declared to be constexpr
, you can use it where constant expression is required:
并且由于函数被声明为constexpr
,您可以在需要常量表达式的地方使用它:
int a[to_integral(my_fields::field)]; //declaring an array
std::array<int, to_integral(my_fields::field)> b; //better!
回答by Andy Prowl
You cannot convert it implicitly, but an explicit cast is possible:
您不能隐式转换它,但可以进行显式转换:
enum class my_fields : unsigned { field = 1 };
// ...
unsigned x = my_fields::field; // ERROR!
unsigned x = static_cast<unsigned>(my_fields::field); // OK
Also mind the fact, that the semicolon should be afterthe closed curly brace in your enum's definition, not before.
还要注意一个事实,分号应该在枚举定义中的闭合花括号之后,而不是之前。
回答by James
I find the following function underlying_cast
useful when having to serialise enum values correctly.
我发现以下函数underlying_cast
在必须正确序列化枚举值时很有用。
namespace util
{
namespace detail
{
template <typename E>
using UnderlyingType = typename std::underlying_type<E>::type;
template <typename E>
using EnumTypesOnly = typename std::enable_if<std::is_enum<E>::value, E>::type;
} // namespace util.detail
template <typename E, typename = detail::EnumTypesOnly<E>>
constexpr detail::UnderlyingType<E> underlying_cast(E e) {
return static_cast<detail::UnderlyingType<E>>(e);
}
} // namespace util
enum SomeEnum : uint16_t { A, B };
void write(SomeEnum /*e*/) {
std::cout << "SomeEnum!\n";
}
void write(uint16_t /*v*/) {
std::cout << "uint16_t!\n";
}
int main(int argc, char* argv[]) {
SomeEnum e = B;
write(util::underlying_cast(e));
return 0;
}