【问题标题】:Input from stream to enum type从流输入到枚举类型
【发布时间】:2011-08-03 18:38:26
【问题描述】:

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

我可以这样做

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

不然呢?

【问题讨论】:

    标签: c++ enums istream


    【解决方案1】:
    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;
    }
    

    【讨论】:

    • 我想你的意思是v = static_cast&lt;Sex&gt;(sex);...也就是说,演员表的参数是sex,而不是v。 :D
    • 这个答案缺少return str;
    • @Konrad Rudolph:谢谢,已解决,现在我要去煮点咖啡了——看来我需要它:P
    • 可惜枚举没有is_valid 函数。
    • @edA-qa mort-ora-y:首先是谁在使用is_valid
    【解决方案2】:

    在此处以更一般的形式提出了这个问题: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 &gt;&gt; EnumReader&lt;enSide&gt;(val.mSide) &gt;&gt; EnumReader&lt;enType&gt;(val.mType),但那是更多的打字(双关语)。

    据称,一些供应商的标准库在其&lt;type_traits&gt; 标头中仍然缺少std::underlying_type。如果您有这些不完整的库之一,您可以使用How to know underlying type of class enum? 中列出的解决方法之一。

    【讨论】:

      【解决方案3】:

      这不漂亮,但应该这样做

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

      干杯, 抄送

      【讨论】:

        猜你喜欢
        • 2018-10-18
        • 2017-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-02
        • 1970-01-01
        • 1970-01-01
        • 2010-10-11
        相关资源
        最近更新 更多