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);
In a range-based for
loop, name lookup for non-member begin()
and end()
uses ADL only. It doesn't perform ordinary unqualified lookup. §6.5.4 [stmt.ranged]/p1.3:
if
_RangeT
is a class type, the unqualified-idsbegin
andend
are looked up in the scope of class_RangeT
as if by class member access lookup (3.4.5), and if either (or both) finds at least one declaration, [...]otherwise, begin-expr and end-expr are
begin(__range)
andend(__range)
, respectively, wherebegin
andend
are looked up in the associated namespaces (3.4.2). [ Note: Ordinary unqualified lookup (3.4.1) is not performed. —end note ]
Hence, your begin()
and end()
overloads are not found.