C++ 为什么int类型的枚举类值不能用作int
我想将一个旧式的enum更改为enum class:int,因为它有自己的作用域 但是编译器抱怨在整数算术中使用这些值。 但是为什么呢?因为枚举是显式类型化为int的 例如:C++ 为什么int类型的枚举类值不能用作int,c++,enum-class,C++,Enum Class,我想将一个旧式的enum更改为enum class:int,因为它有自己的作用域 但是编译器抱怨在整数算术中使用这些值。 但是为什么呢?因为枚举是显式类型化为int的 例如: enum class MsgType : int { Output = 1, Input = 2, Debug = 3 }; enum class MsgSender : int { A = 1, B = 2, C = 3 }; // later
enum class MsgType : int {
Output = 1,
Input = 2,
Debug = 3
};
enum class MsgSender : int {
A = 1,
B = 2,
C = 3
};
// later in code
int id = (MsgType::Input << 16) + (MsgSender::A);
产生
错误C2678:二进制',这是功能。作用域枚举不能隐式转换为整数,因此不能使用它们代替整数。它们是强类型的设计。如果需要隐式转换,请使用非范围枚举
enum MsgType : int {
Output = 1,
Input = 2,
Debug = 3
};
enum MsgSender : int {
A = 1,
B = 2,
C = 3
};
基础类型的作用域和规范是正交的
或者,如果只希望定义某些操作,而枚举通常保持强类型,则可以重载相应的运算符来完成此操作
int operator<<(MsgType, int); // etc
但是如果我不希望它们是可转换的,为什么我要将类型指定为int
确保一定的布局。遵循特定的ABI。允许向前声明类型。类型安全性是使用新的作用域枚举的主要原因可能名称有点误导。如果您只需要一个作用域为且可以隐式转换为整数的枚举,则可以将其包装在结构或命名空间中:
struct MsgSender {
enum Values {
A = 1,
B = 2,
C = 3
};
};
缺点是类型现在是MsgSender::Values,但值是MsgSender::A等
对于作用域枚举,必须对进行静态转换才能获得整数。可以通过静态转换显式转换它们
int id = (static_cast<uint32_t>(MsgType::Input) << 16) + (static_cast<uint32_t>(MsgSender::A)) ;
不能将c++11作用域枚举直接用作int,但可以将其转换为int 主要是由于类型安全原因,非作用域枚举可以在枚举内泄漏名称,而作用域枚举没有泄漏名称的风险,名称只能在枚举内可见 <> C++中有2种枚举形式, C++98样式非范围枚举: 枚举颜色{红、绿、黄};, 可以隐式转换为int C++11作用域枚举:枚举类{Red,Green,Yellow};, 不能隐式转换为int,只能使用强制转换转换为其他类型,如static\u castmy\u color 与非作用域枚举相比,作用域枚举有3个优点: 减少污染; 强型安全; 作用域枚举可以向前声明,非作用域枚举需要额外的工作才能向前声明; 同时,非作用域枚举比作用域枚举更灵活 作用域枚举和非作用域枚举都支持基础类型的规范,作用域枚举的默认基础类型为int。非作用域枚举没有默认基础类型,它依赖于编译器,根据值的范围,可以是char或int 枚举类颜色:std::uint8{Red,Green,Yellow};//定义 枚举颜色:std::uint8{Red,Green,Yellow};//远期申报 只有在声明指定了基础类型时,才能向前声明非作用域枚举 实际上,更喜欢作用域枚举而不是非作用域枚举
<>参见Scott Meyers的《现代C++》,第10项:比较范围内的枚举到非作用域枚举。在移位之前,你试过抛出吗?枚举上可能没有移位运算符。因为它仍然是一个类,而不是一个int。这就是枚举类的要点,它是一个专用类型,不仅仅是整数的别名。但是,如果您切换到类型安全的枚举并期望它不是类型安全的,这似乎是不合逻辑的。这就是新的和旧的主要区别enums@UnholySheep我想将枚举值与对象进行更多的比较,因为它与对象一样使用。在这个例子中,一个从intYes派生的类的对象,语法是类似的。但不,这并不意味着相同。很不幸,但没什么新奇的。嗨,对不起我的错误,我的第四项不正确。我修改了它。