【问题标题】:Serialization of a graph with specific vertex type具有特定顶点类型的图的序列化
【发布时间】:2018-01-25 13:54:27
【问题描述】:

我想对使用 BGL 存储的图形进行磁盘 I/O。我正在使用 boost::serialization。

首先,一些可以编译的代码:

typedef boost::adjacency_list<
    boost::vecS
    ,boost::vecS
    ,boost::undirectedS
    > graph_t;

int main()
{
    graph_t g;

    std::ifstream ifs( "file_in" );          // read from file
    boost::archive::text_iarchive ia( ifs );
    ia >> g;    

    std::ofstream ofs( "file_out" );        // save to file
    boost::archive::text_oarchive oa( ofs );
    oa << g;
}

现在,我需要将数据存储到我的顶点中。所以我重新定义了我的图表:

struct myVertex
{
    int a;
    float b;
};

typedef boost::adjacency_list<
    boost::vecS,
    boost::vecS,
    boost::undirectedS,
    myVertex
    > graph_t;

当然,我需要定义如何序列化myVertex。由于我不想混淆该数据结构,因此我想使用非侵入式方式,因为它是described in the manual

因此,按照手册中的说明,我添加了所需的功能:

namespace boost {
namespace serialization {

    template<class Archive>
    void serialize( Archive& ar, const myVertex& mv, const unsigned int version )
    {
        ar & mv.a;
        ar & mv.b;
    }

} // namespace serialization
} // namespace boost

不幸的是,这不能编译:编译器抱怨缺少序列化函数:

错误:‘struct myVertex’没有名为‘serialize’的成员

Live code on Coliru

我对此的理解是,内部 BGL 数据结构提供了一个序列化函数,它本身依赖于顶点(显然还有边)的类成员序列化函数。并且它不能使用外部序列化函数。

请注意,如果我使用所谓的“侵入式”方式(将序列化函数添加为类成员),它确实构建得很好,但我想知道它是否可以按照上面的说明完成.

【问题讨论】:

    标签: c++ serialization boost boost-graph


    【解决方案1】:

    您应该将参数声明为非常量:

    template <class Archive> void serialize(Archive &ar, myVertex &mv, unsigned /*version*/) {
    

    现场演示

    Live On Coliru

    #include <boost/archive/text_iarchive.hpp>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/graph/adj_list_serialize.hpp>
    #include <boost/graph/adjacency_list.hpp>
    #include <fstream>
    
    struct myVertex {
        int a;
        float b;
    };
    
    namespace boost {
        namespace serialization {
            template <class Archive> void serialize(Archive &ar, myVertex &mv, unsigned /*version*/) {
                ar & mv.a & mv.b;
            }
        } // namespace serialization
    } // namespace boost
    
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, myVertex> graph_t;
    
    #include <iostream>
    int main(int argc, char**) {
    
        if (argc>1) {
            graph_t g;
            std::ifstream ifs("file_out"); // read from file
            boost::archive::text_iarchive ia(ifs);
            ia >> g;
    
            std::cout << "Read " << num_vertices(g) << " vertices\n";
        }
    
        {
            graph_t g(100);
            std::ofstream ofs("file_out"); // save to file
            boost::archive::text_oarchive oa(ofs);
            oa << g;
        }
    }
    

    打印:

    ./a.out
    ./a.out read_as_well
    Read 100 vertices
    

    【讨论】:

    • 你太强了!再次感谢。我想我最初添加了 const (甚至在手册中都没有!!!!)因为我认为“写作”,因此我习惯的“到处都设置最大值”的习惯让我添加了。
    • 关键是我们仍然存在编译器给出不充分错误消息的问题......我被它愚弄了,以为“我需要重新定义图形的序列化方式”,这并不明显案子。我希望编译器的人能够改进。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    相关资源
    最近更新 更多