【问题标题】:How to cast int to enum in C++?如何在 C++ 中将 int 转换为枚举?
【发布时间】:2012-07-12 06:25:00
【问题描述】:

如何在 C++ 中将 int 转换为枚举?

例如:

enum Test
{
    A, B
};

int a = 1;

如何将a 转换为类型Test::A

【问题讨论】:

  • link 请注意,int 是否匹配枚举类型的常量之一并不重要;类型转换总是非法的。
  • 我相信如果你想强制转换为 Test::A,int a 的值必须为 0,因为 Test::A 的隐含值为 0 而 Test::B 有一个隐含的值 1。除非专门为 Test::A 进行强制转换的事实不是重点......

标签: c++ casting enums


【解决方案1】:
int i = 1;
Test val = static_cast<Test>(i);

【讨论】:

  • auto val = static_cast(i); // C++11
  • @Mitch 在这种情况下使用auto 会得到什么?是否有任何性能改进?
  • 没有性能改进。如果您使用“auto”指定,编译器只会自动推断类型。如果您决定将来更改枚举名称,您将减少修改代码,因为编译器会自动推断出正确的类型名称。
  • @AydinÖzcan 现代 IDE 可以轻松重命名整个代码库中的任何内容。
  • 我想说比重构更容易的更大改进主要是针对具有长类型签名的东西:auto myptr = std::make_shared&lt;my::cool::type::class&gt;(1, 2, 3, 4, 5); 比指定 myptr 的完整类型要短得多,而右侧赋值清楚地表明了类型是什么。
【解决方案2】:
Test e = static_cast<Test>(1);

【讨论】:

  • MSDN:static_cast 运算符可以显式地将整数值转换为枚举类型。如果整数类型的值不在枚举值范围内,则生成的枚举值是未定义的。
  • @KirillKobelev 如果整数值可以由枚举的基础类型表示,那么生成的枚举必须具有该值。否则,生成的枚举值将是将表达式转换为枚举的基础类型所产生的任何值。如果 VC++ 做了一些不同的事情,那么我认为它是不符合标准的。
  • 如果枚举具有值 { 1,3,5 } 并且代码尝试从值 2 执行 ,则符合编译器应该做什么。这与 C-cast 有何不同?
  • @KirillKobelev 我没有使用 static_cast,因为它与 C 风格的转换有任何不同,我使用的是 static_cast,因为 C++ 转换在风格上优于 C 转换。
  • @KirillKobelev "if enum has values { 1,3,5 }" No. enumeration 类型不能仅限于这 3 种可能values: { 1,3,5 } 是 枚举数 (命名枚举值),而不是枚举本身。如果 1、3、5 是可能的 枚举 值,那么 2 也是。
【解决方案3】:

你的代码

enum Test
{
    A, B
}

int a = 1;

解决方案

Test castEnum = static_cast<Test>(a);

【讨论】:

  • 最好尽可能使用限制性最强的强制转换,并完全避免 C 风格的强制转换,从而为编译器提供检测错误的最佳机会。 static_cast 在这里会更好。
  • @Mike Seymour,问题是在这种情况下静态演员表与 C 演员表没有区别。它可以检测到什么错误以及如何检测???
  • @KirillKobelev:问题在于 C 风格的转换不明确。它可以等于static_cast,但也可以是const_cast,或者更糟的是reinterpret_cast,甚至是它们的组合。即使您现在知道它会降级什么,假设您稍后将a 更改为另一种类型,它也很可能是转换类型,而您却没有收到尽可能多的警告,您不希望这样。
  • @KillianDS "假设您稍后将 a 更改为另一种类型" 哪种类型?
  • 是的,要么是那些,要么是隐式转换(如果可用)。演员的意图更清楚了。
【解决方案4】:

衍生出最后的问题,“我如何将 a 转换为类型 Test::A”,而不是严格要求在其中有一个 cast,并迟到几年才回答,只是因为这个根据 C++11 标准,这似乎是一个流行的问题,没有其他人提到过替代方案:

5.2.9 静态转换

... 表达式 e 可以显式转换为类型 T 如果声明,则使用 static_cast&lt;T&gt;(e) 形式的 static_cast T t(e); 格式正确,对于某些发明的临时变量 t (8.5)。 这种显式转换的效果与执行 声明和初始化,然后使用临时 作为转换结果的变量。

因此,直接使用t(e) 形式也可以,您可能更喜欢它的简洁性:

auto result = Test(a);

【讨论】:

  • 此解决方案适用于编译器选项阻止 static_cast(语义检查)的情况。不是说它对我有意义,但仍然很整洁。
  • 这里提供的解决方案对我有用,但我也很好奇为什么Test result(a); 不起作用,当它看起来等效时。它会导致错误“无法使用'int'类型的左值初始化'Test'类型的变量”,这似乎正是所提供的解决方案所做的。
  • @BillHollings Test result(a); 看起来像一个构造函数调用类型为Test 的变量result,提供了一个参数a。因为Test 只是枚举类型,而不是类或结构,所以不能像构造函数那样调用它。但是Test(a) 是一种类型转换,所以它们不是等价的——(Test)a 也可以。
【解决方案5】:

Test castEnum = static_cast&lt;Test&gt;(a-1); 会将a 转换为A。如果不想子结构1,可以重新定义enum

enum Test
{
    A:1, B
};

在这种情况下,Test castEnum = static_cast&lt;Test&gt;(a); 可用于将a 转换为A

【讨论】:

    猜你喜欢
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    相关资源
    最近更新 更多