【问题标题】:bad_lexical_cast exception on overloaded operator ">>"重载运算符“>>”上的 bad_lexical_cast 异常
【发布时间】:2014-08-17 13:48:18
【问题描述】:

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

#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

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

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

if (interpreter >> result)

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

对于此类问题,可接受的方法是什么? 谢谢!

【问题讨论】:

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


    【解决方案1】:

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

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

    在您的函数返回后,它会完成if ( interpreter &gt;&gt; result ),它主要检查流是否仍处于良好状态。由于不是(由于前面的eof 位),因此它失败并出现异常。

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

    【讨论】:

    • 感谢您的解释。我只是没有得到,就运算符的功能而言,将映射到默认 ONE 的随机字符串值与也应该映射到 ONE 的空字符串值之间有什么区别。除非我们将空字符串作为一个概念称为“无值”,否则您应该抛出异常是对的。
    • 不同之处在于,随机的非空文本可以成功读入字符串,而空文本会导致输入操作失败。实际上,您的 operator>> 实现应该执行 if (!(is &gt;&gt; value)) return is; 以正确处理输入错误。默认为任何值都会违反最小意外原则,因为没有其他类型具有类似的行为。
    猜你喜欢
    • 2014-02-21
    • 1970-01-01
    • 2020-03-04
    • 2021-12-17
    • 2020-01-10
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多