#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如果没有强制转换就不能做到这一点。

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


当前回答

对于本地枚举类,这似乎是不可能的,但也许你可以用类来模拟枚举类:

在这种情况下,

enum class b
{
    B1,
    B2
};

相当于:

class b {
 private:
  int underlying;
 public:
  static constexpr int B1 = 0;
  static constexpr int B2 = 1;
  b(int v) : underlying(v) {}
  operator int() {
      return underlying;
  }
};

这在很大程度上相当于最初的enum类。你可以在返回类型为b的函数中直接返回b::B1 for。你可以用它来切换大小写,等等。

根据本例的精神,您可以使用模板(可能与其他东西一起使用)泛化和模拟枚举类语法定义的任何可能的对象。

其他回答

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

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 <cstdlib>
#include <cstdio>
#include <cstdint>

#include <type_traits>

namespace utils
{

namespace details
{

template< typename E >
using enable_enum_t = typename std::enable_if< std::is_enum<E>::value, 
                                               typename std::underlying_type<E>::type 
                                             >::type;

}   // namespace details


template< typename E >
constexpr inline details::enable_enum_t<E> underlying_value( E e )noexcept
{
    return static_cast< typename std::underlying_type<E>::type >( e );
}   


template< typename E , typename T>
constexpr inline typename std::enable_if< std::is_enum<E>::value &&
                                          std::is_integral<T>::value, E
                                         >::type 
 to_enum( T value ) noexcept 
 {
     return static_cast<E>( value );
 }

} // namespace utils




int main()
{
    enum class E{ a = 1, b = 3, c = 5 };

    constexpr auto a = utils::underlying_value(E::a);
    constexpr E    b = utils::to_enum<E>(5);
    constexpr auto bv = utils::underlying_value(b);

    printf("a = %d, b = %d", a,bv);
    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;
}

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

没有隐式转换(通过设计)的原因在其他答案中给出了。

我个人使用一元操作符+从枚举类转换到它们的底层类型:

template <typename T>
constexpr auto operator+(T e) noexcept
    -> std::enable_if_t<std::is_enum<T>::value, std::underlying_type_t<T>>
{
    return static_cast<std::underlying_type_t<T>>(e);
}

这给了相当小的“输入开销”:

std::cout << foo(+b::B2) << std::endl;

我实际上使用宏创建枚举和操作符函数在一个镜头。

#define UNSIGNED_ENUM_CLASS(name, ...) enum class name : unsigned { __VA_ARGS__ };\
inline constexpr unsigned operator+ (name const val) { return static_cast<unsigned>(val); }

正如其他人所说,你不能有隐式转换,那是设计的。

如果愿意,可以避免在强制转换中指定底层类型。

template <typename E>
constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept {
    return static_cast<typename std::underlying_type<E>::type>(e);
}

std::cout << foo(to_underlying(b::B2)) << std::endl;