无法通过使用boost v.1.48序列化的boost v.1.55反序列化boost::邻接_列表

无法通过使用boost v.1.48序列化的boost v.1.55反序列化boost::邻接_列表,boost,boost-serialization,adjacency-list,Boost,Boost Serialization,Adjacency List,在从v.1.48升级到v.1.55之后,反序列化一些自定义类(使用boost::serialize)变得不可能了。罪魁祸首是boost::Adjacence_list类成员 为了重新创建问题,我尝试序列化(使用boost v.1.48)和反序列化(使用boost v.1.55)一个空的boost::Adjacence_列表,但反序列化失败,自定义输入流类出现异常,如“输入流意外结束” 我还尝试用v.1.48和v.1.55序列化一个空的boost::adjacement_列表,它们的大小不同:分别

在从v.1.48升级到v.1.55之后,反序列化一些自定义类(使用boost::serialize)变得不可能了。罪魁祸首是boost::Adjacence_list类成员

为了重新创建问题,我尝试序列化(使用boost v.1.48)和反序列化(使用boost v.1.55)一个空的boost::Adjacence_列表,但反序列化失败,自定义输入流类出现异常,如“输入流意外结束”

我还尝试用v.1.48和v.1.55序列化一个空的boost::adjacement_列表,它们的大小不同:分别为26和31字节

有人知道是否可以用新的boost::serialization读取旧的数据文件吗

UPD:尝试使用1.48将邻接列表序列化为XML,并使用boost 1.55将其反序列化回来。反序列化失败

自定义邻接列表的简化版本:

struct vertex_data_t
{
    typedef boost::vertex_property_tag kind;
};
typedef int ObjectType;
typedef boost::property<vertex_data_t, ObjectType > Property;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, Property> AdjList;
struct vertex\u data\t
{
typedef boost::vertex_属性_标记种类;
};
typedef int ObjectType;
typedef boost::property属性;
typedef boost::邻接列表邻接列表;
序列化代码:

TEST(BoostSerializationTest148, Test01)
{
    AdjList adjList148;
    std::ofstream fOut("c:/temp/adjList148.xml");
    boost::archive::xml_oarchive(fOut) << BOOST_SERIALIZATION_NVP(adjList148);
}
TEST(BoostSerializationTest155, Test01)
{
    AdjList adjList155;
    std::ofstream fOut("c:/temp/adjList155.xml");
    boost::archive::xml_oarchive(fOut) << BOOST_SERIALIZATION_NVP(adjList155);

    AdjList adjList148;
    std::ifstream fIn("c:/temp/adjList148.xml");
    boost::archive::xml_iarchive(fIn) >> BOOST_SERIALIZATION_NVP(adjList148);  // archive_exception::input_stream_error exception
}
TEST(BoostSerializationTest148,Test01)
{
AdjList adjList148;
std::of stream fOut(“c:/temp/adjList148.xml”);
boost::archive::xml\u oarchive(fOut)boost\u SERIALIZATION\u NVP(adjList148);//归档\u异常::输入\u流\u错误异常
}
adjList148.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="9">
<adjList148 class_id="0" tracking_level="0" version="0">
    <V>0</V>
    <E>0</E>
</adjList148>
</boost_serialization>

0
0
adjList155.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<adjList155 class_id="0" tracking_level="0" version="0">
    <V>0</V>
    <E>0</E>
    <graph_property class_id="1" tracking_level="0" version="0"></graph_property>
</adjList155>
</boost_serialization>

0
0

是的,应该可以。问题可能有两个方面:您的代码或Boost graph代码。(Boost.Serialization中出现问题的可能性较小)

首先,减少问题——排除自定义流

第二,使问题可读——使用XML存档

因此,第一个检查如下:能否使用1.48将邻接列表序列化为XML,并使用boost 1.55将其反序列化回来

此测试的另一种形式:当您将邻接列表序列化为XML时,1.48和1.55的结果应该是等效的(除了一些“版本”属性)。是这样吗

如果此测试通过,则Boost Graph序列化正常。那么问题很可能出现在自定义数据流中。不过,使用XML存档进行调试会更容易

更新:

实际上,当我比较boost/graph/adj_list_serialize.hpp的两个版本的函数加载(…)时,我发现1.55有额外的语句

ar >> serialization::make_nvp("graph_property", 
                    get_property(graph, graph_all_t()) );
我建议你做一些变通。首先,你声明你的类有一个“版本”;第二,加载时,必须根据版本选择1.48和1.55代码

代码可以如下所示:

#include <boost/graph/adj_list_serialize.hpp>
#include <boost/serialization/serialization.hpp>

struct vertex_data_t
{
    typedef boost::vertex_property_tag kind;
};
typedef int ObjectType;
typedef boost::property<vertex_data_t, ObjectType > Property;
typedef boost::adjacency_list<boost::vecS, boost::vecS, 
                 boost::bidirectionalS, Property> AdjList;

BOOST_CLASS_VERSION(AdjList, 1); //default is 0, corresponds to files 
                                 //serialized with Boost 1.48

namespace boost {

namespace serialization {

template<class Archive>
inline void load(
    Archive & ar,
    AdjList &graph,
    const unsigned int file_version
){
  typedef AdjList Graph;
  typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  typedef typename graph_traits<Graph>::edge_descriptor Edge;

  unsigned int V;
  ar >> BOOST_SERIALIZATION_NVP(V);
  unsigned int E;
  ar >> BOOST_SERIALIZATION_NVP(E);

  std::vector<Vertex> verts(V);
  int i = 0;
  while(V-- > 0){
    Vertex v = add_vertex(graph);
    verts[i++] = v;
    ar >> serialization::make_nvp("vertex_property", 
                                  get(vertex_all_t(), graph, v) );
  }
  while(E-- > 0){
    int u; int v;
    ar >> BOOST_SERIALIZATION_NVP(u);
    ar >> BOOST_SERIALIZATION_NVP(v);
    Edge e; bool inserted;
    boost::tie(e,inserted) = add_edge(verts[u], verts[v], graph);
    ar >> serialization::make_nvp("edge_property", 
                                  get(edge_all_t(), graph, e) );
  }
  if (file_version>=1)
      ar >> serialization::make_nvp("graph_property", 
                                     get_property(graph, graph_all_t()) );
}

}
} //namespace boost
#包括
#包括
结构顶点数据
{
typedef boost::vertex_属性_标记种类;
};
typedef int ObjectType;
typedef boost::property属性;
typedef boost::邻接列表邻接列表;
BOOST_CLASS_版本(AdjList,1)//默认值为0,对应于文件
//用Boost 1.48序列化
名称空间提升{
命名空间序列化{
模板
线内空隙荷载(
存档和ar,
调整列表和图表,
常量无符号整数文件\u版本
){
类型列表图;
typedef typename图形\特征::顶点\描述符顶点;
typedef typename图形\特征::边\描述符边;
无符号整数V;
ar>>增压(V);
无符号整数E;
ar>>BOOST\u序列化\u NVP(E);
std::向量顶点(V);
int i=0;
而(V-->0){
顶点v=添加_顶点(图);
顶点[i++]=v;
ar>>序列化::生成nvp(“顶点属性”,
获取(顶点_all_t(),图,v));
}
而(E-->0){
INTU;INTV;
ar>>增强串行化NVP(u);
ar>>增压(v);
边e;布尔插入;
boost::tie(e,inserted)=添加边(顶点[u],顶点[v],图形);
ar>>序列化::生成nvp(“边缘属性”,
获取(边,图,e));
}
如果(文件版本>=1)
ar>>序列化::生成nvp(“图形属性”,
get_属性(graph,graph_all_t());
}
}
}//名称空间提升

加载旧文件时,此代码不会加载“graph_属性”(与1.48相同);加载新创建的归档文件时,它将按照1.55的方式工作。

谢谢您的回答。尝试按照您的建议进行简化测试,但反序列化仍然失败,在我的初始帖子中添加了测试信息。