有没有人真正使用流提取操作符?

时间:2010-02-22 08:17:52

标签: c++ iostream formatted-input

我写了很多operator<<(std::ostream &, const T &)个函数 - 它们非常有用。

我从未在实际代码中编写operator>>(std::istream &, T &)函数,甚至没有使用内置类型的提取运算符(好的,可能是std::string)。这些仅适用于简短的示例程序和教科书吗? operator>>是C ++的失败功能吗?

有人询问有关safely overloading stream operators的问题。我想知道是否有人在实践中这样做。

即使对于像reading input from a file in C++这样的简单内容,我也建议不要使用operator>>。编写在检测和处理输入错误方面很强大的代码(或者我不知道如何)是非常困难的。

如果你不同意,请展示一个使用operator>>的好例子 - 也许回答我链接的最后一个问题。

<小时/> 总结:感谢大家的回复,很多好的意见。曼努埃尔的回答让我重新考虑我不愿意使用op>>所以我接受了那个。

7 个答案:

答案 0 :(得分:8)

我认为当与std::copystd::istream_iterator类等STL算法结合使用时,流提取器运算符非常有用。

阅读this answer,看看我在说什么。

答案 1 :(得分:6)

是的我确实使用了运营商&gt;&gt; (尽管不像运营商那样频繁&lt;&lt;)。将用户定义的类型解析为各自的对象非常有用,因此集中了解析和必要的错误处理。它对于解析枚举类型的字符串表示也非常有用。

例如,考虑表示水果的枚举类型。您可以使用运算符&gt;&gt;解析字符串(如“apple”,“banana”等)以获取正确的枚举值。

std::istream &operator>>(std::istream &is, Fruit &fruit)
{
    std::string str;
    is >> str;
    if (str == "apple")
        fruit = APPLE;
    else if (str == "banana")
        fruit = BANANA;
    // other fruits
    else
        is.setstate(std::ios::failbit);
    return is;
}

还要注意在istream上使用setstate方法来设置遇到未知字符串时流的失败状态。使用此运算符时,可以按如下方式检查流的failstate:

Fruit fruit;
std::cin >> fruit;
if (std::cin.fail())
   std::cout << "Error: Unknown Fruit!" << std::endl;

答案 2 :(得分:3)

值经常打印而不是读取,因此operator<<的使用频率高于operator>>。不过,如果您想读取值,operator>>很有用。

您必须检查错误并非特定于operator>>,显然,任何其他读取值的方法都必须以某种方式检测无效输入。

答案 3 :(得分:2)

我从不写它们,很少使用“内置”的。提取操作符对于读取交互式用户输入非常无用,因为它很容易让流变坏。编写自定义解析例程几乎总是更容易和更健壮。当涉及到序列化时,如果我想将某些东西保存为文本,我会将其用于行业标准格式,例如XML,其中提取操作符特别不适合阅读。否则,我将数据存储在数据库或二进制文件中,这再次不适合与提取器一起使用。

答案 4 :(得分:2)

operator>>在将文本形式的数字转换为内部表示时非常有用。

它在加载对象数据时也很有用。与不能为不同类型重载的scanf不同,对象可以重载operator>>。因此,它为加载对象提供了更多的数据隐藏,为了将数据读入对象,不需要知道内部表示。

答案 5 :(得分:1)

运营商&gt;&gt;基本上是反序列化。在我有限的轶事经验中,C ++中的大多数序列化/反序列化都是在比流库更低的层次上实现的。它不必在较低级别实现 - 通常只是。

实现自定义反序列化并不总是一个微不足道的问题,但即使您没有使用流提取语法实现它,您也可能遇到相同的问题。

这是对流提取运算符的一种使用至少有用的: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

在这个有限的范围内,似乎正确的用法相当简单。

答案 6 :(得分:0)

我大量使用了运算符&lt;&lt;在我的OOFILE数据库API中汇编排序指令列表,字段到数据库视图等。

出于某种原因,大量用户发现直观地使用运算符&gt;&gt;到append a sort field which was a reverse sort。我不知道是谁首先建议它,但它吸引了足够的人,它在API中做到了。

例如:

dbSorter arcSort;  // declare a sorter
arcSort << reverse(Date) << FileName; // "normal" way to specify two sort fields
arcSort >> Date << FileName;  // shorthand way that evolved to specify 

我们还常规使用了运算符&gt;&gt;从流中解析整个dbTable