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.

Reply via email to