BGL:使用捆绑属性存储另一个顶点的顶点描述符

时间:2014-09-23 02:26:53

标签: c++ vertex boost-graph

我正在尝试使用boost::adjacency list创建一个树形图,并使用捆绑属性来存储每个顶点的父节点,我想以一种在我移除顶点时它们不会失效的方式存储顶点描述符,所以我使用boost::listS,代码看起来应该是这样的

// custom vertex for tree graphs
struct tree_vertex_info{
    // descriptor of parent vertex
    boost::graph_traits<Tree>::vertex_descriptor parent_in_tree;
};
// the tree graph type
typedef boost::adjacency_list<boost::listS, boost::listS, boost::directedS
        tree_vertex_info, boost::no_property, graph_info> Tree;

但是这不起作用,因为必须在结构定义之后定义Tree。有没有其他方法可以使用捆绑属性?我以为我可以使用int变量而不是vertex_descriptor类型来存储vertex_descriptors,但由于我使用boost::listS来存储它们,我不确定是否可以。

1 个答案:

答案 0 :(得分:1)

理论上,你可以这样:

struct tree_vertex_info;  // forward-declaration

typedef boost::adjacency_list<
  boost::listS, boost::listS, boost::directedS, 
  tree_vertex_info, boost::no_property, graph_info> Tree;

struct tree_vertex_info {
  boost::graph_traits<Tree>::vertex_descriptor parent_in_tree;
};

但是,这需要boost::adjacency_list类模板支持不完整类型(这是tree_vertex_info只有一个前向声明,直到编译器达到它的完整声明)。据我所知,boost::adjacency_list类不支持不完整的类型(我知道实现相当多,而且我认为它不会起作用)并且肯定不能保证支持它们。

我实际上正在开发boost::adjacency_list的新版本,我称之为boost::adjacency_list_BC,因为它基于Boost.Container容器,并且它将支持不完整的类型。但是,它仍处于测试阶段(跟随herehere),最新版本的Boost.Container似乎已经破坏了我仍需要弄清楚的东西。顺便说一句,我还有许多BGL树数据结构以及树的新BGL概念和特征(因为你似乎正在实现一种树)。

此外,如果您的动机真的是您所拥有的(&#34;父母在树&#34;),那么您应该在boost::bidirectionalS中使用adjacency_list来能够从子顶点到其父节点(boost::bidirectionalS意味着什么,你得到BidirectionalGraph)。

最后,为了真正解决你所处的这种情况,你必须使用类型擦除技术。一个简单的现成方法是使用boost::any来擦除vertex_descriptor的类型,如下所示:

struct tree_vertex_info{
  // descriptor of parent vertex
  boost::any parent_in_tree;
};

// the tree graph type
typedef boost::adjacency_list<boost::listS, boost::listS, boost::directedS
        tree_vertex_info, boost::no_property, graph_info> Tree;

只需查看Boost.Any有关使用它的说明。

  

我以为我可以使用int变量而不是vertex_descriptor类型来存储vertex_descriptors,但由于我使用listS来存储它们,我不确定是否可以。

不,你不能。你不能依赖于vertex_descriptor类型特别是任何东西(例如,你不能假设它是一个整数类型,更不用说&#34; int&#34;)。我碰巧知道vertex_descriptor通常是迭代器类型(例如std::list<T>::iterator)或大小类型(例如std::size_tstd::vector<T>::size_type),但这是一个实现细节你不应该也不能依赖。