21

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

我从来没有用operator>>(std::istream &, T &)真实的代码写过函数,甚至没有使用过内置类型的提取操作符(好吧,也许是 for std::string)。这些仅适用于简短的示例程序和教科书吗?是operator>>C++ 的失败特性吗?

有人问过有关安全地重载流操作符的问题。我想知道是否有人在实践中这样做。

即使对于像从 C++ 文件中读取输入这样简单的事情,我也不建议使用operator>>. 编写能够检测和处理输入错误(或者我不知道如何)的代码太难了。

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


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

4

7 回答 7

8

I think stream extractor operators can be very useful when combined with STL algorithms like std::copy and with the std::istream_iterator class.

Read this answer to see what I'm talking about.

于 2010-02-22T19:05:00.440 回答
6

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

例如,考虑一个代表水果的枚举类型。您可以使用 operator>> 解析字符串(如“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 方法来设置流的失败状态。使用此运算符时,您可以检查流的失败状态,如下所示:

Fruit fruit;
std::cin >> fruit;
if (std::cin.fail())
   std::cout << "Error: Unknown Fruit!" << std::endl;
于 2010-02-22T08:59:39.633 回答
3

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

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

于 2010-02-22T08:28:03.923 回答
2

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

于 2010-02-22T09:41:59.903 回答
2

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

It can also be useful in loading data for objects. Unlike scanf, which cannot be overloaded for different types, objects can overload operator>>. Thus it provides more data hiding for loading objects, the internal representation does not need to be known in order to read data into the object.

于 2010-02-22T19:00:43.400 回答
1

运算符 >> 基本上是反序列化。在我有限的轶事经验中,C++ 中的大多数序列化/反序列化都是在比流库更低的级别实现的。它不必在较低级别实施 - 通常是这样。

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

这是流提取运算符的一个俗气的使用,它至少有点用处: http: //www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

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

于 2010-02-22T08:47:53.103 回答
0

我大量使用 operator<< 在我的OOFILE数据库 API 中将排序指令列表、字段组合到数据库视图等中。

出于某种原因,大量用户发现使用运算符>>附加一个反向排序的排序字段很直观。我不知道最初是谁建议的,但它吸引了足够多的人,以至于它在 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 

我们还常规使用 operator>>从流中解析整个dbTable 。

于 2010-02-22T08:29:51.970 回答