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 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
#include
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_::termboost::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_::termboost::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