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

BGL: Unable to access bundled vertex properties

我有一个虚拟 class 定义如下:

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,谁能告诉我我做错了什么?文档在这方面不是很有帮助。

使用 property<tag, type> 不是 捆绑 属性¹。

您提到的所有这些示例都将使用这种样式:

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

Note you had edge_selector and vertex_selector reversed.

当然,现在你不能前向声明。因此,在定义 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 

¹(相反,我没记错的话就是老式的所谓"interior property")