【问题标题】:"enum - invalid conversion from int" in class类中的“枚举 - 从 int 的无效转换”
【发布时间】:2013-10-13 01:33:29
【问题描述】:

我在将方法 args 放入我的班级时遇到问题:

class A {
  public:
    enum Mode {ModeA, ModeB, ModeC};

    ... // other methods, constructor etc

    void setMode(Mode m) {
      mMode = m;
    }

  private:
    Mode mMode;
}

int main(int argc, char **argv) {
  A a;
  a.setMode(A::ModeA | A::ModeC );

  return 0;
}

问题,我得到一个 C++ 编译器错误invalid vconversion from int to A::Mode, 我不明白,为什么我不能连接到枚举值?我需要在我的 代码,所以任何解决这个问题的帮助都会非常好。

【问题讨论】:

  • C++ 中的枚举不应该被连接,因为结果不再是枚举类型。
  • @Ashalynd 我同意,所有的答案似乎都忽略了这个操作实际上会导致信息丢失的观点。如果ModeA==0(默认情况下应该如此),则无法区分ModeCModeA | ModeC。我不建议使用枚举来存储标志。您可以手动列出枚举中的各个标志名称(手动分配 0x1、0x2、0x4、0x8 等),但存储组合应在位域、基础类型或类似内容中完成。
  • C++ 中的枚举支持(我敢说明确地支持)位标志,参见this question
  • @DyP 仅当枚举值手动设置为不冲突时。我只是认为有一个Mode 类型的成员可能实际上具有不等于任何单个枚举值的值,但我认为您的观点是标准实际上并没有区分在基础类型或枚举类型。得分。
  • @PeterT 我同意enum 并不完美,但范围枚举比std::bitset 或底层类型更安全。 (更好的解决方案可能是将 std::bitset 包装在不透明的 typedef 中,但这也需要更多的工作。)

标签: c++ enums


【解决方案1】:

operator| 对两个枚举的结果默认不是一个枚举。在你的课之后,添加如下内容:

A::Mode operator|( A::Mode a, A::Mode b )
{
    return A::Mode( int( a ) | int( b ) );
}

如果您的标准库支持它,以下是更多的未来证明,因为转换为 int 并不总是正确的:

A::Mode operator|( A::Mode a, A::Mode b )
{
    typedef std::underlying_type< A::Mode >::type UL;
    return A::Mode( static_cast< UL >( a ) | static_cast< UL >( b ) );
}

与其他答案不同,您只需添加一次(到正确的位置),所有用途都会自动覆盖。

【讨论】:

  • @DyP - 需要显式转换;没有它,运算符内部的a | b 只会再次调用运算符。
  • @DyP 在你写评论之前我已经编辑了答案:) 另外:return A::Mode(a|b); 会将编译器发送到无限递归。
  • 嗯,使用运算符我得到一个新的编译器错误:“运算符 A::Mode 只接受一个参数”
  • @PeteBecker Unary + 通过积分提升来解决问题(请参阅更新的评论)。
【解决方案2】:

也许你需要这个:

a.setMode( (A::Mode) (A::ModeA | A::ModeC ));

A::ModeA | A::ModeC 生成一个int,所以再次将其转换为A::Mode

【讨论】:

  • @AndreasBf 那么你可能做错了,或者发布了错误的代码,请参阅here
  • 好的,这样就可以了 - 忘记了铸造枚举值周围的大括号。
【解决方案3】:

enum 的基础类型在这种情况下可能是 int,并且您的编译器不能依赖使用 |(按位或)构造的标志作为此枚举的有效值。

但是,您知道结果将是此枚举的有效值,因此您可以这样做:

A::Mode newMode = (A::Mode) (A::ModeA | A::ModeC);
a.setMode(newMode);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多