I have a question with respect to the following answer:
https://stackoverflow.com/a/15828866/2160256
As stated there, we cannot use range based for with BGL like this:
for(auto e : boost::edges(g))
// do something with e
However, here it states, that we can overload the begin() and end() functions that are required to use range based for semantics. So I tried:
template<class I>
I begin(std::pair<I,I>& p)
{ return p.first;}
template<class I>
I end(std::pair<I,I>& p)
{ return p.second;}
However, the compiler still complains:
error: no matching function for call to ‘
begin(std::pair<some_really_ugly_type,some_really_ugly_type>&)
’
What am I doing wrong? Does the name lookup not work? Or is this not possible after all? I also found this answer, which works, but shouldtn't it be possible with the begin/end free function overlods as well? Regards, Marti
BTW: I find it really tiresome to write
typename Graph::edge_iterator ebegin, eend;
std::tie(ebegin,eend) = boost::edges(_graph);
std::for_each(ebegin,eend,[&](const edge_descriptor& e){/*do something with e*/;});
UPDATE: C++17 should now allow the following :-)
auto [ebegin,eend] = boost::edges(_graph);
Range-Based 'for' loops have been included in the language since C++11. It automatically iterates (loops) over the iterable (container). This is very efficient when used with the standard library container (as will be used in this article) as there will be no wrong access to memory outside the scope of the iterable.
Range-based for loop (since C++11) Executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.
Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once.
Working of the foreach loop in C++ So basically a for-each loop iterates over the elements of arrays, vectors, or any other data sets. It assigns the value of the current element to the variable iterator declared inside the loop.
Iterator pairs are not ranges by design! The idea was specifically rejected from the language and library specification. See e.g.
If you "find it tiresome" to write the tie()
workaround, just use
for (auto& edge : make_iterator_range(boost::edges(_graph)))
/*do something with edge*/;
You could alias boost::make_iterator_range
something shorter, but my editor¹ suggests make_iterator_range
as completion when I type mir
. This is plenty speedy for me
¹ of course, that editor is Vim
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With