TITLE: relationships between streams and fstreams (Newsgroups: comp.lang.c++.moderated, 18 Oct 99) LIN: "CH Lin" > void foo(ofstream& out) { ... } KUEHL: Dietmar Kuehl You should declare 'foo()' to take an 'ostream&': void foo(ostream& out) { ... } LIN: > It surprised me at first. I always thought the relation between > fstream and ofstream is: > > ifstream ofstream > \ / > \ / > fstream KUEHL: No, this is not the case. The hierarchy looks something like this: ios / \ / \ istream ostream / \ / \ / \ / \ ifstream iostream ofstream | fstream These are typedefs for the corresponding class templates (add 'basic_' to the names to get the name of the class template) using 'char' and 'std::char_traits' as template arguments. The normal approach is to create an appropriate stream using one of the lea[f] classes (or one of the intermediate classes with explicitly specifying the stream buffer to be used). After creation, the streams are normally interchangeable. That is, you would pass 'istream', 'ostream', or 'iostream' around. Normally, no special processing like using 'is_open()' or 'open()' is necessary until the stream is destructed. LIN: > Well, it is not. The relation between fstream and i/ofstream is > surprisingly distinct. The common base between them is ios<>! So how > do I pass a fstream object to function which expects a ofstream or > ifstream argument? KUEHL: If you don't need any of the special file stream members, you can just pass an object of 'istream' or 'ostream', passing them by reference. If you really need to use one of the special members, ie. 'is_open()', 'open()', or 'close()', you are out of luck: It doesn't even work to pass an 'ifstream' with a replaced stream buffer (using 'rdbuf()') because the special member functions do not operate on the result of 'ios::rdbuf()' but on the result of '[io]fstream::rdbuf()': The latter one cannot be changed. In this case, the best approach is to pass still an 'istream&' or 'ostream&' and access the special members by using a downcast: void foo(std::ostream& out) { std::filebuf* fb = dynamic_cast(out.rdbuf()); if (fb != 0) fb->close(); // or whatever // ... } However, I haven't encountered a corresponding use yet...