[英]c++ enum can compare to integer but not assign from integer?
#include <iostream>
enum mode { MODE0=0, MODE1, NUM_MODES};
int main(int args, char ** argv) {
int i = 1;
std::cout << (i == MODE0 ? "true" : "false") << "\n";
std::cout << (i == MODE1 ? "true" : "false") << "\n";
mode test;
test = i; // error
}
Why is it that the comparison of i to enum values works fine, but I get compilation error when assigning mode test variable to an integer value? 为什么将i与枚举值进行比较可以正常工作,但是将模式测试变量分配给整数值时却出现编译错误?
enum.cc:10:8: error: invalid conversion from 'int' to 'mode' [-fpermissive]
enum.cc:10:8:错误:从'int'到'mode'的无效转换[-fpermissive]
My question is specifically about why comparison works and assignment doesn't (not how to fix my code) and it has received a couple of good explanations below. 我的问题专门是关于为什么比较有效且分配不起作用(不是如何修正我的代码),并且在下面收到了一些很好的解释。
MODE0
, MODE1
and NUM_MODES
are guaranteed to be convertible to int
(the underlying type of the enum
) but the reverse is not true. 保证
MODE0
, MODE1
和NUM_MODES
可转换为int
( enum
的基础类型),但反之则不成立。 Not all int
can be converted to mode
. 并非所有
int
都可以转换为mode
。 For example, what is the matching mode
for the int
42? 例如,
int
42的匹配mode
是什么? Simply put, only the implicit conversion from enum
to int
is defined, the opposite implicit conversion is not defined. 简而言之,仅定义从
enum
到int
的隐式转换,而未定义相反的隐式转换。
If you want to convert from int
to mode
you can preform a static_cast
to signal that you are taking the responsibility of ensuring that the value being converted is always legal to convert to mode
. 如果要从
int
转换为mode
,则可以执行static_cast
来表示您有责任确保要转换的值始终合法,可以转换为mode
。 Try 尝试
test = static_cast<mode>(i);
You can use strongly typed enumerations by adding the class
keyword to your enum
to prevent any implicit casts and to limit the scope of the enum
value names. 您可以通过向您的
enum
添加class
关键字来使用强类型的枚举,以防止任何隐式强制转换并限制enum
值名称的范围。 The definition would look like enum class mode { MODE0 = 0, MODE1, NUM_MODES };
该定义看起来像
enum class mode { MODE0 = 0, MODE1, NUM_MODES };
. 。 In this case, you must quality the
enum
value names, for example, you would need to use mode::MODE0
instead of MODE0
. 在这种情况下,您必须保证
enum
值名称的质量,例如,您将需要使用mode::MODE0
而不是MODE0
。 This has the advantage that it avoids name collisions. 这具有避免名称冲突的优点。
It's because there is a conversion from an enumerated type to int
but there is no conversion in the opposite direction. 这是因为存在从枚举类型到
int
转换,但没有相反的转换。 For the comparison, MODE0
gets promoted to int
. 为了进行比较,将
MODE0
提升为int
。 For the assignment, i
would have to be converted to mode
. 对于分配,
i
将不得不转换为mode
。
Look at it this way. 这样看。 When you do a comparison it doesn't matter if the
int
is not a valid possible value. 当您进行比较时,
int
是否不是有效的可能值并不重要。 If it is not then the comparison will fail and we can go on. 如果不是,则比较将失败,我们可以继续。 Now when we go and try to assign an
int
to an enum
you could assign to it a value that isn't mapped to the enum values. 现在,当我们尝试为一个
enum
分配一个int
,您可以为其分配一个未映射到该枚举值的值。 Since we don't want this implicitly happening the conversion is invalid. 由于我们不希望这种隐式发生,因此转换无效。 If you want to tell the compiler that it is okay, you know what you are doing, then you can cast it like:
如果您想告诉编译器还可以,那么您知道自己在做什么,然后可以将其强制转换为:
test = static_cast<mode>(i);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.