我有一个这样定义的虚拟类:
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,有人能启发我这里做错了什么吗?该文档在这方面不是很有帮助。
答案 0 :(得分:2)
使用property<tag, type>
是不是捆绑财产¹。
您正在谈论的所有这些示例都将使用此样式:
typedef boost::adjacency_list<
edge_selector, vertex_selector, boost::bidirectionalS,
VertexProperty, EdgeProperty> adjacency_type;
注意,您将
edge_selector
和vertex_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;
#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
¹(相反,如果我没记错的话,这就是旧式的“内部装饰”)