Why can't I initialize a reference to `ofstream` / `ifstream`, with an instance of `fstream`?

前端 未结 1 1360
走了就别回头了
走了就别回头了 2020-12-16 14:00

INTRODUCTION

void  read_foo (std::ifstream& out);
void write_foo (std::ofstream& out);

I have these two functions where one is su

相关标签:
1条回答
  • 2020-12-16 14:20

    "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.


    iostreams inheritance visualized

    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. )

    0 讨论(0)
提交回复
热议问题