#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;
}

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

其他回答

正如许多人所说,没有办法在不增加开销和太多复杂性的情况下自动转换,但是如果在某个场景中要多使用一些强制转换,则可以通过使用lambdas来减少输入并使其看起来更好。这将增加一些函数调用开销,但与下面看到的长static_cast字符串相比,将使代码更具可读性。这可能不适用于项目范围,但只适用于类范围。

#include <bitset>
#include <vector>

enum class Flags { ......, Total };
std::bitset<static_cast<unsigned int>(Total)> MaskVar;
std::vector<Flags> NewFlags;

-----------
auto scui = [](Flags a){return static_cast<unsigned int>(a); };

for (auto const& it : NewFlags)
{
    switch (it)
    {
    case Flags::Horizontal:
        MaskVar.set(scui(Flags::Horizontal));
        MaskVar.reset(scui(Flags::Vertical)); break;
    case Flags::Vertical:
        MaskVar.set(scui(Flags::Vertical));
        MaskVar.reset(scui(Flags::Horizontal)); break;

   case Flags::LongText:
        MaskVar.set(scui(Flags::LongText));
        MaskVar.reset(scui(Flags::ShorTText)); break;
    case Flags::ShorTText:
        MaskVar.set(scui(Flags::ShorTText));
        MaskVar.reset(scui(Flags::LongText)); break;

    case Flags::ShowHeading:
        MaskVar.set(scui(Flags::ShowHeading));
        MaskVar.reset(scui(Flags::NoShowHeading)); break;
    case Flags::NoShowHeading:
        MaskVar.set(scui(Flags::NoShowHeading));
        MaskVar.reset(scui(Flags::ShowHeading)); break;

    default:
        break;
    }
}

c++委员会向前迈出了一步(将枚举范围从全局命名空间中排除),又后退了五十步(没有枚举类型衰减为整数)。遗憾的是,如果您需要以任何非符号的方式获取枚举的值,枚举类是不可用的。

最好的解决方案是根本不使用它,而是自己使用名称空间或结构来确定枚举的范围。出于这个目的,它们是可以互换的。当引用枚举类型本身时,您将需要输入一些额外的内容,但这种情况可能不会经常发生。

struct TextureUploadFormat {
    enum Type : uint32 {
        r,
        rg,
        rgb,
        rgba,
        __count
    };
};

// must use ::Type, which is the extra typing with this method; beats all the static_cast<>()
uint32 getFormatStride(TextureUploadFormat::Type format){
    const uint32 formatStride[TextureUploadFormat::__count] = {
        1,
        2,
        3,
        4
    };
    return formatStride[format]; // decays without complaint
}

不。没有自然的方法。

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

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

#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;
}

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

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

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;
}