Boost logo

Boost Users :

Subject: [Boost-users] [phoenix] ambiguity between std::begin/end and phoenix::begin/end due to ADL
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-12-16 04:44:19


Hello,

I am running into a problem where an unqualified call to begin()
on a range type whose template parameters include a Boost.Phoenix
type (for examle filtered_range<Pred, R> where Pred is a phoenix
function) is ambiguous because, in addition to the intended
std::begin, phoenix::begin is being found by ADL.

What can be done about this? There exists precedent for placing
boost::xxx::begin/end functions in ADL barrier namespaces because
C++11 encourages unqualified calls to begin/end (specifically,
this was done for boost::range::begin/end). Should the same thing
be done for Phoenix?

Here is a minimal example that reproduces the problem:

#include <iterator>

#include <boost/range/adaptor/filtered.hpp>
#include <boost/phoenix/phoenix.hpp>

using std::begin;

int main()
{
    using boost::phoenix::arg_names::arg1;
    using boost::adaptors::filtered;
   
    int v[5];
    const auto& f = v | filtered(arg1 < 0);
    begin(f);
}

And here are the errors, with GCC 4.7:

test.cpp: In function 'int main()':
test.cpp:15:12: error: call of overloaded 'begin(
        const boost::range_detail::filtered_range<
            boost::phoenix::actor<
                boost::proto::exprns_::basic_expr<
                    boost::proto::tagns_::tag::less
                  , boost::proto::argsns_::list2<
                        boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal
                              , boost::proto::argsns_::term<
                                    boost::phoenix::argument<1>
                                >, 0l
                            >
                        >, boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal
                              , boost::proto::argsns_::term<int>, 0l
                            >
                        >
                    >, 2l
                >
            >, int [5]
        > &
    )' is ambiguous
test.cpp:15:12: candidates are:
In file included from string:53:0,
from c++/4.7.0/bits/locale_classes.h:42,
from ios_base.h:43,
    [STL Decryptor: Suppressed 3 more STL standard header messages]
from test.cpp:1:
c++/4.7.0/bits/range_access.h:58:5:
    decltype (
        __cont.begin()
    ) begin(
        const boost::range_detail::filtered_range<
            boost::phoenix::actor<
                boost::proto::exprns_::basic_expr<
                    boost::proto::tagns_::tag::less, boost::proto::argsns_
                    ::list2<
                        boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<
                                    boost::phoenix::argument<1> >, 0l> >, boost
                        ::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<int>, 0l> > >, 2l> >,
            int [5]>; decltype (__cont.begin()) = boost::filter_iterator<
            boost::phoenix::actor<
                boost::proto::exprns_::basic_expr<
                    boost::proto::tagns_::tag::less, boost::proto::argsns_
                    ::list2<
                        boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<
                                    boost::phoenix::argument<1> >, 0l> >, boost
                        ::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<int>, 0l> > >, 2l> >,
            int *> &)
c++/4.7.0/bits/range_access.h:48:5:
    decltype (
        __cont.begin()
    ) begin(
        const boost::range_detail::filtered_range<
            boost::phoenix::actor<
                boost::proto::exprns_::basic_expr<
                    boost::proto::tagns_::tag::less, boost::proto::argsns_
                    ::list2<
                        boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<
                                    boost::phoenix::argument<1> >, 0l> >, boost
                        ::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<int>, 0l> > >, 2l> >,
            int [5]>; decltype (__cont.begin()) = boost::filter_iterator<
            boost::phoenix::actor<
                boost::proto::exprns_::basic_expr<
                    boost::proto::tagns_::tag::less, boost::proto::argsns_
                    ::list2<
                        boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<
                                    boost::phoenix::argument<1> >, 0l> >, boost
                        ::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<int>, 0l> > >, 2l> >,
            int *> &)
In file included from boost/boost/phoenix/stl/container.hpp:11:0,
from boost/boost/phoenix/stl.hpp:16,
from boost/boost/phoenix/phoenix.hpp:18,
from test.cpp:4:
boost/boost/phoenix/stl/container/container.hpp:794:1: const boost
    ::phoenix::detail::expression::function_eval<
        boost::phoenix::stl::begin, boost::range_detail::filtered_range<
            boost::phoenix::actor<
                boost::proto::exprns_::basic_expr<
                    boost::proto::tagns_::tag::less, boost::proto::argsns_
                    ::list2<
                        boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<
                                    boost::phoenix::argument<1> >, 0l> >, boost
                        ::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<int>, 0l> > >, 2l> >,
            int [5]>; boost::phoenix::detail::expression::function_eval<
            boost::phoenix::stl::begin, A0>::type = boost::phoenix::actor<
            boost::proto::exprns_::basic_expr<
                boost::phoenix::detail::tag::function_eval, boost::proto
                ::argsns_::list2<
                    boost::proto::exprns_::basic_expr<
                        boost::proto::tagns_::tag::terminal, boost::proto
                        ::argsns_::term<boost::phoenix::stl::begin>, 0l>, boost
                    ::proto::exprns_::basic_expr<
                        boost::proto::tagns_::tag::terminal, boost::proto
                        ::argsns_::term<
                            boost::range_detail::filtered_range<
                                boost::phoenix::actor<
                                    boost::proto::exprns_::basic_expr<
                                        boost::proto::tagns_::tag::less, boost
                                        ::proto::argsns_::list2<
                                            boost::phoenix::actor<
                                                boost::proto::exprns_
                                                ::basic_expr<
                                                    boost::proto::tagns_::tag
                                                    ::terminal, boost::proto
                                                    ::argsns_::term<
                                                        boost::phoenix
                                                        ::argument<1> >, 0l> >,
                                            boost::phoenix::actor<
                                                boost::proto::exprns_
                                                ::basic_expr<
                                                    boost::proto::tagns_::tag
                                                    ::terminal, boost::proto
                                                    ::argsns_::term<int>, 0l> >
                                        >, 2l> >, int [5]> >, 0l> >, 2l> >
    >::type boost::phoenix::begin(
        const boost::range_detail::filtered_range<
            boost::phoenix::actor<
                boost::proto::exprns_::basic_expr<
                    boost::proto::tagns_::tag::less, boost::proto::argsns_
                    ::list2<
                        boost::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<
                                    boost::phoenix::argument<1> >, 0l> >, boost
                        ::phoenix::actor<
                            boost::proto::exprns_::basic_expr<
                                boost::proto::tagns_::tag::terminal, boost
                                ::proto::argsns_::term<int>, 0l> > >, 2l> >,
            int [5]>; boost::phoenix::detail::expression::function_eval<
            boost::phoenix::stl::begin, A0>::type = boost::phoenix::actor<
            boost::proto::exprns_::basic_expr<
                boost::phoenix::detail::tag::function_eval, boost::proto
                ::argsns_::list2<
                    boost::proto::exprns_::basic_expr<
                        boost::proto::tagns_::tag::terminal, boost::proto
                        ::argsns_::term<boost::phoenix::stl::begin>, 0l>, boost
                    ::proto::exprns_::basic_expr<
                        boost::proto::tagns_::tag::terminal, boost::proto
                        ::argsns_::term<
                            boost::range_detail::filtered_range<
                                boost::phoenix::actor<
                                    boost::proto::exprns_::basic_expr<
                                        boost::proto::tagns_::tag::less, boost
                                        ::proto::argsns_::list2<
                                            boost::phoenix::actor<
                                                boost::proto::exprns_
                                                ::basic_expr<
                                                    boost::proto::tagns_::tag
                                                    ::terminal, boost::proto
                                                    ::argsns_::term<
                                                        boost::phoenix
                                                        ::argument<1> >, 0l> >,
                                            boost::phoenix::actor<
                                                boost::proto::exprns_
                                                ::basic_expr<
                                                    boost::proto::tagns_::tag
                                                    ::terminal, boost::proto
                                                    ::argsns_::term<int>, 0l> >
                                        >, 2l> >, int [5]> >, 0l> >, 2l> >
        &)

Thanks,
Nate
                                               


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net