为什么不能用`ofstream` /`ifstream`初始化一个`fstream`实例的引用? [英] Why can't I initialize a reference to `ofstream` / `ifstream`, with an instance of `fstream`?

查看:578
本文介绍了为什么不能用`ofstream` /`ifstream`初始化一个`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 , $ b

INTRODUCTION

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 an ifstream&, or 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);
}

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.


src: http://en.cppreference.com/w/cpp/io


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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆