boost 子图给出“形成对 void 的引用”错误

问题描述 投票:0回答:1

我正在尝试创建

boost::subgraph
boost::adjacency_list
,但我在创建时遇到了一个我不明白的错误。专门使用
boost::adjacency_list
的类似代码可以构建并正常工作。

创建

base_graph
的行足以解决该错误,但其余部分演示了我如何单独使用
adjacency_list
,以及我期望如何使用
subgraph

示例代码:

struct Component { int vert_id; };
struct Connection { int edge_id; };
struct NetworkData { int graph_id; };

boost::subgraph<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Component, Connection, NetworkData>> base_graph;

auto& sub_graph = base_graph.create_subgraph();

base_graph[boost::graph_bundle].graph_id;
sub_graph[boost::graph_bundle].graph_id;

const auto base_vert = boost::add_vertex(base_graph);
const auto sub_vert = boost::add_vertex(sub_graph);
base_graph[base_vert].vert_id;
base_graph[sub_vert].vert_id;
sub_graph[base_vert].vert_id;
sub_graph[sub_vert].vert_id;

const auto [base_edge, a1] = boost::add_edge(base_vert, sub_vert, base_graph);
const auto [sub_edge, a2] = boost::add_edge(base_vert, sub_vert, sub_graph);
base_graph[base_edge].edge_id;
base_graph[sub_edge].edge_id;
sub_graph[base_edge].edge_id;
sub_graph[sub_edge].edge_id;

错误日志:

In file included from /.../include/boost/graph/adjacency_list.hpp:255,
                 from /.../main.cpp:1:
/.../include/boost/graph/detail/adjacency_list.hpp: In instantiation of ‘struct boost::detail::adj_list_any_edge_pmap::bind_<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Component, Connection, NetworkData>, Connection, boost::edge_index_t>’:
/.../include/boost/graph/detail/adjacency_list.hpp:2801:12:   required from ‘struct boost::detail::adj_list_choose_edge_pmap<boost::edge_index_t, boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Component, Connection, NetworkData>, Connection>’
/.../include/boost/graph/detail/adjacency_list.hpp:2809:16:   required from ‘struct boost::detail::adj_list_edge_property_selector::bind_<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Component, Connection, NetworkData>, Connection, boost::edge_index_t>’
/.../include/boost/graph/properties.hpp:218:12:   required from ‘struct boost::detail::edge_property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Component, Connection, NetworkData>, boost::edge_index_t>’
/.../include/boost/graph/properties.hpp:234:8:   required from ‘struct boost::property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Component, Connection, NetworkData>, boost::edge_index_t, void>’
/.../include/boost/graph/subgraph.hpp:351:64:   required from ‘class boost::subgraph<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, Component, Connection, NetworkData> >’
/.../main.cpp:46:122:   required from here
/.../include/boost/graph/detail/adjacency_list.hpp:2764:33: error: forming reference to void
 2764 |             typedef value_type& reference;
      |                                 ^~~~~~~~~
/.../include/boost/graph/detail/adjacency_list.hpp:2765:39: error: forming reference to void
 2765 |             typedef const value_type& const_reference;
      |                                       ^~~~~~~~~~~~~~~
/.../include/boost/graph/detail/adjacency_list.hpp:2770:17: error: forming reference to void
 2770 |                 type;
      |                 ^~~~
/.../include/boost/graph/detail/adjacency_list.hpp:2774:17: error: forming reference to void
 2774 |                 const_type;
      |                 ^~~~~~~~~~

vert_id
edge_id
graph_id
都是概念性的,用于演示我预期如何访问节点/边缘数据。

我发现如果我将

Connection
更改为
boost::property<boost::edge_index_t, std::size_t>
它将构建。但这会阻止访问
graph_bundle
,并且导致访问边缘属性不太方便,而且我不知道如何使用
boost::property

我还审查了这个SO问题这个SO问题,但他们不使用

subgraph
,我的问题似乎与
subgraph
特别相关。

我使用 GCC13 和 MSVC 时遇到类似的错误。

c++ boost boost-graph
1个回答
0
投票

子图需要vertex_index和edge_index:doc

图形类型建模

VertexMutableGraph
EdgeMutableGraph
。此外,该图必须具有内部
vertex_index
edge_index
属性。顶点索引必须由图自动维护,而边索引将由子图类实现分配

自动宣传此属性的最简单方法是使用内部属性标签而不是您的捆绑包类型:

// struct Connection { int edge_id; };
using Connection = boost::property<boost::edge_index_t, int>;

确实,经过一些修改,效果如下:

住在Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/subgraph.hpp>

struct Component {
    int vert_id;
};

#ifndef CUSTOM_PROPERTY_MAPS
    using Connection = boost::property<boost::edge_index_t, int>;
#else
    struct Connection {
        int edge_id;
    };
#endif

struct NetworkData {
    int graph_id;
};

using G   = boost::adjacency_list<                //
    boost::vecS, boost::vecS, boost::directedS, //
    Component,                                  //
    Connection,                                 //
    NetworkData                                 //
    >;
using Sub = boost::subgraph<G>;

int main() {
    Sub base_graph;

    auto& sub_graph = base_graph.create_subgraph();

    get_property(base_graph).graph_id;
    get_property(sub_graph).graph_id;

    auto const base_vert = add_vertex(base_graph);
    auto const sub_vert  = add_vertex(sub_graph);
    base_graph[base_vert].vert_id;
    base_graph[sub_vert].vert_id;
    sub_graph[base_vert].vert_id;
    sub_graph[sub_vert].vert_id;

    auto const [base_edge, a1] = add_edge(base_vert, sub_vert, base_graph);
    auto const [sub_edge, a2]  = add_edge(base_vert, sub_vert, sub_graph);

#ifndef CUSTOM_PROPERTY_MAPS
    auto bmi = get(boost::edge_index, base_graph);
    auto smi = get(boost::edge_index, sub_graph);
    bmi[base_edge];
    smi[sub_edge];
#else
    base_graph[base_edge].edge_id;
    // base_graph[sub_edge].edge_id; // UB!?
    // sub_graph[base_edge].edge_id; // UB!?
    sub_graph[sub_edge].edge_id;
#endif
}

如果你坚持

您可能会坚持捆绑属性。在这种情况下,您必须调整所需的特征来告诉

subgraph
有关边缘索引的信息:

namespace Lib {
    struct Component   { int vert_id;     };
    struct Connection  { int edge_id = 0; };
    struct NetworkData { int graph_id;    };

    using G = boost::adjacency_list<                //
        boost::vecS, boost::vecS, boost::directedS, //
        Component,                                  //
        Connection,                                 //
        NetworkData                                 //
        >;

} // namespace Lib

template <>
struct boost::property_map<Lib::G, boost::edge_index_t>
    : boost::property_map<Lib::G, decltype(&Lib::Connection::edge_id)> {};

namespace Lib {
    // ADL accessible
    static inline auto get(boost::edge_index_t, G const& g) { return boost::get(&Connection::edge_id, g); }
    static inline auto get(boost::edge_index_t, G& g) { return boost::get(&Connection::edge_id, g); }

    using Sub = boost::subgraph<G>;
} // namespace Lib

看到它也住在Coliru

© www.soinside.com 2019 - 2024. All rights reserved.