1
votes

My use case is to create a function which takes a fileName , an ifsttream/ofstream object and then opens the file for reading/writing accordingly in the given filestream object. also to check whether the operation was successful or not and if successful, returns the filestream object.

My implementation is as following and is based on the assumption that both ifstream and ofstream are derived from fstream.

#include <iostream>
#include <fstream>
using namespace std;
void populate_filehandles(const string &inFileName, fstream &filehandle) {
    filehandle.open(inFileName);
    if (!filehandle.is_open()) {
            cout << "input file : " << inFileName << " could not be opened" << endl;
            exit(0);
        }
}
int main () {
    ifstream inFile;
    string inFileName = "abc.txt";
    populate_filehandles(inFileName, inFile);
}

the code gives an error that ifstream can not be converted to fstream. is there any other way to solve the problem?

1
I think it isn'T a good design to handle ofstream and ifstream (if it would possible) in the same function. Maybe with a templated function it will workRoQuOTriX
You are passing the stream into the function by reference, why do you need to return it as well? Just change the function return type to void. Now the only prolbem to solve is the error message, at the moment is say "input file" which isn't necessarily true.john
That code does not produce that message. Please post a minimal reproducible example.molbdnilo
You might want to verify your assumption that both ifstream and ofstream are derived from fstream. Surprises are usually caused by one or more assumptions being mistaken.molbdnilo
@VisheshArya Let's make this explicit, ifstream inherits from istream, ofstream inherits from ostream, fstream inherits from iostream. So the code as currently written cannot work. Referencejohn

1 Answers

0
votes

So, as others have suggested, this is due to the fact that std::ifstream doesn't inherit from std::fstream. Rather, it inherits from std::istresm instead. std::fstream on the other hand inherits from std::iostream. So you can't really do that.

Some options you have to work around:

  1. Templates (as others have mentioned):
template <class T> void populate_filehandles(const string &inFileName, T &filehandle)
  1. Overloading:
void populate_filehandles(const string &inFileName, std::ifstream &filehandle)
void populate_filehandles(const string &inFileName, std::ofstream &filehandle)

This, however will require you to implement the same function twice. Not necessarily the best idea, but would work.

  1. Pass a flag

Something interesting about std::fstream is that it has the ability to open a file for reading or writing (or even both I think). So, in theory, you could add a flag to say which direction you want to open it:

void populate_filehandles(const string &inFileName, fstream &filehandle, bool reading) {
    if(reading) {
        filehandle.open(inFileName, std::ios::in);
    } else {
        filehandle.open(inFileName, std::ios::out);
    }
    //...
}