2012-11-19 32 views
10

मैं शुद्ध सी ++ 11 समकक्ष के साथ वर्टेक्स या किनारों पर बीजीएल पुनरावृत्ति को प्रतिस्थापित करना चाहता हूं। (से: http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/quick_tour.html) बीजीएल कोड है:"शुद्ध" सी ++ 11 विकल्प के साथ वर्टेक्स पर बीजीएल पुनरावृत्ति को बदलें?

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 
    { 

    } 

}

मैक्रो सी ++ 03 और सी ++ 11 में दोनों काम करते हैं।