В C ++ нет интеллектуального преобразования между строками и перечислениями.
Ваш входной код не работает, потому что вы читаете int
из входного потока и приводите его к цвету:
- Это может сработать, если вы введете действительное целое число, соответствующее одной из кодировок значений перечисления.
- Но если вы введете строку, операция ввода завершится неудачно из-за несовместимого типа. Входной поток получает ошибку, и все последующие операции в этом потоке будут терпеть неудачу, пока вы не очистите флаги ошибок.
Если вы хотите прочитать строку, вам нужно позаботиться об этом. Например, со следующим кодом:
std::istream& operator>>( std::istream& is, Color& I )
{
std::string tmp;
if ( is >> tmp ) {
for (auto&c:tmp)
c=std::tolower(c);
if (tmp=="red") I = red;
else if (tmp=="blue") I = blue;
// but what happens if the string is invalid ???
}
return is ;
}
std::ostream& operator<<( std::ostream& os, Color& O )
{
std::string tmp;
switch (O) {
case red: tmp="red"; break;
case blue: tmp="blue"; break;
default: tmp="oops!!";
}
return os<<tmp ;
}
Конечно, это только наивный пример. В действительности у вас, вероятно, будет std :: map для хранения связи между строкой и перечислением, и наоборот.
Стоит знать:
Перечислители в перечислении могут быть сопоставлены с целыми значениями. По умолчанию первый перечислитель (red
) сопоставлен с 0. Следующие перечислители получают значение, которое на 1 больше, чем предыдущие (т. Е. blue
будет равно 1).
Но вы можете установить значение (например, enum Color { red=2, green, blue=green+4 };
). Вот почему допустимо делать между int и enum. Но будьте очень осторожны при этом, потому что, как только целое число не соответствует точно значению перечислителя, оно может стать сложным.