
"Peter Dimov" <pdimov@mmltd.net> wrote in message news:011e01c5565c$b9f22000$6401a8c0@pdimov2... | Thorsten Ottosen wrote: | > "Peter Dimov" <pdimov@mmltd.net> wrote in message | > news:007301c55654$256e3bb0$6401a8c0@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 no. | 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. why not? | You | also forgot the end() overload. well, It's just the same code again. | It's debatable whether non-const MyType rvalues should be | mutably-iteratable, so we might prefer & instead of && in the above. at least the standard should not dictate whether it is. | > 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. your assumptions are wrong; but we should get the same size if the free-standing adapter is used. now take into consideration that begin()/end() are also needed for range algorithms and there shouldn't be any doubt that ADL + free.standing functions is superior. -Thorsten