我正在尝试反序列化没有默认构造函数的对象。我已经看到你可以通过将存档传递给构造函数来实现这一点。但是,当我这样做时,似乎没有正确读取数据?以下是一个示例 - Works()
输出" 1 2"应该(使用默认构造函数和运算符>>),但DoesntWork()
输出" 0 0"。我已经介入,一切似乎都得到了适当的调用。谁能解释这两个函数之间的区别呢?
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
class Point
{
private:
friend class boost::serialization::access;
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
{
archive & mX;
archive & mY;
}
public:
template<class TArchive>
Point(TArchive& archive)
{
serialize(archive, 0);
}
Point(){} // Only provided to test Works()
Point(const float x, const float y) : mX(x), mY(y) { }
float mX = 4;
float mY = 5;
};
void Works()
{
std::cout << "Works():" << std::endl;
Point p(1,2);
std::ofstream outputStream("test.archive");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << p;
outputStream.close();
// read from a text archive
std::ifstream inputStream("test.archive");
boost::archive::text_iarchive inputArchive(inputStream);
Point pointRead;
inputArchive >> pointRead;
std::cout << pointRead.mX << " " << pointRead.mY << std::endl;
}
void DoesntWork()
{
std::cout << "DoesntWork():" << std::endl;
Point p(1,2);
std::ofstream outputStream("test.archive");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << p;
outputStream.close();
std::ifstream inputStream("test.archive");
boost::archive::text_iarchive inputArchive(inputStream);
Point pointRead(inputArchive);
std::cout << pointRead.mX << " " << pointRead.mY << std::endl;
}
int main()
{
Works(); // Output "1 2"
DoesntWork(); // Output "0 0"
return 0;
}
答案 0 :(得分:1)
您不应该直接调用serialize
方法:operator >>
存档方式不仅仅是调用serialize
;它取决于首先需要加载序言等的归档类型。你可以通过调试器来检查这一点,或者通过检查test.archive里面的内容,它就像
22 serialization::archive 12 0 0 1.000000000e+000 2.000000000e+000
所以在构建text_iarchive
之后,对operator &
的前两次调用恰好会在那里看到那些0
而不是实际数据。
你的构造函数应该是:
template<class TArchive>
Point(TArchive& archive)
{
archive >> *this;
}
编辑这是一个如何使用SFINAE来确保仍然可以调用复制构造函数的示例
Point( const Point& rh ) :
mX( rh.mX ),
mY( rh.mY )
{
}
template<class TArchive>
Point( TArchive& archive,
std::enable_if_t< !std::is_same< TArchive, Point >::value >* = nullptr )
{
archive >> *this;
}