2

如果有某种通用版本,我会喜欢的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()我认为当编译器可以一般地推断出读取的大小时,我必须告诉它是愚蠢的。

有没有更好的办法?

4

2 回答 2

2

您的函数没有任何问题,请load记住它仅适用于 POD 类型,因此您应该添加:

static_assert(std::is_standard_layout<T>::value, "A must be a POD type.");

另外,请记住在您的流上打开异常,否则您根本不会收到任何错误报告——这可能就是为什么流首先不提供这种读取结构的方式的原因。

于 2013-06-04T16:08:15.347 回答
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;
  }
}

当您打开您的流时,只需将它放在 anObjectStream中并传递它而不是您的 istream - 现在您可以通过 do 来读取对象stream >> obj,类似于 istream 重载的方式>>

当然,如果您愿意,也可以只使用常规实例方法。

于 2013-06-04T16:05:24.450 回答