
Joel de Guzman schrieb:
On 12/21/2010 12:56 PM, Michel MORIN wrote:
Michel MORIN wrote:
Better solutions would be:
A. (almost the same as Jeffrey's suggestion) If boost::fusion::begin/end doesn't need to be found via ADL, then use ADL barrier technique to fusion::begin/end (i.e. defining begin/end in another namespace and pull its name in namespace fusion by using directive/declaration).
B. If boost::begin/end doesn't need to be found via ADL, then use ADL barrier technique to boost::begin/end.
C. Define begin/end in namespace boost for all containers and ranges which live in namespace boost (boost::array, boost::iterator_range, boost::unordered_map, etc.). For example, define begin/end for boost::array in namespace boost. Since this is very tedious work, it would be better to define some BOOST_DEFINE_BEGIN_END macro for boilerplate code generation.
Oooops, I made a mistake! Definitely, solution B is not a choice. It diables Boost-interfaced range from using in range-based for.
So let's forget about solution B.
A is the only viable option, AFAIK.
Let me throw another possibility into the mix. This problem - a possible ambiguity between fusion::begin and std::begin/boost::begin is uncommon. In fact, only adapted boost::array's and std::array's are both fusion sequences and ranges. To get ADL kicking in we'd actually need an array of one of the inbuilt fusion container... We could disable fusion::begin/fusion::end for those few types that may collide via a new fusion extension metafunction. Say: namespace boost{namespace fusion { namespace extension {template<typename>struct disable_begin_end_impl;} namespace result_of {template<typename>struct begin;}; template <typename Seq> typename lazy_enable_if< mpl::and_< traits::is_sequence<Seq> , mpl::not_<extension::disable_begin_end_impl< typename traits::tag_of<Seq>::type >> > , result_of::begin<Seq> >::type begin(Seq&& seq); }} That way we'd just cripple the fusion interface for adapted arrays and probably a minority of user-defined fusion sequences. Ultimately, to make such types full-blown fusion sequences again, we could offer a new (meta-)function, for example fusion::pack/fusion::result_of::pack, which takes such a 'reduced' fusion sequence and returns an implementation-specific object/type that encapsulates the passed sequence and offers a full-blown fusion interface. To do so, that wrapper forwards its fusion implementation to the implementation of the underlying type - but always returns mpl::false_ for extension::disable_begin_end_impl. It's not pretty - but this approach does not break much and we'd keep ADL, even for fusion::begin/fusion::end, in most cases. Do I make sense? -Christopher