问题
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?
回答1:
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;
}
回答2:
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?.
回答3:
This is not pretty but should do it
stream >> reinterpret_cast<std::underlying_type<Sex>::type &>(student.m_bio.sex);
Cheers, CC
来源:https://stackoverflow.com/questions/5633784/input-from-stream-to-enum-type