从流到枚举类型的输入

发布于 2024-10-31 12:02:17 字数 165 浏览 1 评论 0原文

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

我也能做到,

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

不然呢?

How to input from stream to enum type?

I can do it so

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

Otherwise?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

秋日私语 2024-11-07 12:02:17
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;
}
inline std::istream & operator>>(std::istream & str, Sex & v) {
  unsigned int sex = 0;
  if (str >> sex)
    v = static_cast<Sex>(sex);
  return str;
}

If you want to ensure that the value is valid, you can do something like this:

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;
}
淑女气质 2024-11-07 12:02:17

这个问题在这里以更一般的形式提出:如何以通用方式从 std::istream 读取枚举
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 具有相同的用途库:它让我们省去了尖括号。您同样可以在 >> 中编写 EnumReader(val.mSide)>> EnumReader(val.mType),但这更多的是打字(双关语)。

据称,一些供应商的标准库在其 标头中仍然缺少 std::underlying_type。如果您有这些不完整的库之一,则可以使用 如何知道类枚举的底层类型?

This question was asked in a more general form over here: How to read enums from a std::istream in a generic fashion.
The OP almost had a working solution as it was; he just had some trouble with const, and a few unnecessary angle-brackets. Here's the working solution fleshed out:

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

The read_enum function template serves the same purpose here as std::make_pair or std::make_shared in the standard library: it lets us dispense with the angle brackets. You could equally well write in >> EnumReader<enSide>(val.mSide) >> EnumReader<enType>(val.mType), but that's more typing (pun intended).

A few vendors' standard libraries are allegedly still missing std::underlying_type from their <type_traits> headers. If you have one of these incomplete libraries, you can use one of the workarounds listed at How to know underlying type of class enum?.

丘比特射中我 2024-11-07 12:02:17

这并不漂亮,但应该做到,

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

干杯,
CC

This is not pretty but should do it

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

Cheers,
CC

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文