我想用纯C ++ 11等效替换顶点或边上的BGL迭代。 BGL代码(来自:http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/quick_tour.html)是:
typename boost::graph_traits<Graph>::out_edge_iterator out_i, out_end;
typename boost::graph_traits<Graph>::edge_descriptor e;
for (std::tie(out_i, out_end) = out_edges(v, g);
out_i != out_end; ++out_i)
{
e = *out_i;
Vertex src = source(e, g), targ = target(e, g);
std::cout << "(" << name[get(vertex_id, src)]
<< "," << name[get(vertex_id, targ)] << ") ";
}
我从这里尝试了几条建议:Replace BOOST_FOREACH with "pure" C++11 alternative?但没有运气。
我希望能够写出如下内容:
for (auto &e : out_edges(v, g))
{ ... }
或类似的东西:
for (std::tie(auto out_i, auto out_end) = out_edges(v, g);
out_i != out_end; ++out_i)
{...}
有可能吗?
答案 0 :(得分:8)
out_edges
上的简单包装就足够了:
#include <boost/range/iterator_range.hpp>
#include <type_traits>
template<class T> using Invoke = typename T::type
template<class T> using RemoveRef = Invoke<std::remove_reference<T>>;
template<class G> using OutEdgeIterator = typename boost::graph_traits<G>::out_edge_iterator;
template<class V, class G>
auto out_edges_range(V&& v, G&& g)
-> boost::iterator_range<OutEdgeIterator<RemoveRef<G>>>
{
auto edge_pair = out_edges(std::forward<V>(v), std::forward<G>(g));
return boost::make_iterator_range(edge_pair.first, edge_pair.second);
}
甚至更简单,一个将std::pair
转换为有效范围的函数:
template<class It>
boost::iterator_range<It> pair_range(std::pair<It, It> const& p){
return boost::make_iterator_range(p.first, p.second);
}
然后
for(auto e : pair_range(out_edges(v, g))){
// ...
}
答案 1 :(得分:3)
Boost.Graph还提供了与BOOST_FOREACH
类似的便捷宏,但专为Graph迭代而设计。
宏BGL_FORALL_VERTICES
/ BGL_FORALL_EDGES
及其模板对应BGL_FORALL_VERTICES_T
/ BGL_FORALL_EDGES_T
提供了对给定图表的所有顶点/边缘的迭代。
宏BGL_FORALL_OUTEDGES
或BGL_FORALL_INEDGES
提供给定顶点的内边缘或外边缘的迭代。 (为其模板版本添加_T)。对于邻接顶点,请使用BGL_FORALL_ADJ
。
示例:
#include <boost/graph/iteration_macros.hpp>
typedef ... Graph;
Graph g;
BGL_FORALL_VERTICES(v, g, Graph) //v is declared here and
{ //is of type Graph::vertex_descriptor
BGL_FORALL_OUTEDGES(v, e, g, Graph) //e is declared as Graph::edge_descriptor
{
}
}
宏在C ++ 03和C ++ 11中都有效。