简体   繁体   English

C ++枚举可以比较整数但不能从整数赋值?

[英]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. 保证MODE0MODE1NUM_MODES可转换为intenum的基础类型),但反之则不成立。 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. 简而言之,仅定义从enumint的隐式转换,而未定义相反的隐式转换。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM