I am designing an interface for reading and writing video frames to various inputs and outputs. Stream operators seem to me a superb alternative to named functions for the task. This is the gist of it:

struct FrameSource
    virtual FrameSource & operator>>( cv::Mat & frame ) = 0;
    virtual ~FrameSource() = default;

struct FrameSink
    virtual FrameSink & operator<<( const cv::Mat & frame ) = 0;
    virtual ~FrameSink() = default;

Now, supposing this is an OK design, how should I signal end of stream (end of video; last picture in the folder; deinitialized camera)?

The options I have considered:

  • EndOfIteration exception, like in python. Sounds slow, dangerous and not idiomatic. No way to indicate this behaviour in the header.
  • Return cv::Mat{}. Sounds slow, easy to miss(leading to infinite loops), violates the invariant that any frame can be returned, not idiomatic.
  • cv::Mat f; while(stream.get(f)); idiomatic but involves named functions, return status easy to miss.
  • A variation of the above via the conversion operator operator bool() const;.
  • Derive from std::basic_i/ostream. But those are character based.
  • Derive from iterator and provide begin(), end().

My application doesn't mandate streams, I am using them because of the subjective advantages of:

  • ease of use
  • not having to hold a bunch of large files in working memory simultaneously.
  • Do you need to distinguish between end-of-stream and error? Feb 20, 2019 at 12:08
  • @ChristianHackl yes, I am using a simple struct Exception : public runtime_error {}; for the latter.
    – Vorac
    Feb 20, 2019 at 12:13
  • You mention the advantage "not having to hold a bunch of large files in working memory simultaneously". This has absolutely nothing to do with using stream-operators vs using named functions: A stream-operator is still a function call, just like a named function, so both methods can achieve exactly the same things.
    – pschill
    Feb 22, 2019 at 8:22
  • @pschill streams as opposed to an iterable vector.
    – Vorac
    Feb 22, 2019 at 8:24
  • @Vorac You can program something that behaves like a stream even if you use named functions instead of the stream operators. I think that helps the user to understand what happens and allows you to use additional arguments (e.g., a bool& end_of_stream argument which cannot be ignored like a return value). If you really want to stick to operator<< and operator>>, you should probably use them in a standard-fashion: Provide some operator bool() which allows the common while (stream >> value) pattern.
    – pschill
    Feb 22, 2019 at 8:31

1 Answer 1


If you want to provide a stream-like interface, I would strongly recommend to provide an interface that is comparable to that provided by std::basic_i/ostream. For error reporting (including EOF), this would involve the member functions operator! and operator bool (which in std::basic_i/ostream are based on the member functions good, eof, fail, bad).

  • 3
    Isn't the standard I/O streams interface known to be hard to use and overly complicated? The difference or relationship between good, eof, fail and bad are especially hard to grasp and memorise, and the names are really bad (IMO). For the sake of simplicity, it might be better if the OP just provided operator bool, because that seems to be enough for his use case. Feb 20, 2019 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.