Я перегружен оператор «>>» для Enum:
#include <iostream>
#include <boost/lexical_cast.hpp>using namespace std;
enum MyEnum
{
ONE = 0,
TWO,
TREE,
MAX
};
const char* MyEnumString[MAX] =
{
"ONE","TWO","THREE"};
istream& operator>>(istream& is, MyEnum& myEnum)
{
string value;
is >> value;
myEnum = ONE;
for (int i=0; i < MAX; i++)
{
if (!value.compare(MyEnumString[i]))
{
myEnum = static_cast<MyEnum>(i);
return is;
}
}
return is;
}
int main()
{
cout << "Hello World" << endl;
boost::lexical_cast<MyEnum>(""); //Throws exception.
return 0;
}
На выходе я получаю:
Привет, мир
завершить вызов после броска экземпляра
«Повышение :: exception_detail :: clone_impl‘what (): неверное лексическое приведение: значение типа источника не может быть интерпретировано как цель
Исключение выдается из lexical_cast_39.hpp (1155):
if (interpreter >> result)
Оператор работает для каждого значения, кроме пустой строки. Входной поток, возвращаемый оператором, является тем же потоком, который был с самого начала.
Каков приемлемый подход для такой проблемы?
Спасибо!
Проблема в том, что вы говорите lexical_cast
преобразовать пустую строку в MyEnum. Что бы вы ожидали от этого? Он не может вернуть реальное значение, поэтому исключение является правильным.
Более подробная разбивка: lexical_cast
принимает входную пустую строку и создает входной поток из этого значения. Это затем передается на ваш operator>>
, Когда вы делаете is >> value;
это устанавливает eof
флаг в потоке (так как он попытался прочитать строку, и не осталось данных.
После того, как ваша функция возвращается, она завершает if ( interpreter >> result )
, который в основном проверяет, находится ли поток в хорошем состоянии. Так как это не так (из-за eof
немного раньше), это не удалось за исключением.
Если вы хотите, чтобы пустая строка интерпретировалась как определенное значение, вы должны очистить флаги ошибок из потока перед возвратом. Лично я бы не стал этого делать, так как это ограничило бы полезность оператора ввода в других ситуациях. Если бы мне понадобилась эта возможность, я бы, скорее всего, проверил бы пустую строку перед вызовом lexical_cast.