在C++中,`var << ifstream` 和 `ifstream >> var` 是一样的吗?

3

var << ifstreamifstream >> var是一样的吗?

据我所知,它们应该完全相同。但现在已经很晚了,我的大脑有些迷糊,所以我想要一个澄清。


3
另外,对于这种事情来说,谷歌搜索很糟糕。我真的希望他们能允许搜索符号。 - Polynomial
2
请查看http://www.symbolhound.com/,它在与SO一起使用时特别好用。 - Niklas B.
6个回答

9
它们不是相同的。 foo << barfoo.operator<<(bar)operator<<(foo, bar),而 bar >> foobar.operator>>(foo)operator>>(bar, foo)
它们只是不同的东西。无论这些版本中是否存在任何一个,更不用说如果存在两个版本它们是否执行相同的操作,这完全取决于您的代码中有什么。
对于标准iostreams,通常仅为某些用户定义的类型T定义以下两个自由函数,没有其他函数被定义:
std::ostream & operator<<(std::ostream &, T const &);  // for "os << x"
std::istream & operator>>(std::istream &, T &);        // for "is >> y"

1
这只是说明我疲倦时不应该编码。现在完全有道理了。谢谢 :) - Polynomial
4
没问题。需要记住的是,在C++中,运算符可以被广泛地重载;有时会在非常意外的情况下出现这种情况(例如,在当前标准中存在一个关于逗号运算符错误使用的缺陷)。但是,重载的运算符只是函数调用,没有任何魔法。 - Kerrek SB

3
不,它们调用完全不同的功能。一个调用operator >>,另一个调用operator <<。此外,这两个函数的参数也不同。这就像问F(int,double)是否与调用Q(double, int)相同,也许是,也许不是,尽管我可以理解为什么对于新手来说这并不立即显而易见。您首先需要意识到重载运算符并没有什么特别之处,它们只是函数调用。

2

除非var定义了<<运算符或者它被定义为自由函数,否则前者是无效的。


2
它不必由var类定义。它可以是一个自由函数。 - Benjamin Lindley

0

这里有一个小提示,显示出两个表达式不相同。操作符也可以通过非常丑陋的语法调用。自己看看:

var << ifstream;

等于

var.operator<<(ifstream);

ifstream >> var;

等于

ifstream.operator>>(var);

编辑:在下面的评论提醒后,还有第三种选择。operator>> 也可以被实现为一个函数:

returntype operator>>(ifstream, var);
returntype operator>>(var, ifstream);

由于签名不匹配,它们可能会被实现得不同。

马蒂亚斯。


1
不一定,它们也可以是operator << (var, ifstream)operator >> (ifstream, var) - Edward Strange

0
不,这不是同一件事。惯例是流参数始终位于<< >>运算符的左侧,要读取/写入的值位于右侧。这样做有很好的理由:这些运算符可以像链条一样链接起来。
std::cout << "Hello" << ',' << " world";

(对于istream也是类似的)这里发生了什么: << 运算符是左结合的,所以我们有
((std::cout << "Hello") << ',') << " world";

类型在哪里

std::cout                         :   std::ostream
(std::cout << "Hello")            :   std::ostream
((std::cout << "Hello") << ',')   :   std::ostream

所以每次调用operator<<(stream, value)时,都会得到期望的结果。现在你想要的是完全颠倒过来,就像这样
" world" >> ',' >> "Hello" >> std::cout;

一开始看起来应该做同样的事情。但它不会,因为这现在解析为

((" world" >> ',') >> "Hello") >> std::cout;

你从一个 operator>>(const char*, char) 开始。现在这个操作符怎么知道最终的结果会被放入一个 std::ostream 中呢?


-1

1
没有理由不为一个以流作为第二个参数并从中读取的类型定义operator <<。只是这不是大多数人使用的标准预期方法。 - Edward Strange
@CrazyEddie,当然你可以定义任何你想要的东西。我理解这个问题的意思是它们是否都可以直接使用,答案是不行 - Mark Ransom
1
很不幸,你的回答也暗示着只需要查看ifstream的文档就可以知道答案,这是非常误导人的...姑且给你一点怀疑的余地。 - Edward Strange
3
这意味着查看cplusplus.com上的条目等同于查看文档。 - Benjamin Lindley
@BenjaminLindley,如果你知道更好的在线文档,我很乐意听取建议。 - Mark Ransom
当然:这个虽然还不完整,但我发现它更加准确(向 StackOverflower cubbi 表示感谢,他为此付出了大量的工作)。但两者都不是最终的权威来源。我只是对你所使用的措辞有异议,它似乎暗示cplusplus.com确实是权威来源。具体来说,在“documentation”之前使用“the”这个词。抱歉我可能过于迂腐,但我认为这样的措辞会让阅读者产生错误的印象。 - Benjamin Lindley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接