BGL:无法访问捆绑的顶点属性

时间:2018-07-04 20:05:40

标签: c++ boost boost-graph

我有一个这样定义的虚拟类:

class Graph
{
  friend std::ostream& operator<<(std::ostream&, const ArchGraph &);

  struct VertexProperty;
  struct EdgeProperty;

  typedef boost::vecS vertex_selector;
  typedef boost::vecS edge_selector;

  typedef boost::property<boost::vertex_name_t, VertexProperty> vertex_property;
  typedef boost::property<boost::edge_name_t, EdgeProperty> edge_property;

  typedef boost::adjacency_list<
    vertex_selector, edge_selector, boost::bidirectionalS,
    vertex_property, edge_property> adjacency_type;

  typedef size_t size_type;

  struct VertexProperty {
    size_type id;
  };

  struct EdgeProperty {
    adjacency_type::edges_size_type index;
    size_type id;
  };

public:
  void foo() const;

private:
  adjacency_type _adj;
};

foo方法中,我尝试遍历邻接表_adj中的所有顶点,并打印每个顶点属性的id成员:

void Graph::foo() const
{
  for (auto v : boost::make_iterator_range(boost::vertices(_adj))) {
    std::cout << _adj[v].id;
  }
}

这无法编译,显然_adj[v]的类型为const struct boost::no_property,这不是我期望的。

对我来说,这似乎有点荒谬,因为似乎有很多例子都采用这种方法。

我正在使用Boost 1.67.0,有人能启发我这里做错了什么吗?该文档在这方面不是很有帮助。

1 个答案:

答案 0 :(得分:2)

使用property<tag, type>不是捆绑财产¹。

您正在谈论的所有这些示例都将使用此样式:

typedef boost::adjacency_list<
    edge_selector, vertex_selector, boost::bidirectionalS,
    VertexProperty, EdgeProperty> adjacency_type;
  

注意,您将edge_selectorvertex_selector颠倒了。

当然,现在您不能向前声明。因此,在定义adjacency_list本身之前,您需要找到另一种访问图特征的方法:'

typedef boost::adjacency_list_traits<edge_selector, vertex_selector, boost::bidirectionalS> traits;

因此您可以提前设置尺寸类型:

typedef traits::vertices_size_type size_type;
typedef traits::edges_size_type    edges_size_type;

演示

Live On Coliru

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

struct ArchGraph;

class Graph
{
    friend std::ostream& operator<<(std::ostream&, const ArchGraph &);

    struct VertexProperty;
    struct EdgeProperty;

    typedef boost::vecS vertex_selector;
    typedef boost::vecS edge_selector;

    typedef boost::adjacency_list_traits<edge_selector, vertex_selector, boost::bidirectionalS> traits;

    typedef traits::vertices_size_type size_type;
    typedef traits::edges_size_type    edges_size_type;

    struct VertexProperty {
        size_type id;
    };

    struct EdgeProperty {
        edges_size_type index;
        size_type id;
    };

    typedef boost::adjacency_list<
        edge_selector, vertex_selector, boost::bidirectionalS,
        VertexProperty, EdgeProperty> adjacency_type;

  public:
    Graph() : _adj(3) {
        for (auto vd : boost::make_iterator_range(vertices(_adj)))
            _adj[vd].id = (vd+1)*10;
    }
    void foo() const;

  private:
    adjacency_type _adj;
};

void Graph::foo() const
{
    for (auto v : boost::make_iterator_range(boost::vertices(_adj))) {
        std::cout << _adj[v].id << " ";
    }
}

int main() {
    Graph g;

    g.foo();
}

打印

10 20 30 

¹(相反,如果我没记错的话,这就是旧式的“内部装饰”)