Mohan Mohan - 3 months ago 27
C++ Question

Moving a class derived from istream

I'm creating a C++

istream
with a custom
streambuf
. Trying to move this fails because the istream move constructor is protected. To get round I derived a class from
istream
:

struct VectorCharBuf : public streambuf {
VectorCharBuf(vector<char>& v) {
setg(v.data(), v.data(), v.data() + v.size());
}
};

struct IVectorCharStream : public istream {
IVectorCharStream(VectorCharBuf* contents_buf) : istream(contents_buf) {}
};


The default move constructor for this class is not generated because it involves the


use of deleted function 'std::basic_ios<_CharT, _Traits>::basic_ios(const std::basic_ios<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits]'


Further, if I try to declare a move constructor explicitly, as in

struct MyIStream : public istream {
MyIStream(MyIStream&& str) : istream(move(str)) {}
};


I get an error "invalid use of void expression". (I'm probably doing something silly in this last case, but I just can't spot it... .)

How can I create a movable
istream
?

Answer
struct MyIStream : public istream {
    MyIStream(MyIStream&& str) : istream(move(str)) {}
};

I get an error "invalid use of void expression".

This doesn't work because basic_ios, a base class of istream contains a member function void move(basic_ios& _Other) (for moving the base class).

If you use std::move(str) in the constructor, it compiles!