N.B. I'm going to use the term "good old for" instead of "plain old for" ;-)
On 25 March 2011 11:43, Rodrigo Rivas wrote: > On Fri, Mar 25, 2011 at 11:52 AM, James Dennett <james.denn...@gmail.com> > wrote: >> I'd be interested to know those reasons. > Well, maybe not *plenty*, but *some*... Let's say that I have a function: > template <typename S, typename T> void Dump(S &s, const T &t) > { > for (auto i : t) > s.dump(i); > } > Cool! > > Now I want to do the following: > template <typename S, typename T> void DumpExtra(S &s, const T &t) > { You need: using std::begin; using std::end; here to emulate the FCD range-for behaviour, so that namespace std is an associated namespace. > auto _b = begin(c); > auto _e = end(c); > for (auto _it = _b; _it != _e; ++_it) > { > auto i = *_it; > if (s.condition(i)) > s.dump(i); > else > { > if (++_it == _e) > break; > s.dump2(i, *_it); > } > } > I cannot use the range-for because I increment the iterator. But now > I'm not sure if this may not compile, or worse, may use a different > range definition than the other one! > > Disclaimer: the fact that I lack the imagination for a better example > doesn't mean that it will not happen in the real world. I might write the loop above to use qualified calls to std::begin and std::end, and require users of strange types to wrap their range in an adaptor with begin/end members, so that std::begin and std::end do the right thing. The adaptor would forward to my::begin/my::end or whatever you wanted ADL to find. We're never going to achieve perfection so everything works for all cases.