BGL:如何从顶点迭代器获取自定义顶点属性类实例?

Col*_*oss 1 c++ boost

我正在学习使用Boost Graph Library.我已经定义了一个自定义结构来存储有关顶点的信息,如下所示:修改Boost :: Graph中的顶点属性.

struct VertexProperties {
    int attribute1; 
    string attribute2;
    }; 
typedef adjacency_list<vecS, vecS, directedS, VertexProperties, no_property> Graph; 
Run Code Online (Sandbox Code Playgroud)

我可以像这样迭代图顶点并修改它们的属性:

for (int i = 0; i < num_vertices(g); i++)
{
    g[i].attribute1 = 123; 
    g[i].attribute2 = "123";
} 
Run Code Online (Sandbox Code Playgroud)

但是,当我所有的都是顶点迭代器时,我如何实际获得这些属性(即VertexProperties的相应实例)?

GraphTraits::vertex_iterator vert_i, vert_end;
for (tie(vert_i, vert_end) = vertices(g); vert_i != vert_end; ++vert_i){
    //how do i get to "vert_i.attribute1" ?
}
Run Code Online (Sandbox Code Playgroud)

边缘和边缘迭代器也是同样的问题.它应该很容易,但我似乎无法在BGL文档或其他任何地方找到它.

谢谢你的帮助.

Mik*_*son 6

使用g[*vert_i].attribute1应该工作.这是指定它的方式,它确实有效.如果查看捆绑属性的doc页面,它会说:

要访问绑定属性的特定边缘或顶点,下标与您的图形描述的边缘或顶点,其捆绑的属性,你要访问的.

他们举了一个例子:

Graph g;
Graph::vertex_descriptor v = *vertices(g).first;
g[v].name = "Troy";
Run Code Online (Sandbox Code Playgroud)

这些vertex_iterator类型应该被引用到vertex_descriptor你应该用来下标到图中的一个(g[v]).因此,使用g[*vert_i].attribute1绝对应该工作.如果没有,那么您需要在跟踪器上提交错误.

所以,这也意味着你的原代码,用g[i].attribute1,是不正确的,因为没有保证整数指数就一定是相同vertex_descriptor的是图形类型(它只是碰巧工作,因为你使用vecS的VertexList参数,这使得vertex_descriptor一个整数,但它不一定是,即使有vecS).您应该只使用vertex_descriptor对象来索引图形.而且,如果你的g[i]代码有效,那么也g[*vert_i]应该工作,除非存在严重的错误,否则根本无法工作而不能工作.

但请注意,我知道在某些条件下禁用了捆绑属性.特别是,它使用了一些编译器可能不支持的技术,这意味着旧版或外来编译器可能无法使其工作.这是一个缺陷,我希望将来能够通过一个彻底改进当前adjacency_list类模板的替代实现来删除,但这样一个激烈的重新设计不太可能在一段时间之前进入BGL.

访问捆绑属性的另一种方法是使用其属性映射,它具有一些讨厌的语法,但可能有更大的工作机会.对于您的示例,它将是这样的:

boost::property_map<Graph, int VertexProperties::*>::type attr1 = 
  get(&VertexProperties::attribute1, g);

GraphTraits::vertex_iterator vert_i, vert_end;
for (tie(vert_i, vert_end) = vertices(g); vert_i != vert_end; ++vert_i){
  put(attr1, *vert_i, 123);
}
Run Code Online (Sandbox Code Playgroud)

还有一个不受支持的功能(引擎盖下)用于获取整个捆绑包的属性映射,但您无法使用它,因为它不是受支持的接口的一部分.