
Hi, This proposal is somewhat beyond the current Boost.Range. I have been looking for "how to define compile-time polymorphism", which Boost.Range and Boost.Serialization etc are combating. Motivation: There is no conforming way of customization if you cannot open namespaces that contain types you customize. New Implementation: Provide a namespace for customization by using a type named 'overloaded' that triggers intentional ADL on 2nd-phase lookup. (This idea comes from Boost.Serialization.) Snippet: namespace boost { namespace range { struct overloaded { }; // ADL trigger // the metafunction template< class T > // default struct iterator { typedef typename T::iterator type; }; // the begin template< class T > typename iterator<T>::type begin(T& x) { // ADLookup to the same namespace as T or 'overloaded'. return begin(x, overloaded()); } // library-defined template< class T > // default typename iterator<T>::type begin(T& x, overloaded) { return x.begin(); } } } // namespace boost::range namespace my { template< class T > typename boost::range::iterator<T>::type algo(T& x) { // ... return boost::range::begin(x); } } namespace your { template< class T1, class T2 > struct pair { T1 first; T2 second; }; } // user-defined namespace boost { namespace range { template< class Iterator > struct iterator< your::pair<Iterator, Iterator> > { typedef Iterator type; }; template< class Iterator> Iterator begin(your::pair<Iterator, Iterator>& p, overloaded) { return p.first; } } } // namespace boost::range int main() { std::string str; boost::range::iterator<std::string>::type it1 = my::algo(str); your::pair<char*,char*> pr; boost::range::iterator< your::pair<char*,char*> >::type it2 = my::algo(pr); return 0; } Result1: In either case of metafunctions or functions, you open 'namespace boost::range'. Result2: You can avoid awkward names like 'boost_range_begin' that suppresses name-conflicts. (Why not use types!) Result3: You may provide a special namespace for customizations named like 'overloadset', where the type 'overloaded' is defined. Result4: Aside from Boost.Range, you can overload functions for built-in types, which have no associated namespaces. Result5: Broken compilers that have no ADL can be handled without any burden to users. (See: <boost/serialization/serialization.hpp>) Question1: I said on Motivation that there is "no" way. Is it positive? Do you know other workarounds? (though broken compilers can easily work around.) Question2: I said on Result2 that you can avoid the long names. Is it positive? Any danger? Question3: What if we cannot open even 'namespace boost::range'? If 'namespace range' becomes the member of 'namespace std', what can I do? Can Result3 be the workaround? Question4: This technique that triggers intentional ADL is famous? What do they call? Who is the inventor? Should I call "Ramey Lookup"? Question5: Is 'overloaded' the appropriate name? Should it be the first parameter of 'begin'? Regards, MB http://p-stade.sourceforge.net/ -------------------------------------- STOP HIV/AIDS. Yahoo! JAPAN Redribbon Campaign 2005 http://pr.mail.yahoo.co.jp/redribbon/