As you can see, the types of the exceptions thrown are the same. But, as your checking is done so near the opening of the file, you can do it without exceptions, no? like:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string inputFileName { "/notexists" };
string outputFileName { "/notexistsandprobablynotwritable" };
ifstream inputFile { inputFileName };
if( !inputFile ) {
cerr << "Failed to open input file" << endl;
return -1;
}
cout << "Input file opened" << endl;
ofstream outputFile { outputFileName };
if( !outputFile ) {
cerr << "Failed to open output file" << endl;
return -1;
}
cout << "Output file opened" << endl;
}
Or, if you really need the exceptions, you can throw different exceptions yourself, at the open site:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
template<typename Stream, typename Exception = typename Stream::failure>
void try_open(Stream& s, string filename) {
s.open(filename);
if( !s )
throw Exception( string("cannot open ")+filename );
}
struct input_exception: ifstream::failure { input_exception(const string& s): ifstream::failure(s) {} };
struct output_exception: ofstream::failure { output_exception(const string& s): ofstream::failure(s) {} };
int main() {
string inputFileName { "/notexists" };
string outputFileName { "/notexistsandprobablynotwritable" };
try {
ifstream inputFile;
try_open<ifstream, input_exception>(inputFile, inputFileName);
cout << "Input file opened" << endl;
ofstream outputFile;
try_open<ofstream, output_exception>(outputFile, outputFileName);
cout << "Output file opened" << endl;
} catch(const output_exception& e) {
cerr << "output exception!\n" << e.what() << "\n";
} catch(const input_exception& e) {
cerr << "input exception!\n" << e.what() << "\n";
} catch(const exception& e) {
cerr << "exception!\n" << e.what() << "\n";
}
}