#include <iostream>
typedef enum my_time {
day,
night
} my_time;
int main(){
// my_time t1 = 1; <-- will not compile
int t2 = night;
return 0;
}
在C++中,我如何能够将enum
值分配给int
值,而不是相反的方式呢?
当然,这都可以在C
中实现。
 ; 可以转换为int。 此表达式对指定的数据类型(int)和给定的值(night)进行显式转换。
int t2 = static_cast<int>(night)
隐式转换,或通常的转换,不是相互的。 类型a
可以转换为类型b
并不意味着b
可以转换为a
。
旧枚举(未限定范围的枚举)可以转换为integer,但不可能(隐式地)采用其他方式。 这就是它的定义。 详情请参阅:https://en.cppreference.com/W/cpp/language/enum
大致来说,enum
只是命名为常量,用于函数
void foo(my_time x);
传递任意的int
很可能是一个错误。 然而,a
void bar(int x);
可以对x
的特殊值使用枚举,但仍允许其他值:
enum bar_parameter { NONE, ONE, MORE, EVEN_MORE, SOME_OTHER_NAME };
bar(NONE);
bar(SOME_OTHER_NAME);
bar(42);
这个问题在C++11中已经被“修复”了,它使用了具有作用域的枚举,这些枚举不会隐式转换任何一种方式。
当然,这在C语言中都是可行的
这并不意味着C++背后的思想自动地认为它是一种期望的行为。 他们也不应该有这样的态度。 C++在类型方面遵循自己的哲学。 这并不是唯一一个有意识地决定比C更强类型的方面。这个有效的C代码片段在C++中是无效的
void *vptr = NULL;
int *iptr = vptr; // No implicit conversion from void* to T* in C++
在C++中,我怎样才能将枚举值赋给int值,而不是用另一种方式呢?
之所以这样做,是因为转换的一边不太容易出错。 允许枚举数成为整数不太可能打破程序员对整数值的任何假设。
枚举是一种新类型。 一些枚举的值被命名为。 对于大多数使用枚举的情况,我们确实希望将自己限制在那些命名的常量上。
即使枚举可以保存整数值,也不意味着该值是命名常量之一。 这很容易违反代码对其输入的假设。
// Precondition: e is one of the name values of Enum, under pain of UB
void frombulate_the_cpu(Enum e);
此函数记录其前提条件。 违反前提条件会导致可怕的问题,这就是UB通常的情况。 如果隐式转换在程序中的任何地方都是可能的,那么更有可能是我们无意中违反了前提条件。
C++适合于在编译时随时捕捉问题。 这被认为是有问题的。
如果程序员需要将整数转换为枚举,他们仍然可以通过强制转换来完成。 强制转换在代码库中非常突出。 它们需要一个有意识的决定来覆盖编译器的检查。 这是一件好事,因为当做一些潜在的不安全的事情时,人们应该充分意识到这一点。