3

可能重复:
从流输入到枚举类型

我有几个具有不同枚举的类作为类成员,我想从流中读取这些类。

以下代码显示了一个示例类:

  enum enSide{
    eLeft,
    eRight
  };

  enum enType{
    eConUndefined,
    eConRoom    
  };

  class MyClass{
    public:
      friend std::istream& operator>>(std::istream& in, MyClass& val) {
        in >> val.mSide >> val.mType >> val.mTargetId;        
        return in;      
      }

      MyClass(){}

    private:
      enSide mSide;
      enType mType;
      int mTargetId; 
  };

不幸的是,这不起作用,因为无法直接读取enum值(>> 没有模板)。

因此我创建了一个辅助类:

template<class ENUM>
class ScanTo{
  public:
    friend std::istream& operator>>(std::istream& in, ScanTo<ENUM>& eval) {
      unsigned int val;
      in >> val;
      eval.mrEnum = static_cast<ENUM>(val);
      return in;      
    }

    ScanTo(ENUM& eRef):mrEnum(eRef){}

  private:
    ENUM& mrEnum;    
};

现在我可以编写MyClass如下代码进行阅读:

friend std::istream& operator>>(std::istream& in, MyClass& val) {
  ScanTo<enSide> scanside(val.mSide);
  ScanTo<enType> scantype(val.mType);
  in >> scanside >> scantype >> val.mTargetId;        
  return in;      
}

这已经离我想要的不远了,但仍然需要对辅助类进行两个间接处理,不能将其写为临时对象:

friend std::istream& operator>>(std::istream& in, MyClass& val) {
 in >>  ScanTo<enSide>(val.mSide)>> ScanTo<enType>(val.mType) >> val.mTargetId;        
 return in;      
}

不编译 (gcc 4.43),因为正如评论中指出的那样,禁止对临时对象进行非 const 引用。

那么问题来了:

如果不使用上面所做的一些临时工具和模板,这是否可以更轻松地完成?

4

2 回答 2

1

我想你可以写一个辅助函数模板:

template <class T>
std::istream& operator >>(std::istream& is, T& t)
{
    int i;
    is >> i;
    t = (T)i;
    return is;
}

这使得

in >> val.mSide >> val.mType >> val.mTargetId;

可能的。

于 2012-06-24T16:06:13.047 回答
0

您最好的选择是将您的数据成员定义为int,并使用类型安全访问器来设置和检索它们。

class MyClass{
  public:
    friend std::istream& operator>>(std::istream& in, MyClass& val) {
      in >> val.mSide >> val.mType >> val.mTargetId;        
      return in;      
    }

    MyClass(){}

    enSide side () const { return static_cast<enSide>(mSide); }
    void side (enSide v) { mSide = v; }

    enType type () const { return static_cast<enType>(mType); }
    void type (enType v) { mType = v; }

    int targetId () const { return mTargetId; }
    void targetId (int v) { mTargetId = v; }

  private:
    int mSide;
    int mType;
    int mTargetId; 
};

这可以避免您想要的临时工。

于 2012-06-24T16:08:52.643 回答