Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Range based for with pair<Iterator,Iterator>

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);
like image 464
Marti Nito Avatar asked Nov 26 '14 03:11

Marti Nito


People also ask

Does range-based loop use iterator?

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.

Are there range-based for loops in C?

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.

Are range-based for loops faster?

Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once.

Are iterators used in for each loops C++?

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.


1 Answers

Iterator pairs are not ranges by design! The idea was specifically rejected from the language and library specification. See e.g.

  • paper n2995.pdf Pairs do not make good ranges

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

like image 66
sehe Avatar answered Sep 28 '22 06:09

sehe