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 providebegin(), 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.
struct Exception : public runtime_error {};
for the latter. – Vorac Feb 20 '19 at 12:13bool& 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 someoperator bool()
which allows the commonwhile (stream >> value)
pattern. – pschill Feb 22 '19 at 8:31