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