如何以通用方式从std :: istream读取枚举 [英] How to read enums from a std::istream in a generic fashion

查看:192
本文介绍了如何以通用方式从std :: istream读取枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

从流到枚举类型的输入


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



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

 枚举enSide {
eLeft,
eRight
};

枚举enType {
eConUndefined,
eConRoom
};

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

MyClass(){}

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

不幸的是,直接读入枚举值不可能(没有模板为>>)。



因此,我创建了一个帮助类:

 模板< class ENUM> 
class ScanTo {
public:
friend std :: istream&运算符>>(std :: istream& in,ScanTo< ENUM>& eval){
unsigned int val;
in>> VAL;
eval.mrEnum = static_cast< ENUM>(val);
返回;
}

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

private:
ENUM& mrEnum;
};

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

  friend std :: istream&运算符>>(std :: istream& in,MyClass& val){
ScanTo< enSide> scanside(val.mSide);
ScanTo< enType> scantype(val.mType);
in>>扫描>> scantype>> val.mTargetId;
返回;
}

这已经不远于我想要的,但仍然需要两个助手类,不能写为临时类:

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

不编译(gcc 4.43)如在评论中指出的那样,禁止非暂时的引用。


所以这里有一个问题:



这样做可以轻松完成吗?



解决方案

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

  template < class T> 
std :: istream&运算符>>(std :: istream& is,T&)
{
int i;
是>>一世;
t =(T)i;
return is;
}

这使得



<$ >>中的p $ p> val.mSide>> val.mType>> val.mTargetId;

可能。


Possible Duplicate:
Input from stream to enum type

I have several classes with different enums as class members and I want to read the classes from a stream.

The following code shows an exemplary class:

  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; 
  };

Unfortunately this does not work since direct reading into an enum Value is not possible (no template for >>).

Thus I created a helper class:

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;    
};

Now I can write the code for reading MyClass as follows:

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;      
}

This is already not far from what I wanted but still needs two indirections over the helper class, which cannot be written as temporarys:

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

does not compile (gcc 4.43), because a non const reference to a temporary is forbidden as pointed out in the comments.

So here comes the question:

Can this be done easier without resorting to some temporaries and templates as done above?

解决方案

I think you may write a helper function template:

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

which makes

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

possible.

这篇关于如何以通用方式从std :: istream读取枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆