2011-04-12 10 views

Respuesta

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

Si desea asegurarse de que el valor es válido, puede hacer algo como esto:

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; 
} 
+0

Creo que quería decir 'v = static_cast (sexo);' ... Es decir, el argumento de la el reparto es 'sexo', no' v'. : D – Nawaz

+0

@Nawaz: Sí, corregido, gracias. – Erik

+0

En esta respuesta falta un 'return str;'. –

3

Esta pregunta fue hecha en una forma más general aquí: How to read enums from a std::istream in a generic fashion. El OP casi tenía una solución de trabajo tal como estaba; él solo tuvo algunos problemas con const, y algunos corchetes angulares innecesarios. Aquí está la solución de trabajo concretarse:

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

La plantilla de función read_enum sirve al mismo propósito aquí como std::make_pair o std::make_shared en la biblioteca estándar: nos permite prescindir de los paréntesis angulares. También podría escribir in >> EnumReader<enSide>(val.mSide) >> EnumReader<enType>(val.mType), pero eso es más tipeo (juego de palabras).

Las bibliotecas estándar de unos pocos proveedores todavía faltan supuestamente std::underlying_type de sus encabezados <type_traits>. Si tiene una de estas bibliotecas incompletas, puede usar una de las soluciones alternativas enumeradas en How to know underlying type of class enum?.

0

Esto no es bonita, pero debe hacerlo

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

Cheers, CC

Cuestiones relacionadas