#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是强类型enum试图实现的目标,但有一个小小的区别:普通enum可以转换为整数类型,而强类型enum如果没有强制转换就不能做到这一点。

那么,有没有一种方法可以将强类型枚举值转换为整数类型而不进行强制转换呢?如果是,怎么做?


当前回答

简单的回答是你不能像上面的帖子指出的那样。但对于我的情况,我只是不想让名称空间混乱,但仍然有隐式转换,所以我只是这样做:

#include <iostream>

using namespace std;

namespace Foo {
   enum Foo { bar, baz };
}

int main() {
   cout << Foo::bar << endl; // 0
   cout << Foo::baz << endl; // 1
   return 0;
}

命名空间增加了一层类型安全,而我不必静态地将任何枚举值强制转换为底层类型。

其他回答

不。没有自然的方法。

事实上,在c++ 11中使用强类型枚举类的动机之一是防止它们无声地转换为int。

总结

问题:

是否有一种方法将强类型枚举值转换为整数类型而不强制转换?如果是,怎么做?

答:

不,没有。如果没有显式强制转换,强类型枚举不能转换为整数。但是,弱枚举可以,因为它们将自动隐式强制转换。所以,如果你想自动隐式转换为int型,可以考虑使用c风格的弱enum(详见“进一步”一节)。

从这里(强调添加):https://en.cppreference.com/w/cpp/language/enum ->节下的“范围枚举”:

虽然可以使用static_cast来获得枚举数的数值,但没有从作用域枚举数[AKA: "strong enum"]的值到整型的隐式转换。

进一步:讨论c++中的弱(C风格)和强(c++ enum类)enum类型

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

“unscoped”,“regular”,“weak”,“弱类型”,或“c风格”枚举 "scoped", "strong", "强类型","枚举类",或" c++风格"枚举。

“作用域”枚举,或“强”枚举,除了“常规”枚举之外,还提供了两个额外的“特性”。

范围的枚举:

不允许从枚举类型隐式转换为整数类型(因此您不能隐式地做您想做的事情!),以及 它们“限定”枚举,因此您必须通过枚举类型名称访问枚举。

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风格enum即可!好处是:你仍然可以“作用域”或“命名空间”枚举,就像在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_。

main.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. 如何遍历枚举:

*****[我的回答]如何迭代的完整示例弱类型的c风格和2。作用域,强类型的c++枚举类枚举:如何遍历枚举? [我的问答]在c++中迭代枚举类的常用方法是什么?

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

提供类型安全,从而消除通过积分提升到整数的隐式转换。 指定基础类型。 提供强作用域。

因此,不可能隐式地将强类型枚举转换为整数,甚至是它的底层类型——这就是其思想。因此必须使用static_cast来显式地进行转换。

如果你唯一的问题是作用域,并且你真的想要隐式提升为整数,那么你最好使用非强类型enum和它声明的结构的作用域。

希望这能帮助到你或其他人

enum class EnumClass : int //set size for enum
{
    Zero, One, Two, Three, Four
};

union Union //This will allow us to convert
{
    EnumClass ec;
    int i;
};

int main()
{
using namespace std;

//convert from strongly typed enum to int

Union un2;
un2.ec = EnumClass::Three;

cout << "un2.i = " << un2.i << endl;

//convert from int to strongly typed enum
Union un;
un.i = 0; 

if(un.ec == EnumClass::Zero) cout << "True" << endl;

return 0;
}

简单的回答是你不能像上面的帖子指出的那样。但对于我的情况,我只是不想让名称空间混乱,但仍然有隐式转换,所以我只是这样做:

#include <iostream>

using namespace std;

namespace Foo {
   enum Foo { bar, baz };
}

int main() {
   cout << Foo::bar << endl; // 0
   cout << Foo::baz << endl; // 1
   return 0;
}

命名空间增加了一层类型安全,而我不必静态地将任何枚举值强制转换为底层类型。