Boost logo

Boost :

Subject: Re: [boost] [Fusion] begin/end ADL issues with C++0x range-based for
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-12-21 15:29:19


On 12/21/2010 5:33 AM, Christopher Schmidt wrote:
[...]
> 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?

I would like to see a situation where finding boost::fusion::begin/end
via ADL is actually useful (i.e., couldn't be replaced by explicit
qualification). Until then, I believe preventing
boost::fusion::begin/end (and, possibly, boost::begin/end) from being
found via ADL is a better solution; further, it explicitly discourages
any future code from relying on ADL (assuming that relying on ADL
*should* be discouraged).

- Jeff


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk