重载运算符“>>”上的bad_lexical_cast异常

时间:2014-08-17 13:48:18

标签: c++ operator-overloading lexical-cast

我已经超载了运营商">>"对于一个枚举:

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

我得到的输出:

  

Hello World   抛出一个实例后终止调用   &#39;升压:: exception_detail :: clone_impl

     
    

&#39; what():错误的词法转换:源类型值无法解释为目标

  

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

if (interpreter >> result)

运算符正在处理除空字符串之外的每个值。从运算符返回的输入流与从头开始的流相同。

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

1 个答案:

答案 0 :(得分:3)

问题在于您告诉lexical_cast将空字符串转换为MyEnum。你期望它做什么?它无法返回实际值,因此异常是正确的。

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

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

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