【发布时间】:2011-01-18 21:48:08
【问题描述】:
在线参考对std::iostream::sentry 的用途的描述相当简短和模糊。我什么时候应该关心这个小动物?如果它只打算在内部使用,为什么要公开?
【问题讨论】:
-
标识符是从什么时候开始的?而且肯定不小! :D
在线参考对std::iostream::sentry 的用途的描述相当简短和模糊。我什么时候应该关心这个小动物?如果它只打算在内部使用,为什么要公开?
【问题讨论】:
当您需要使用流提取或输出数据时使用它。也就是说,每当您创建 operator>>(提取运算符)或 operator<<(插入运算符)时。
其目的是简化逻辑:“是否设置了任何失败位?同步缓冲区。对于输入流,可以选择排除任何空白。好的,准备好了吗?”
所有提取流运算符都应以:
// second parameter to true to not skip whitespace, for input that uses it
const std::istream::sentry ok(stream, icareaboutwhitespace);
if (ok)
{
// ...
}
所有插入流操作符都应该以:
const std::ostream::sentry ok(stream);
if (ok)
{
// ...
}
这只是一种更清洁的方式(类似于):
if (stream.good())
{
if (stream.tie())
stream.tie()->sync();
// the second parameter
if (!noskipwhitespace && stream.flags() & ios_base::skipws)
{
stream >> std::ws;
}
}
if (stream.good())
{
// ...
}
ostream 只是跳过空白部分。
【讨论】:
operator>>,是否仍然需要(或一个好主意)使用哨兵?
大多数人永远不会编写任何需要处理创建哨兵对象的代码。当/如果您从作为流对象本身基础的流缓冲区中提取数据(或将其插入)时,需要一个哨兵对象。
只要您的插入/提取操作符使用其他 iostream 成员/操作符来完成它的工作,它确实不必处理创建哨兵对象(因为那些其他 iostream 操作符将创建和销毁哨兵对象根据需要)。
【讨论】:
除基本类型(int、double 等)之外的任何内容的格式化输入都没有多大意义,并且可以说只有在从非交互式流(如 istringstream)中获取时才从它们中获取。所以你可能不应该首先实现 op>>,因此不必担心哨兵对象。
【讨论】:
struct Point{double x, double y}; Point point; file >> point; 重载的 operator>> 是根据基本类型的 operator>> 实现的。
operator>>(istream& s, P& p){s>>p.x; s>>p.y;} 不好,但getPoint(istream& s, P& p){s>>p.x; s>>p.y;} 没问题?