枚举类可以转换为基础类型吗?

edA*_*a-y 105 c++ c++11

有没有办法将enum class字段转换为基础类型?我认为这将是自动的,但显然不是.

enum class my_fields : unsigned { field = 1 };

unsigned a = my_fields::field;
Run Code Online (Sandbox Code Playgroud)

该任务被海湾合作委员会拒绝.error: cannot convert 'my_fields' to 'unsigned int' in assignment.

Naw*_*waz 171

我认为你可以使用std :: underlying_type来了解底层类型,然后使用cast:

#include <type_traits> //for std::underlying_type

typedef std::underlying_type<my_fields>::type utype;

utype a = static_cast<utype>(my_fields::field);
Run Code Online (Sandbox Code Playgroud)

有了这个,您不必假设基础类型,或者您不必在enum class类似的定义中提及它enum class my_fields : int { .... }.

你甚至可以编写一个通用的转换函数,它应该能够将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);
}
Run Code Online (Sandbox Code Playgroud)

然后使用它:

auto value = to_integral(my_fields::field);

auto redValue = to_integral(Color::Red);//where Color is an enum class!
Run Code Online (Sandbox Code Playgroud)

并且由于声明了函数constexpr,您可以在需要常量表达式的地方使用它:

int a[to_integral(my_fields::field)]; //declaring an array

std::array<int, to_integral(my_fields::field)> b; //better!
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 现在我们处于未来: `template &lt;typename T&gt; auto to_integral(T e) { return static_cast&lt;std::underlying_type_t&lt;T&gt;&gt;(e); }` (2认同)

And*_*owl 40

您无法隐式转换它,但可以进行显式转换:

enum class my_fields : unsigned { field = 1 };

// ...

unsigned x = my_fields::field; // ERROR!
unsigned x = static_cast<unsigned>(my_fields::field); // OK
Run Code Online (Sandbox Code Playgroud)

还要注意这样一个事实,即分号应该在你的枚举定义中的闭合大括号之后,而不是之前.


Sta*_*ker 12

使用 C++23,您最终将获得一个库函数:

std::to_underlying

它已经在 GCC 11、Clang 13 和 MSVC 19.30(又名 2022 17.0)的标准库中实现。

在您能够使用 C++23 之前,我建议您(重新)命名任何自定义实现并将to_underlying其放置在#if !defined(__cpp_lib_to_underlying) #endif块之间,该块是关联的功能测试宏。这样,当 C++23 可供您使用时,您可以在将来的某个时候简单地放弃代码。