【问题标题】:using enum says invalid conversion from 'int' to 'type'使用枚举表示从“int”到“type”的无效转换
【发布时间】:2012-01-02 17:49:23
【问题描述】:

在我的课堂上,我定义了一个这样的枚举:

class myClass 
{
 public:
    enum access {
      forL,
      forM,
      forA
    };
    typedef access AccessType;
    AccessType aType;
};

后来定义了一个这样的对象:

myClass ob;
ob->aType = 0;

但是我得到了这个错误:

错误:从“int”到“myClass::AccessType {aka myClass::access}”的无效转换 [-fpermissive]

枚举字段不映射到整数吗?

【问题讨论】:

标签: c++ enums


【解决方案1】:

不,它们存储为整数,但它们是不同的类型(例如,您甚至可以基于枚举类型重载)。您必须显式转换:

myClass ob;
ob->aType = (myClass::AccessType)0;

或者更好地编写枚举的相应命名值:

myClass ob;
ob->aType = myClass::forL;

或者,如果您想将枚举仅用作一组整数常量,请更改字段的类型:

class myClass 
{
 public:
    enum {
      forL,
      forM,
      forA
    };
    int aType; // just stores numbers
};

从 enum 到 int 的转换是隐式的。

【讨论】:

  • 对象是在另一个文件中创建的。所以它不识别'forL'。
  • @mahmood:糟糕,您必须使用myClass:: 对其进行限定。
  • 我写了 ob->aType=myClass::access::forL; 但它说 'myClass::access' 不是类或命名空间
  • 我建议为此使用适当的 C++ 演员:auto exampleEnum = static_cast<MyClass::AccessType>(exampleInt);
【解决方案2】:

枚举成员由整数值支持,但没有从整数到枚举类型的隐式转换。如果你真的想这样写,你需要使用显式转换:

ob->aType = static_cast<myClass::access>(0);

【讨论】:

  • 这是一个可移植的解决方案(我的意思是将来的编译器警告)?
  • 只要指定的整数在枚举的有效范围内,任何符合标准的编译器都应该根据 C++ 规范的 7.2.10 允许这样做:“算术或枚举类型的表达式可以显式转换为枚举类型。如果在枚举类型的枚举值范围内,则该值不变;否则生成的枚举值未指定。"
【解决方案3】:

您不能从 int -> enum 进行隐式转换,因为在编译时无法知道转换是否有效。

可以以另一种方式进行隐式转换,因此您可以(如果您愿意)这样做:

int foo = forL;

【讨论】:

    【解决方案4】:

    我也遇到了同样的问题。 我必须从我在 xml 文件中读取的内容初始化一个对象,并且可以肯定的是,我无法控制该文件可能发生的情况。

    构造函数有一个枚举作为参数:

    enum status_t { NOT_STARTED, STARTED, DONE };
    MyObject::MyObject(int id, status_t status) : m_id(id), m_status(status){}
    

    所以在解析 Xml 时,我必须强制转换它。我更喜欢在构造函数中处理强制转换,这样其他类就不必知道哪个是有效的枚举。

    MyObject::MyObject(int id, int status) : m_id(id){
        m_status = status_t(status);
    }
    

    但无法确定来自 xml 的值是否在正确的范围内。

    这是我提供的解决方案:

    MyObject::MyObject(int id, int status) : m_id(id){
        switch(status){
            case NOT_STARTED:
            case STARTED:
            case DONE:
                m_status=status_t(status);
                break;
            default:
                m_status=NOT_STARTED;
                break;
        }
    }
    

    这是一个实现选择,在数据不一致的情况下强制使用默认值。人们可能更喜欢抛出异常,在我的情况下它会这样做。

    【讨论】:

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