如果有某种std::istream::read
的通用版本,我会喜欢它,所以我可以这样做:
ClassA func( std::istream& is ) {
ClassA a;
is.read(a);
return a;
}
或
ClassA func( std::istream& is ) {
return is.read<ClassA>();
}
或者甚至可能:
ClassA::ClassA( std::istream& is ) {
is.read(data_member);
}
但我总是要补充我自己的通用定义,如下所示:
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;
};
在执行此操作时,我必须提供流作为参数,因为它似乎应该是流对象上的方法。
load(a.data_member, is);
// vs
is.read(a.data_member);
我有一种感觉,也许我错误地想到了这个问题,或者甚至想要这样的事情也许是愚蠢的。我认为当编译器可以推断它时,我必须告诉read()
关于读取的大小是愚蠢的。
有更好的方法吗?
答案 0 :(得分:2)
您的load
功能没有任何问题,请记住它只适用于POD类型,因此您应该添加:
static_assert(std::is_standard_layout<T>::value, "A must be a POD type.");
另外,请记住打开流上的异常,否则根本不会收到任何错误报告 - 这可能就是为什么流不提供这种首先读取结构的方式。
答案 1 :(得分:1)
一种选择是简单地包装流。沿着这些方向的东西(未经测试):
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;
}
}
当你打开你的流时,只需将它放在ObjectStream
内并传递它而不是你的istream - 现在你只需要通过stream >> obj
来读取一个对象,类似于istream重载>>
。
当然,如果您愿意,也可以使用常规实例方法。