Boost logo

Boost :

Subject: Re: [boost] [Fusion] begin/end ADL issues with C++0x range-based for
From: Christopher Schmidt (mr.chr.schmidt_at_[hidden])
Date: 2010-12-18 11:03:39


Michel MORIN schrieb:
> Hi,
>
> In some cases, Fusion Sequence cannot be used in
> C++0x range-based for (available on GCC 4.6 Pre-Release).
> For example, this code
>
> #include <vector>
> #include <boost/fusion/include/vector.hpp>
>
>
> int main(int argc, char* argv[])
> {
> typedef boost::fusion::vector<int, int> sequence;
>
> for (auto x : std::vector<sequence>()) {}
>
> return 0;
> }
>
> does not compile.
>
> The C++0x range-based for
> for (auto x : std::vector<sequence>()) {}
> is equivalent to
> {
> auto&& rng = std::vector<sequence>();
> for (
> auto it_begin = begin(rng),
> it_end = end(rng);
> it_begin != it_end;
> ++it_begin
> ) {}
> }
> Note that rng has std and boost::fusion as its associated namespaces
> and the unqualified begin/end function call triggers ADL.
>
> The reason for the compiler errors is that the call to begin/end
> is ambiguous between std::begin/end and boost::fusion::begin/end.
> (Also boost::fusion::begin/end tries to instanciate
> result_of::begin/end::<std::vector<sequence> >
> which leads to a compiler error.)
>
> These compiler errors can be avoided by using SFINAE
> (lazy_enable_if with "is_sequence" metafunction)
> to boost::fusion::begin/end:
>
> // <boost/fusion/sequence/intrinsic/begin.hpp>
> template <typename Sequence>
> inline typename
> lazy_enable_if<
> traits::is_sequence<Sequence>
> , typename result_of::begin<Sequence>
> >::type const
> begin(Sequence& seq)
> {
> return result_of::begin<Sequence>::call(seq);
> }
>
> I attached a patch (against trunk) and a test case.
> The test case does not compile before applying the patch,
> but compiles fine after applying the patch.
> Joel and Christopher, what do you think about this change?
>
> Regards,
> Michel

Your patch makes perfect sense to me.
BTW., Mathias Gaunard created a ticket for this issue a while ago. He
also proposed disabling fusion::begin/fusion::end via SFINAE.

https://svn.boost.org/trac/boost/ticket/4028

-Christopher


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