如何自动将强类型枚举转换为 int?

新手上路,请多包涵
#include <iostream>

struct a {
  enum LOCAL_A { A1, A2 };
};
enum class b { B1, B2 };

int foo(int input) { return input; }

int main(void) {
  std::cout << foo(a::A1) << std::endl;
  std::cout << foo(static_cast<int>(b::B2)) << std::endl;
}

a::LOCAL_A 是强类型枚举试图实现的,但有一个小的区别:普通枚举可以转换为整数类型,而强类型枚举在没有强制转换的情况下无法做到。

那么,有没有一种方法可以将强类型枚举值转换为整数类型而无需强制转换?如果是,如何?

原文由 BЈовић 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.2k
2 个回答

强类型枚举旨在解决多个问题,而不仅仅是您在问题中提到的范围问题:

  1. 提供类型安全,从而通过整数提升消除到整数的隐式转换。
  2. 指定基础类型。
  3. 提供强有力的范围界定。

因此,不可能将强类型枚举隐式转换为整数,甚至是其底层类型——这就是想法。所以你必须使用 static_cast 来明确转换。

如果您唯一的问题是作用域,并且您确实希望对整数进行隐式提升,那么您最好使用非强类型枚举及其声明的结构范围。

原文由 user405725 发布,翻译遵循 CC BY-SA 4.0 许可协议

概括

问题:

有没有办法将强类型枚举值转换为整数类型而无需强制转换?如果是,如何?

回答:

不,那里没有。强类型枚举不能在没有显式转换的情况下转换为整数。然而,弱枚举可以,因为它们会被自动隐式转换。因此,如果您想自动隐式转换为 int,请考虑改用 C 风格的弱枚举(请参阅下面的“进一步介绍”部分中的更多内容)。

从这里(强调添加): https://en.cppreference.com/w/cpp/language/enum –> 在“Scoped enumerations”部分下:

没有从 作用域枚举 器 [AKA: “strong enum”] 的值到整数类型的隐式转换,尽管 static_cast 可用于获取枚举器的数值。

更进一步:C++ 中 _弱_(C 风格)与 _强_(C++ enum class )枚举类型的讨论

在 C++ 中有 两种类型的枚举:

  1. “unscoped”、“regular”、“weak”、“weakly typed”或“C-style”枚举,以及
  2. “作用域”、“强”、“强类型”、“枚举类”或“C++ 风格”枚举。

“作用域”枚举或“强”枚举提供了超出“常规”枚举所提供的两个额外“功能”。

范围枚举:

  1. 不允许从枚举类型隐式转换为整数类型(所以你 不能 隐式地 做你想做的事!),和
  2. 他们“限定”枚举,以便您必须通过枚举类型名称访问枚举。

1. 枚举类示例(仅在 C++ 中可用):

 // enum class (AKA: "strong" or "scoped" enum)
enum class my_enum
{
    A = 0,
    B,
    C,
};

my_enum e = my_enum::A; // scoped through `my_enum::`
e = my_enum::B;

// NOT ALLOWED!:
//   error: cannot convert ‘my_enum’ to ‘int’ in initialization
// int i = e;

// But explicit casting works just fine!:
int i1 = static_cast<int>(e); // explicit C++-style cast
int i2 = (int)e;              // explicit C-style cast

第一个“功能”实际上可能是您 想要的东西,在这种情况下,您只需要使用常规的 C 样式枚举来代替!好消息是:您仍然可以像在 C 中所做的那样,通过简单地在枚举类型名称前加上枚举类型名称来为枚举“范围”或“命名空间”,如下所示:

2. 常规枚举示例(在 C 和 C++ 中均可用):

 // regular enum (AKA: "weak" or "C-style" enum)
enum my_enum
{
    // C-style-scoped through the `MY_ENUM_` prefix
    MY_ENUM_A = 0,
    MY_ENUM_B,
    MY_ENUM_C,
};

my_enum e = MY_ENUM_A; // scoped through `MY_ENUM_`
e = MY_ENUM_B;

// This works fine!
int i = e;

请注意,只需将 MY_ENUM_ “范围”添加到每个枚举的前面,您仍然可以获得“范围”的好处!

3. 常规枚举和枚举类一起使用:

在此处测试代码: https ://onlinegdb.com/BkWGqlqz_。

主.cpp

 #include <iostream>
#include <stdio.h>

// enum class (AKA: "strong" or "scoped" enum [available only in C++, not C])
enum class my_enum
{
    A = 0,
    B,
    C,
};

// regular enum (AKA: "weak" or "C-style" enum [available in BOTH C and C++])
enum my_enum2
{
    MY_ENUM_A = 0,
    MY_ENUM_B,
    MY_ENUM_C,
};

int main()
{
    printf("Hello World\n");

    // 1) scoped enum

    my_enum e = my_enum::A; // scoped through `my_enum::`
    e = my_enum::B;

    // IMPLICIT CASTING TO INT IS NOT ALLOWED!
    // int i = e; // "error: cannot convert ‘my_enum’ to ‘int’ in initialization"
    // But this explicit C++-style cast works fine:
    int i1 = static_cast<int>(e);
    // This explicit C-style cast works fine too, and is easier to read
    int i2 = (int)e;


    // 2) regular enum

    my_enum2 e2 = MY_ENUM_A; // scoped through `MY_ENUM_`
    e2 = MY_ENUM_B;

    // This implicit cast works fine / IS allowed on C-style enums!
    int i3 = e2;
    // These explicit casts are also fine, but explicit casting is NOT
    // required for regular enums.
    int i4 = static_cast<int>(e2); // explicit C++-style cast
    int i5 = (int)e2;              // explicit C-style cast

    return 0;
}

4.如何迭代枚举:

  1. *****[我的回答] 如何迭代 1. 弱类型 C 风格 和 2. 范围强类型 C++ enum class 枚举的完整示例: 我如何迭代枚举?
  2. [我的问答] 在 C++ 中迭代枚举类的常用方法是什么?

原文由 Gabriel Staples 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题