我trying使用BGL的BFS算法使用两个访问者:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/visitors.hpp>
using Graph = boost::adjacency_list<>;
using Vertex = Graph::vertex_descriptor;
using Edge = Graph::edge_descriptor;
namespace boost
{
template <typename event_type>
class test_visitor: public default_bfs_visitor
{
public:
using event_filter = event_type;
void discover_vertex(Vertex, const Graph&) const
{
std::cout << "vertex discovered" << std::endl;
}
};
}
int main()
{
// Initialize a test graph
Graph graph;
Vertex vertexFoo = boost::add_vertex(graph);
Vertex vertexBar = boost::add_vertex(graph);
Vertex vertexBaz = boost::add_vertex(graph);
boost::add_edge(vertexFoo, vertexBar, graph);
boost::add_edge(vertexBar, vertexBaz, graph);
// Initialize parents map
std::vector<Vertex> parents_map(boost::num_vertices(graph));
parents_map[vertexFoo] = vertexFoo;
// Perform BFS with two listeners
boost::breadth_first_search(
graph,
vertexFoo,
boost::visitor(
boost::make_bfs_visitor(
std::make_pair(
boost::record_predecessors(&parents_map[0], boost::on_tree_edge()),
boost::test_visitor<boost::on_discover_vertex()>()
)
)
)
);
return 0;
}
我的自定义访问者的监听器(discover_vertex
)由于某种原因未被调用。我认为这个问题与我如何将听众传递给breadth_first_search
有关。我无法找到关于boost::visitor
和boost::make_bfs_visitor
的好文档。
B.t.w。我的自定义访问者可以正常工作,如果我从中移除using event_filter = event_type;
并将其包含在仅boost::visitor
而不包含boost::make_bfs_visitor
的{{1}}中,这需要typedef
。
我也无法找到任何关于event_filter
的文档以及如何在一个访问者中同时使用多个事件(例如on_discover_vertex
和on_examine_edge
)。我是否正确event_filter
指定访问者将处理哪些事件?有关此文档的链接值得赞赏。
答案 0 :(得分:2)
首先,无需在boost名称空间中声明访问者。这是一个坏主意,不要将自己的东西注入你无法控制的名称空间。
接下来,如果您使用make_bfs_visitor
拼凑特定event_filter
的访问者,则需要实施operator()
而不是discover_vertex
:
template <typename event_type>
struct test_visitor: public default_bfs_visitor
{
using event_filter = event_type;
void operator()(Vertex, Graph const&) const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
最后,event_type
参数完全错误,请删除括号:
test_visitor<boost::on_discover_vertex>()
<强> Live On Coliru 强>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/visitors.hpp>
#include <iostream>
using Graph = boost::adjacency_list<>;
using Vertex = Graph::vertex_descriptor;
using Edge = Graph::edge_descriptor;
template <typename event_type>
struct test_visitor: public boost::default_bfs_visitor {
using event_filter = event_type;
void operator()(Vertex, Graph const&) const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
int main() {
// Initialize a test graph
enum { Foo, Bar, Baz, NUMVERTICES };
Graph graph(NUMVERTICES);
boost::add_edge(Foo, Bar, graph);
boost::add_edge(Bar, Baz, graph);
// Initialize parents map
std::vector<Vertex> parents_map(boost::num_vertices(graph));
parents_map[Foo] = Foo;
// Perform BFS with two listeners
boost::breadth_first_search(graph, Foo,
boost::visitor(
boost::make_bfs_visitor(
std::make_pair(
boost::record_predecessors(&parents_map[0], boost::on_tree_edge()),
test_visitor<boost::on_discover_vertex>()
)
)
)
);
}