从流输入到枚举类型

时间:2011-04-12 10:28:04

标签: c++ enums istream

如何从流输入到枚举类型?

我可以这样做

unsigned int sex = 0;
stream >> sex;
student.m_bio.sex = static_cast<Sex>(sex);

否则?

3 个答案:

答案 0 :(得分:13)

inline std::istream & operator>>(std::istream & str, Sex & v) {
  unsigned int sex = 0;
  if (str >> sex)
    v = static_cast<Sex>(sex);
  return str;
}

如果您想确保该值有效,您可以执行以下操作:

enum Sex {
    Male,
    Female,
    Sex_COUNT
};

inline std::istream & operator>>(std::istream & str, Sex & v) {
  unsigned int sex = 0;
  if (!(str >> sex))
    return str;
  if (sex >= Sex_COUNT) {
    str.setstate(str.rdstate() | std::ios::failbit);
    return str;
  }
  v = static_cast<Sex>(sex);
  return str;
}

答案 1 :(得分:3)

这个问题在这里以更一般的形式提出:How to read enums from a std::istream in a generic fashion。 OP几乎有一个可行的解决方案;他只是遇到了const的问题,以及一些不必要的尖括号。以下是充实的工作解决方案:

#include <iostream>
#include <type_traits>

enum enSide { eLeft, eRight };
enum enType { eConUndefined, eConRoom };

template<typename Enum>
class EnumReader
{
    Enum& e_;

    friend std::istream& operator>>(std::istream& in, const EnumReader& val) {
      typename std::underlying_type<Enum>::type asInt;
      if (in >> asInt) val.e_ = static_cast<Enum>(asInt);
      return in;
    }
  public:
    EnumReader(Enum& e) : e_(e) {}
};

template<typename Enum>
EnumReader<Enum> read_enum(Enum& e)
{
    return EnumReader<Enum>(e);
}

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

read_enum函数模板在此处与标准库中的std::make_pairstd::make_shared具有相同的用途:它可以让我们省去尖括号。你也可以写in >> EnumReader<enSide>(val.mSide) >> EnumReader<enType>(val.mType),但这更像打字(双关语)。

据称,一些供应商的标准库仍然从std::underlying_type标题中丢失<type_traits>。如果您有其中一个不完整的库,则可以使用How to know underlying type of class enum?中列出的解决方法之一。

答案 2 :(得分:0)

这不是很漂亮,但应该这样做

stream >>  reinterpret_cast<std::underlying_type<Sex>::type &>(student.m_bio.sex);

干杯, CC