0

我为枚举重载了运算符“>>”:

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

我得到的输出:

抛出 'boost::exception_detail::clone_impl 的实例后调用 Hello World 终止

' what(): bad lexical cast: 源类型值不能被解释为目标

从 lexical_cast_39.hpp (1155) 抛出异常:

if (interpreter >> result)

该运算符适用于除空字符串之外的每个值。从运算符返回的输入流与一开始的流相同。

这种问题的可接受方法是什么?谢谢!

4

1 回答 1

3

问题是您要告诉lexical_cast将空字符串转换为 MyEnum。你希望它做什么?它不能返回一个真正的值,所以一个异常是正确的。

更详细 lexical_cast的细分:获取输入空字符串,并从该值创建输入流。然后将其传递给您的operator>>. 当您这样做时is >> value;,它会eof在流上设置标志(因为它试图读取字符串,并且没有剩余数据。

在您的函数返回后,它会完成if ( interpreter >> result ),这基本上会检查流是否仍处于良好状态。由于它不是(由于eof前面的一点),它失败并出现异常。

如果要将空字符串解释为特定值,则必须在返回之前从流中清除错误标志。就个人而言,我不会这样做,因为它会限制输入运算符在其他情况下的有用性。如果我需要这个功能,我很可能会在调用 lexical_cast 之前检查空字符串。

于 2014-08-17T13:56:42.933 回答