10

頂点またはエッジでのBGL反復を、同等の純粋なC++11に置き換えたいと思います。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)] << ") ";
}

ここからいくつかの提案を試しました。BOOST_FOREACHを「純粋な」C++11の代替に置き換えますか?しかし運がない。

私は次のようなものを書けるようになりたいです:

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

出来ますか?

4

2 に答える 2

9

単純なラッパーで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))){
  // ...
}
于 2012-11-19T12:24:09.340 に答える