1

I have a function I'm writing that should handle output differently if it gets passed a file stream vs if it gets passed the console out. I could write two functions, one to handle cout and one to handle the fstream, and throw them in an if statement to determine which is called, or could add a bool on which version to run, but it'd be simpler to verify the output passed to the function, in my opinion. My first attempt was

    void print(unsigned long long exp, unsigned long long* total, 
    ostream& out, unsigned long long min, unsigned long long max, unsigned 
    long long length)
    {
        if (out == cout)
    ...
    }

Is there a way to overload == to compare these or a function that compares these?

  • 1
    It sounds like you probably want two subclasses, with a virtual "write()" method specific to each. See [SOLID](https://www.tomdalling.com/blog/software-design/solid-class-design-the-liskov-substitution-principle/) – paulsm4 Oct 03 '18 at 20:37
  • 3
    You don't need an overload, just compare pointers - `if ( &out == &cout)` –  Oct 03 '18 at 20:38
  • 4
    Do you have to print differently depending on he stream? That seems counter-intuitive. If you really have to make it different I would overload the function for a `ostream&` and `ofstream&`. – NathanOliver Oct 03 '18 at 20:38
  • 3
    "I have a function I'm writing that should handle output differently if it gets passed a file stream vs if it gets passed the console out." Then write two functions. If it should do different things, it should be different functions – Justin Oct 03 '18 at 20:38
  • People suggesting two functions might like to consider how you are going to dispatch to those functions depending on the run-time value of the stream. –  Oct 03 '18 at 20:44
  • If you don't want to, or can't, use separate functions, you *could* use `dynamic_cast` to check if the passed `ostream` is really an `ofstream` (since `ostream` has a virtual destructor). However, it is also possible for someone to attach a standard `filebuf` (or even a user-defined `streambuf` that happens to use files) to an `ostream` that is not an `ofstream`. In which case, the only reliable way to know for sure is to simply require the caller to pass in an input parameter indicating the desired output format. – Remy Lebeau Oct 03 '18 at 22:25
  • The function has to scale some spacing if it's getting printed to console, where if it's going to a txt, I don't care if it text wraps to the next line. The additional bit for if it's console just will assign the scaling factor to the length of the output. – Cali Springston Oct 03 '18 at 23:46

1 Answers1

1

Based on your comments this is an XY problem -- you really have a completely different problem (having special formatting for the output when it is going to a console instead of a file) and think that is best done by identifying the ostream.

The better way is to allocate a custom formatting flag for your use, and then set that flag in cout. Then your printing routines check the flag:

class CustomFlag {
    static int flag_id = -1;
public:
    static std::ios_base &set(std::ios_base &s) {
        if (flag_id < 0) flag_id = s.xalloc();
        s.iword(flag_id) = 1;
        return s; }
    static std::ios_base &clear(std::ios_base &s) {
        if (flag_id < 0) flag_id = s.xalloc();
        s.iword(flag_id) = 0;
        return s; }
    static int get(std::ios_base &s) {
        if (flag_id < 0) flag_id = s.xalloc();
        return s.iword(flag_id); }
};

You do std::cout << CustomFlag::set; to set it on stdout, and use CustomFlag::get(stream) to check the flag on any ostream.

By doing things this way, you can control the formatting on any ostream -- including doing "console" formatting into a file (for testing). It will also be copied properly between streams if you call copyfmt

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226