为什么不能用`ofstream` /`ifstream`初始化一个`fstream`实例的引用? [英] Why can't I initialize a reference to `ofstream` / `ifstream`, with an instance of `fstream`?
问题描述
简介
void read_foo(std :: ifstream& out);
void write_foo(std :: ofstream& out);
我有这两个函数,其中一个应该从文件读取,
$ b
一切正常,具有以下片段;
std :: ifstream ifs(filename.txt);read_foo(ifs);
std :: ofstream ofs(filename.txt);
write_foo(ofs);
问题
然而,如果我尝试使用 std :: fstream
,所以我可以调用两个函数与同一流,它不编译,
- 为什么我不能绑定
fstream
到ifstream&
或ofstream&
?
foo.cpp
#include< fstream>
void read_foo(std :: ifstream& out);
void write_foo(std :: ofstream& out);
int main(){
std :: fstream fs(filename.txt);
read_foo(fs);
write_foo(fs);
}
错误:
$ b b
foo.cpp:在函数'int main()'中:
foo.cpp:9:16:error:的类型'std :: ifstream&从表达式类型'std :: fstream {aka std :: basic_fstream< char>}'
read_foo(fs);
^
中的{aka std :: basic_ifstream< char>& > foo.cpp:3:7:注意:在传递void read_foo(std :: ifstream&)'的参数1 void read_foo(std :: ifstream& out);
foo.cpp:10:16:error:无效的引用初始化类型'std :: ofstream&来自类型为std :: fstream(aka std :: basic_fstream< char>}的表达式的
在通用代码中接受流时,您不应该关心底层流的 real 类型。 p>
如果我们传入一个 std :: stringstream , std :: fstream std :: ofstream 到我们的函数,它将一些输出数据写入流?不,我们关心的是读取/写入的能力。
我们通过形成一个引用 std :: istream
, std :: ostream
或 std :: iostream
当我们需要可以分别读取,写或两者的流。
(注意:如果不明显: ifstream , $ bINTRODUCTION
void read_foo (std::ifstream& out);
void write_foo (std::ofstream& out);
I have these two functions where one is supposed to read from a file, and the other is supposed to write to one.
Everything works having the below snippets;
std::ifstream ifs ("filename.txt");
read_foo (ifs);
std::ofstream ofs ("filename.txt");
write_foo (ofs);
THE PROBLEM
However, if I try to use a std::fstream
, so I can call both functions with the same stream, it doesn't compile, and the compiler spits out a lot of error messages.
- Why can't I bind a
fstream
to anifstream&
, orofstream&
?
foo.cpp
#include <fstream>
void read_foo (std::ifstream& out);
void write_foo (std::ofstream& out);
int main () {
std::fstream fs ("filename.txt");
read_foo (fs);
write_foo (fs);
}
Error(s):
foo.cpp: In function ‘int main()’:
foo.cpp:9:16: error: invalid initialization of reference of type ‘std::ifstream& {aka std::basic_ifstream<char>&}’ from expression of type ‘std::fstream {aka std::basic_fstream<char>}’ read_foo (fs);
^
foo.cpp:3:7: note: in passing argument 1 of ‘void read_foo(std::ifstream&)’ void read_foo (std::ifstream& out);
foo.cpp:10:16: error: invalid initialization of reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from expression of type ‘std::fstream {aka std::basic_fstream<char>}’
write_foo (fs);
^
foo.cpp:4:6: note: in passing argument 1 of ‘void write_foo(std::ofstream&)’ void write_foo (std::ofstream& out);
"THE LONG STORY; SHORT" - ANSWER
Since a std::fstream
is not derived from either std::ofstream
, nor std::ifstream
, the reference is not "compatible" with the instance of std::fstream
.
Use std::istream&
and std::ostream&
, instead of std::ifstream&
and std::ofstream&
(respectively).
void write_data (std::ostream&);
void read_data (std::istream&);
INTRODUCTION
As the compiler is trying to tell you; std::fstream
does not inherit from std::ifstream
, therefore you cannot initialize a reference to the latter with a value of the former.
I've stumbled upon several developers who seem to assume that std::fstream
, behind the scenes, is some sort of direct merge between a std::ifstream
, and a std::ofstream
, and that it is implemented by deriving from both.
When asked why they think that is the case, many think that the answer can be summed up with; "because it makes sense, right?"
THE SILLY ANALOGY
Imagine that we have three siblings; Ivan, Owen, and John, living in a family where reading and writing is everything.
All brothers were born with a gift;
- Ivan is great at reading, and has given it his whole life, he never does anything else, and;
- Owen has a thing for writing, which is odd since he can't read, and;
- John got lucky and got both the skill of reading and writing.
Just because John can do both of the things his brothers can, doesn't mean that they are his parents - they are, after all; his brothers.
All three brothers has inherited their certain traits from other relatives, not each other.
THE ANSWER
std::fstream
is not built "on top of" std::{i,o}fstream
, even though they share certain parts of their individual inheritance tree.
When accepting a stream in generic code you should not care about the "real" type of the underlying stream.
Does it really matter if we pass in a std::stringstream, std::fstream, or std::ofstream to our function which writes some output data to a stream? No, all we care about is the ability to read/write.
We express this by forming a reference to either std::istream
, std::ostream
, or std::iostream
, when we need a stream which can;read, write, or both, respectively.
( Note: IF it's not obvious: Ivan is an ifstream, Owen an ofstream, and John a fstream. )
这篇关于为什么不能用`ofstream` /`ifstream`初始化一个`fstream`实例的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!