反序列化没有默认构造函数的类型的STL容器

时间:2016-03-01 20:03:02

标签: c++ boost boost-serialization

我最近学习了反序列化构造函数(Deserializing constructor doesn't read data correctly)的模式,以便对没有默认构造函数的类型使用序列化。现在我尝试序列化这些对象的STL容器,如下例所示:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/vector.hpp>

#include <fstream>

class Point
{
public:
    Point(double x) : mX(x) {}

    template<class TArchive>
    Point(TArchive& archive)
    {
        archive >> *this;
    }

    template<class TArchive>
    void serialize(TArchive& archive, const unsigned int version)
    {
        archive & mX;
    }

    double mX;
};

int main()
{
    std::vector<Point> pointVector;
    pointVector.push_back(Point(1));
    pointVector.push_back(Point(2));

    std::ofstream outputStream("test.txt");
    boost::archive::text_oarchive outputArchive(outputStream);

    outputArchive << pointVector;
    outputStream.close();

    std::vector<Point> readPointVector;
    std::ifstream inputStream("test.txt");
    boost::archive::text_iarchive inputArchive(inputStream);
    inputArchive >> readPointVector; // Compiler error - no matching function call to Point::Point()

    return 0;
}

很明显,这不应该工作,但是如何告诉存档它需要使用反序列化构造函数来构造它在将它们添加到容器之前读取的对象?

----------编辑----------

在唯一的答案中实现建议后,此代码编译良好,但似乎没有正确反序列化。 readPointVector只有1大小但它的大小应该是2(并且它包含的一个对象中的数据不正确):

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/vector.hpp>

#include <fstream>

class Point
{
public:
    Point(double x) : mX(x) {}

    template<class TArchive>
    Point(TArchive& archive)
    {
        archive >> *this;
    }

    template<class TArchive>
    void serialize(TArchive& archive, const unsigned int version)
    {
        archive & mX;
    }

    double mX;
};

template <typename Archive>
Archive& operator >> (Archive& archive, std::vector<Point>& points)
{
    points.emplace_back(archive);
    return archive;
}

int main()
{
    std::vector<Point> pointVector;
    pointVector.push_back(Point(5.6));
    pointVector.push_back(Point(7.8));

    std::cout << pointVector.size() << std::endl; // outputs 2

    {
        std::ofstream outputStream("test.txt");
        boost::archive::text_oarchive outputArchive(outputStream);

        outputArchive << pointVector;
        outputStream.close();
    }

    std::vector<Point> readPointVector;
    std::ifstream inputStream("test.txt");
    boost::archive::text_iarchive inputArchive(inputStream);
    inputArchive >> readPointVector;

    std::cout << readPointVector.size() << std::endl; // outputs 1 (and readPointVector[0].mX is 2, but should be 7.8)

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您可以专注于积分矢量:

template <typename Archive>
Archive& operator >> (Archive& archive, std::vector<Point>& points)
{
    points.emplace_back(archive);
    return archive;
}