2012-11-19 38 views
10

我想用纯C++ 11等价物替换顶点或边上的BGL迭代。 BGL的代码(来自:http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/quick_tour.html)是:用“纯”C++ 11替代替换BGL迭代顶点?

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) 
{...} 

这可能吗?

回答

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))){ 
    // ... 
} 
+0

谢谢,但您提供的代码甚至没有编译:(请看看源代码(包括您的代码):http://pastebin.com/Nx7WeMhU –

+0

@ danilo2:究竟是什么错误? – Xeo

+0

在这里他们是:http://pastebin.com/LDLRYwNG(另外我添加';'第20行,因为没有它缺少分号语法错误) –

3

Boost.Graph还提供了类似于方便的宏BOOST_FOREACH,但专为图形迭代而设计。

给定图的所有顶点/边的迭代由宏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工作两者。