【问题标题】:BGL: Unable to access bundled vertex propertiesBGL:无法访问捆绑的顶点属性
【发布时间】:2018-07-04 20:05:39
【问题描述】:

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

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

【问题讨论】:

    标签: c++ boost boost-graph


    【解决方案1】:

    使用property&lt;tag, type&gt;不是捆绑属性¹。

    您所谈论的所有示例都将使用这种样式:

    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 
    

    ¹(相反,如果我没记错的话,它是旧式的所谓“内部属性”)

    【讨论】:

    • 好的,这就很清楚了。谢谢你。此外,`operator
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多