如何从流中输入枚举类型?
我可以这样做
unsigned int sex = 0;
stream >> sex;
student.m_bio.sex = static_cast<Sex>(sex);
否则呢?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;
}
这个问题的一般形式已经在这里提出:如何以通用的方式从std::istream中读取枚举。
原帖的解决方案基本上就差一点点,只是有些麻烦的地方需要处理 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_pair
或std::make_shared
相同:它让我们省略了尖括号。你可以同样地写成in >> EnumReader<enSide>(val.mSide) >> EnumReader<enType>(val.mType)
,但那样会更加冗长(双关语)。std::underlying_type
,这个头文件在<type_traits>
中。如果你使用的是这些不完整的库之一,你可以使用如何知道类枚举底层类型的方法?中列出的其中一种解决方法。这不太好看,但应该能行。
stream >> reinterpret_cast<std::underlying_type<Sex>::type &>(student.m_bio.sex);
干杯, CC
v = static_cast<Sex>(sex);
...也就是说,转换的参数是sex
,而不是v
。 :D - Nawazreturn str;
。 - Konrad Rudolphis_valid
函数。 - edA-qa mort-ora-yis_valid
? - NawazSex.is_valid(sex)
会非常方便。 - edA-qa mort-ora-y