Reputation: 4368
I'd love it if there was some kind of generic version of std::istream::read
, so I could do this:
ClassA func( std::istream& is ) {
ClassA a;
is.read(a);
return a;
}
or
ClassA func( std::istream& is ) {
return is.read<ClassA>();
}
or maybe even:
ClassA::ClassA( std::istream& is ) {
is.read(data_member);
}
But I always have to supplement my own generic definitions like so:
template< class T >
void load( T& v, std::istream& is ) {
is.read((char*)&v, sizeof(v));
};
template< class T >
T load( std::istream& is ) {
T v;
is.read((char*)&v, sizeof(v));
return v;
};
In doing this, I have to provide the stream as a parameter when it seems like maybe it should be a method on a stream object.
load(a.data_member, is);
// vs
is.read(a.data_member);
I have a feeling that maybe I'm thinking about this problem incorrectly or that maybe it's stupid to even want this sort of thing. I think it's silly that I have to tell read()
about the size of the read when the compiler can infer it generically.
Is there a better way?
Upvotes: 2
Views: 562
Reputation: 6999
There's nothing wrong with your load
function, just remember that it only works with POD types, so you should add:
static_assert(std::is_standard_layout<T>::value, "A must be a POD type.");
Also, remember to turn on exceptions on your streams, or you won't get any error reporting at all - which is probably why streams don't provide such a way of reading into structs in the first place.
Upvotes: 2
Reputation: 55009
One option would be to simply wrap the stream. Something along these lines (not tested):
class ObjectStream
{
std::istream& _is;
public:
ObjectStream(std::istream& _is) : _is(is) {};
template <class T>
ObjectStream& operator>>(T& v) {
_is.read((char*)&v, sizeof(T));
return *this;
}
}
When you open your stream, simply put it inside an ObjectStream
and pass that around instead of your istream - now you're able to read an object simply by doing stream >> obj
, similar to how istream overloads >>
.
Of course, you can also just use a regular instance method if you prefer that.
Upvotes: 1