【问题标题】:Enums are implemented internally as integers. Then why does this give an error?枚举在内部实现为整数。那为什么这会出错?
【发布时间】:2016-02-23 06:30:14
【问题描述】:

代码是:

//正确

enum StudentNames
{
KENNY, // 0
KYLE, // 1
STAN, // 2
BUTTERS, // 3
CARTMAN, // 4
WENDY, // 5
MAX_STUDENTS // 6
};

int main()
{
int testScores[MAX_STUDENTS]; // allocate 6 integers
testScores[STAN] = 76; // still works

return 0;
}

//不正确:给出编译时错误

enum class StudentNames
{
KENNY, // 0
KYLE, // 1
STAN, // 2
BUTTERS, // 3
CARTMAN, // 4
WENDY, // 5
MAX_STUDENTS // 6
};

int main()
{
int testScores[StudentNames::MAX_STUDENTS]; // allocate 6 integers
testScores[StudentNames::STAN] = 76;
}

然后又修正为:

namespace StudentNames
{
enum StudentNames
{
    KENNY, // 0
    KYLE, // 1
    STAN, // 2
    BUTTERS, // 3
    CARTMAN, // 4
    WENDY, // 5
    MAX_STUDENTS // 6
    };
 }

int main()
{
int testScores[StudentNames::MAX_STUDENTS]; // allocate 6 integers
testScores[StudentNames::STAN] = 76;
}

因为,枚举在内部被实现为整数。为什么第二种情况会报错?

添加命名空间如何纠正它?

【问题讨论】:

  • 我没有使用命名空间 StudentNames
  • 这段代码我还没写。来自 learncpp.com @Ajay。
  • 嗯,请阅读 rici 的回答,据我所知,我认为他所说的是正确的。

标签: c++ c++11 enums integer


【解决方案1】:

enum classenum 不同。

如果你有一个enum class,那么你的值不是int 类型的(尽管它们有一个整数表示)。您不能将它们隐式转换为任何其他类型,甚至不能转换为另一个 enum。这是好事;它允许您定义类型安全的枚举。 (如果要将它们用作int,则可以使用显式转换。)

所以不是引入命名空间使第二个编译。这是enum 声明中缺少class

如果您真的想将enum class 的值用作ints,则需要显式转换:

int main() {
  int testScores[int(StudentNames::MAX_STUDENTS)]; // allocate 6 integers
  testScores[int(StudentNames::STAN)] = 76;
  // ...
}

但我不建议使用该代码,因为enum class 的全部意义在于表明枚举值不应用作整数。

(进行转换是有原因的,但应该很少见。例如,虽然您可以使用由enum class 索引的std::map,但效率会有点低。另一方面,典型的enum class 的成员太少,效率低下可能不如清晰度重要。请注意,您不能使用 std::unordered_map,因为虽然 enum class 的值具有可比性,但它们不可散列。)

【讨论】:

  • 您通常应该避免使用 C 样式转换。此处使用的正确演员表是 static_cast<int>()
  • @JesperJuhl:我没有使用 C 风格的演员表。根据 5.2.3,我以函数形式使用了显式类型转换。 C 风格的演员表有不同的括号。确实,static_cast<int> 可以工作,但 int 构造函数是完全有效的 C++,我不明白为什么在这种用法中会出现问题。
  • @JesperJuhl:另一方面,我认为我并没有充分阻止这个成语。通常,您根本不应该将enum class 值转换为ints。我在答案中添加了该观察结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
相关资源
最近更新 更多