反序列化类型的STL容器没有默认构造函数 [英] Deserializing STL container of type with no default constructor

查看:162
本文介绍了反序列化类型的STL容器没有默认构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近学到的反序列化的构造格局(<一个href=\"http://stackoverflow.com/questions/35722135/deserializing-construtor-doesnt-read-data-correctly\">Deserializing构造不能正确的)读出的数据,以使用序列与不具有默认构造类型。现在我想要序列化这些对象的一个​​STL容器中,如下面的例子:

 的#include&LT;升压/存档/ text_oarchive.hpp&GT;
#包括LT&;升压/存档/ text_iarchive.hpp&GT;
#包括LT&;升压/系列化/ split_member.hpp来&GT;
#包括LT&;升压/系列化/ vector.hpp&GT;#包括LT&;&的fstream GT;类Point
{
上市:
    点(双X):MX(X){}    模板&LT;类TArchive&GT;
    点(TArchive&安培;存档)
    {
        归档&GT;&GT; *这个;
    }    模板&LT;类TArchive&GT;
    无效连载(TArchive&安培;归档,const的无符号整型版)
    {
        归档和放大器; MX;
    }    双MX;
};诠释的main()
{
    的std ::矢量&lt;点和GT; pointVector;
    pointVector.push_back(点(1));
    pointVector.push_back(点(2));    的std ::的ofstream的OutputStream(的test.txt);
    提高::档案:: text_oarchive的outputArchive(OutputStream中);    outputArchive&LT;&LT; pointVector;
    outputStream.close();    的std ::矢量&lt;点和GT; readPointVector;
    性病:: ifstream的InputStream的(的test.txt);
    提高::档案:: text_iarchive inputArchive(InputStream的);
    inputArchive&GT;&GT; readPointVector; //编译器错误 - 没有匹配的函数调用点::点()    返回0;
}

似乎很清楚,这不应该工作,但我怎么会知道,它需要将它们添加到容器之前使用反序列化的构造函数构造它读取对象的档案?

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

在唯一的答案实施的建议后,此code编译罚款,但似乎并没有正确地反序列化。在 readPointVector 只有大小为1,但它应该有大小2(和数据是不正确的一个对象,它并包含):

 的#include&LT;升压/存档/ text_oarchive.hpp&GT;
#包括LT&;升压/存档/ text_iarchive.hpp&GT;
#包括LT&;升压/系列化/ vector.hpp&GT;#包括LT&;&的fstream GT;类Point
{
上市:
    点(双X):MX(X){}    模板&LT;类TArchive&GT;
    点(TArchive&安培;存档)
    {
        归档&GT;&GT; *这个;
    }    模板&LT;类TArchive&GT;
    无效连载(TArchive&安培;归档,const的无符号整型版)
    {
        归档和放大器; MX;
    }    双MX;
};模板&LT; typename的归档和GT;
归档和放大器;运营商的GT;&GT; (归档和放大器;归档的std ::矢量&lt;点和GT;&安培;分)
{
    points.emplace_back(存档);
    返回档案;
}诠释的main()
{
    的std ::矢量&lt;点和GT; pointVector;
    pointVector.push_back(点(5.6));
    pointVector.push_back(点(7.8));    性病::法院LT&;&LT; pointVector.size()&所述;&下;的std :: ENDL; //输出2    {
        的std ::的ofstream的OutputStream(的test.txt);
        提高::档案:: text_oarchive的outputArchive(OutputStream中);        outputArchive&LT;&LT; pointVector;
        outputStream.close();
    }    的std ::矢量&lt;点和GT; readPointVector;
    性病:: ifstream的InputStream的(的test.txt);
    提高::档案:: text_iarchive inputArchive(InputStream的);
    inputArchive&GT;&GT; readPointVector;    性病::法院LT&;&LT; readPointVector.size()&所述;&下;的std :: ENDL; //输出1(和readPointVector [0] .MX是2,但应该是7.8)    返回0;
}


解决方案

您可以专门为点的矢量:

 模板&LT; typename的归档和GT;
归档和放大器;运营商的GT;&GT; (归档和放大器;归档的std ::矢量&lt;点和GT;&安培;分)
{
    points.emplace_back(存档);
    返回档案;
}

I've recently learned the pattern of the deserializing constructor (Deserializing constructor doesn't read data correctly) to use serialization with types that do not have default constructors. Now I'm trying to serialize an STL container of these objects, as in the example below:

#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;
}

It seems clear that this shouldn't work, but how would I tell the archive that it needs to use the deserializing constructor to construct the objects that it reads before adding them to the container?

---------- EDIT ----------

After implementing the suggestion in the only answer, this code compiles fine, but doesn't seem to deserialize correctly. The readPointVector only has size 1 but it should have size 2 (and the data is not correct in the one object that it does contain):

#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;
}

解决方案

You may specialize for vector of Points:

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

这篇关于反序列化类型的STL容器没有默认构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆