有大量关于重载operator<<
的信息,以模仿将toString()
- 样式方法转换为字符串的方法。我对还实现逆,operator>>
以将字符串反序列化为对象感兴趣。
通过检查STL
来源,我收集到了:
istream &operator>>(istream &, Object &);
将是用于反序列化Object
类型对象的正确函数签名。不幸的是,我对如何正确实现这一点感到茫然 - 特别是如何处理错误:
答案 0 :(得分:18)
您应该设置fail
位。如果流的用户想要抛出异常,他可以配置流(使用istream::exceptions
),并且流将相应地抛出。我会这样做,然后
stream.setstate(ios_base::failbit);
对于不符合您要阅读的格式的格式错误的数据,通常应设置fail
位。对于内部流特定错误,使用bad
位(例如,如果没有连接到流的缓冲区)。
我没有听说过这样的事情。
要检查流是否处于良好状态,可以使用istream::sentry
类。创建一个对象,传递流和true
(告诉它不要立即跳过空格)。如果设置了false
,eof
或fail
位,则哨兵将评估为bad
。
istream::sentry s(stream, true);
if(!s) return stream;
// now, go on extracting data...
答案 1 :(得分:2)
一些补充说明:
在实现运算符&gt;&gt;时,您可能应该考虑使用 bufstream而不是运营商的其他重载&gt;&gt ;;
操作期间发生的异常应该转换为 failbit或badbit(streambuf的成员可能会抛出,取决于 使用的类);
设置状态可能会抛出;如果你在捕获后设置状态 例外,您应该传播原始异常而不是传播异常 被setstate抛出;
宽度是您应该注意的字段。如果你是 考虑到这一点,你应该将其重置为0.如果你正在使用其他 运营商GT;&GT;要做基本的工作,你必须计算你传递的宽度 从你收到的那个;
考虑考虑区域设置。
Lange和Kreft(标准C ++ IOStreams和Locales )甚至将它融合在一起 更多细节。他们为错误处理提供了一个模板代码 大约一页。
答案 2 :(得分:0)
至于旗帜,我不知道某处是否有任何标准,但重置它们是个好主意。
Boost有完整的raii包装:IO State Savers