我有一堆结构可以从各种文件中读取,以避免为每一个文件定义重复的operator>>
和operator<<
,我考虑使用以下内容:
#include <fstream>
#pragma pack(push, 1)
template<typename Derived>
struct Base
{
friend std::istream& operator>>(std::istream& stream, Base& base)
{
return stream.read(reinterpret_cast<char*>(&base), sizeof(Derived));
}
friend std::ostream& operator<<(std::ostream& stream, Base const& base)
{
return stream.write(reinterpret_cast<char const*>(&base), sizeof(Derived));
}
};
struct Foo : public Base<Foo>
{
int32_t i;
int8_t j, k, l;
uint16_t m;
};
struct Bar : public Base<Bar>
{
int32_t i;
uint16_t m;
};
#pragma pack(pop)
int main()
{
Foo foo;
Bar bar;
std::ifstream("foobarout", std::ios::binary) >> foo >> bar;
std::ofstream("foobarout", std::ios::binary) << foo << bar;
}
正在读取/复制像上面这样的简单POD对象,使用指向其基类的定义明确(至少在我正在运行的单个平台的范围内,我意识到这不一定是可移植的),或者我在薄冰上行走吗?
答案 0 :(得分:3)
我认为这不是一个好的解决方案。
它可以工作,但是从客户端实现者的角度看,你看起来会定义这些运算符,但是它们依赖于二进制模式的流(这不是你的接口明确或建议的 - 不要这样做)它需要使用reinterpret_cast(也不要这样做)。您对POD类型的限制也将被隐藏,除非您在某处删除评论(“// DO NOT declare non-POD types here
”)。
如果添加非POD类型(或使用非二进制流),则生成的错误将是静默数据损坏。
你最好为每个人单独实施一个;这也不会对使用POD施加任何限制,并且实施将尊重最少惊喜的原则。
答案 1 :(得分:0)
根据您的使用情况,您可能还需要查看Boost Serialization Library。虽然这对于简单的用例来说似乎有些过分,但我发现这个库非常灵活,可以存储不同复杂程度的对象。