From: Peter Dimov (pdimov_at_[hidden])
Date: 2005-05-11 14:07:47


Thorsten Ottosen wrote:
> "Peter Dimov" <pdimov_at_[hidden]> wrote in message
> news:007301c55654$256e3bb0$6401a8c0_at_pdimov2...
>> Thorsten Ottosen wrote:

>>> yep, but the latter approach is harder and takes just about twice as
>>> much code in C++0x.
>>
>> Can you elaborate, please?
>
> sure.
>
> as a free-standing function we can say
>
> template< class T >
> auto begin( MyType<T>&& r ) -> decltype( r.Begin() )
> {
> return r.Begin();
> }

And

template< class T >
auto begin( MyType<T> const && r ) -> decltype( r.Begin() )
{
   return r.Begin();
}

assuming r.Begin() is const-correct, which it isn't in your example. You
also forgot the end() overload.

It's debatable whether non-const MyType rvalues should be
mutably-iteratable, so we might prefer & instead of && in the above.

> for( const auto& r : my_obj )
> { ... }

> with an adapter class we need to say...

With an adapter we need to say

template<class T> std::range<T*> adapt( MyType<T> & r )
{
    return std::range<T*>( r.Begin(), r.End() );
}

template<class T> std::range<T const *> adapt( MyType<T> const & r )
{
    return std::range<T const *>( r.Begin(), r.End() );
}

for( auto & r: adapt( my_obj ) )
{
    // ...
}

which is twice as short, not twice as long. One can argue that this is
offset by the need to write adapt(), of course.