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

これは私が望んでいたものから遠く離れていませんが、ヘルパー クラスに対して 2 つの間接化が必要であり、一時的なものとして書き込むことはできません。

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 に答える