You can make a particular stream throw an exception on any of eof/fail/bad by calling its ios::exceptions() function with the proper bitmask. So, you could rewrite the example in the initial question above as:
std::ifstream stream;
stream.exceptions(std::ios::failbit | std::ios::badbit);
stream.open(filename.c_str());
Here stream will throw an exception when the failbit or badbit gets set. For example if ifstream::open() fails it will set the failbit and throw an exception. Of course, this will throw an exception later if either of these bits gets set on the stream, so this rewrite is not exactly the same as the initial example. You can call
stream.exceptions(std::ios::goodbit);
to cancel all exceptions on the stream and go back to checking for errors.