【问题标题】:BGL adjacency_list<listS, listS>::vertex_descriptor evaluates to void*BGL adjacency_list<listS, listS>::vertex_descriptor 计算为 void*
【发布时间】:2015-08-29 10:38:07
【问题描述】:

boost::graph_traits&lt;graph_type&gt;::vertex_descriptor&gt; vertex_map_type 计算结果为 void*boost::listS 用于VertexListS

以下代码无法编译。但是使用 vecS 而不是 listS 可以。

#include <iostream>
#include <fstream>
#include <map>
#include <list>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/adj_list_serialize.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/map.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_serialize.hpp>

typedef boost::adjacency_list<
    boost::listS,
    boost::listS, // << ------ vecS works but listS or setS doesn't !!
    boost::bidirectionalS> graph_type;
typedef std::map<boost::uuids::uuid, typename boost::graph_traits<graph_type>::vertex_descriptor> vertex_map_type;

int main(){
    graph_type graph;
    vertex_map_type map;
    std::ofstream stream("archive");
    boost::archive::binary_oarchive archive(stream);
    archive << graph;
    archive << map;
    return 0;
}

由于void*而无法编译

$ g++ graph.cpp -o graph -lboost_graph -lboost_serialization
In file included from /usr/include/boost/archive/detail/interface_oarchive.hpp:23:0,
                 from /usr/include/boost/archive/detail/common_oarchive.hpp:22,
                 from /usr/include/boost/archive/basic_binary_oarchive.hpp:34,
                 from /usr/include/boost/archive/binary_oarchive_impl.hpp:23,
                 from /usr/include/boost/archive/binary_oarchive.hpp:21,
                 from graph.cpp:9:
/usr/include/boost/archive/detail/oserializer.hpp: In instantiation of ‘static void boost::archive::detail::save_pointer_type<Archive>::invoke(Archive&, TPtr) [with TPtr = void*; Archive = boost::archive::binary_oarchive]’:
/usr/include/boost/archive/detail/oserializer.hpp:525:24:   required from ‘void boost::archive::save(Archive&, T&) [with Archive = boost::archive::binary_oarchive; T = void* const]’
/usr/include/boost/archive/detail/common_oarchive.hpp:69:40:   required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = void* const; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/basic_binary_oarchive.hpp:75:7:   required from ‘void boost::archive::basic_binary_oarchive<Archive>::save_override(const T&, int) [with T = void*; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/binary_oarchive_impl.hpp:51:9:   required from ‘void boost::archive::binary_oarchive_impl<Archive, Elem, Tr>::save_override(T&, int) [with T = void* const; Archive = boost::archive::binary_oarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:63:9:   required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = void* const; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/serialization/nvp.hpp:79:9:   [ skipping 52 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/oserializer.hpp:525:24:   required from ‘void boost::archive::save(Archive&, T&) [with Archive = boost::archive::binary_oarchive; T = const std::map<boost::uuids::uuid, void*>]’
/usr/include/boost/archive/detail/common_oarchive.hpp:69:40:   required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = const std::map<boost::uuids::uuid, void*>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/basic_binary_oarchive.hpp:75:7:   required from ‘void boost::archive::basic_binary_oarchive<Archive>::save_override(const T&, int) [with T = std::map<boost::uuids::uuid, void*>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/binary_oarchive_impl.hpp:51:9:   required from ‘void boost::archive::binary_oarchive_impl<Archive, Elem, Tr>::save_override(T&, int) [with T = std::map<boost::uuids::uuid, void*>; Archive = boost::archive::binary_oarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:63:9:   required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = std::map<boost::uuids::uuid, void*>; Archive = boost::archive::binary_oarchive]’
graph.cpp:27:13:   required from here
/usr/include/boost/archive/detail/oserializer.hpp:465:27: error: ‘void*’ is not a pointer-to-object type
         register_type(ar, * t);
                           ^
/usr/include/boost/archive/detail/oserializer.hpp:473:18: error: ‘void*’ is not a pointer-to-object type
         save(ar, * t);

See it on coliru

【问题讨论】:

    标签: c++ dictionary boost stl boost-graph


    【解决方案1】:

    没错。它确实评估为不透明的整数类型。这是设计使然,并已记录在案。

    vecS 具有连续存储,但 listSsetS (etc) 具有迭代器稳定性。您可以选择您的应用所需的内容。

    这意味着您需要一个 ID(BGL 算法为此使用 vertex_index_t 属性)。或者,只需使用内置的序列化支持。

    #include <boost/archive/binary_oarchive.hpp>
    #include <boost/graph/adj_list_serialize.hpp>
    #include <boost/graph/adjacency_list.hpp>
    #include <boost/uuid/uuid.hpp>
    #include <boost/uuid/uuid_serialize.hpp>
    #include <fstream>
    
    typedef boost::adjacency_list<
        boost::listS, boost::listS, boost::bidirectionalS,
        boost::property<boost::vertex_index_t, boost::uuids::uuid>
    > graph_type;
    
    int main(){
        graph_type graph;
    
        std::ofstream stream("archive");
        boost::archive::binary_oarchive archive(stream);
        archive << graph;
    }
    

    【讨论】:

    • 嗯,我需要存储一个 uuid 和顶点索引的映射。那我应该改用typedef std::map&lt;boost::uuids::uuid, typename boost::graph_traits&lt;graph_type&gt;::vertex_descriptor&gt; vertex_index_t; 吗?
    • ?!哇。为什么命名 typedef 会有所不同(我的意思是,c++ 有一些晦涩难懂的特性,但这不是其中之一)
    • 添加了一个 sn-p 显示我会考虑的内容。当然,现在您已经发现确实无法完成您想做的事情,所以有一个健康剂量的X/Y problem。无论如何,即使我的建议不是直接命中,你也需要开箱即用。您根本不能使用 Boost 序列化来(有用地)序列化 void*
    • 抱歉,我认为boost::graph_traits&lt;graph_type&gt;::vertex_index_t 会起作用
    • 但是我将如何创建一个 vertex_index ?我需要add_vertex 并将其存储在std::map 中。但是 add_vertex() 只返回 vertex_descriptor。
    猜你喜欢
    • 1970-01-01
    • 2013-11-30
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    相关资源
    最近更新 更多