Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#5626 closed Bugs (fixed)

Compilation error when using boost::phoenix with range adaptors

Reported by: Nicolas Savoire <nicos@…> Owned by: Thomas Heller
Milestone: Boost 1.47.0 Component: phoenix
Version: Boost 1.47.0 Severity: Regression
Keywords: Cc:

Description

The following piece of code fails to compile with gcc-4.5:

#include <iostream>
#include <boost/range.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/phoenix.hpp>

using namespace boost::phoenix::arg_names;
using namespace boost::adaptors;

int main()
{
  std::cout << *boost::begin(boost::irange(0,5) | transformed( arg1 +1));
}

The error is:

In file included from /usr/local/mkt-dev/src/boost_1_47_0_rc/boost/range/adaptor/transformed.hpp:16:0,
                 from /usr/local/mkt-dev/src/boost_1_47_0_rc/boost/range/adaptor/map.hpp:14,
                 from /usr/local/mkt-dev/src/boost_1_47_0_rc/boost/range/adaptors.hpp:20,
                 from test2.cpp:4:
/usr/local/mkt-dev/src/boost_1_47_0_rc/boost/iterator/transform_iterator.hpp: In member function ‘typename boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type::reference boost::transform_iterator<UnaryFunction, Iterator, Reference, Value>::dereference() const [with UnaryFunc = boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0l> >, Iterator = boost::range_detail::integer_iterator<int>, Reference = boost::use_default, Value = boost::use_default, typename boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type::reference = int&]’:
/usr/local/mkt-dev/src/boost_1_47_0_rc/boost/iterator/iterator_facade.hpp:517:32:   instantiated from ‘static typename Facade::reference boost::iterator_core_access::dereference(const Facade&) [with Facade = boost::transform_iterator<boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0l> >, boost::range_detail::integer_iterator<int>, boost::use_default, boost::use_default>, typename Facade::reference = int&]’
/usr/local/mkt-dev/src/boost_1_47_0_rc/boost/iterator/iterator_facade.hpp:643:67:   instantiated from ‘reference boost::iterator_facade<I, V, TC, R, D>::operator*() const [with Derived = boost::transform_iterator<boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0l> >, boost::range_detail::integer_iterator<int>, boost::use_default, boost::use_default>, Value = int, CategoryOrTraversal = boost::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::random_access_traversal_tag>, Reference = int&, Difference = long int, reference = int&]’
test2.cpp:13:70:   instantiated from here
/usr/local/mkt-dev/src/boost_1_47_0_rc/boost/iterator/transform_iterator.hpp:121:31: error: invalid initialization of reference of type ‘int&’ from expression of type ‘const int’

It seems that result_of<arg1(int)> returns int& instead of int.

Change History (6)

comment:1 by Nicolas Savoire <nicos@…>, 11 years ago

Ooops, I made a mistake, the failing example is:

#include <iostream>
#include <boost/range.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/phoenix.hpp>

using namespace boost::phoenix::arg_names;
using namespace boost::adaptors;

int main()
{
  std::cout << *boost::begin(boost::irange(0,5) | transformed( arg1 ));
}

comment:2 by Thomas Heller, 11 years ago

Resolution: fixed
Status: newclosed
Version: Boost Release BranchBoost Development Trunk

It seems that result_of<arg1(int)> returns int& instead of int.

Good observation. This shouldn't be the case. The right return type is "int const &" in that case. I commit the necessary fix to trunk. And will ask the release managers to merge to release so the release won't suffer this defect. However, it is quite late in the release process, so chances are that it won't make it.

As a small workaround, I suggest the following:

boost::irange(0,5) | transformed( val( arg1 ) )

Thanks for your report.

comment:3 by Thomas Heller, 11 years ago

Milestone: To Be DeterminedBoost 1.47.0

comment:4 by Nicolas Savoire <nicos@…>, 11 years ago

Thanks for the quick fix !

in reply to:  4 comment:5 by Thomas Heller, 11 years ago

Replying to Nicolas Savoire <nicos@…>:

Thanks for the quick fix !

No problem. The tests on the release branch look good. The fix will be part of 1.47.0

comment:6 by Thomas Heller, 11 years ago

Version: Boost Development TrunkBoost 1.47.0
Note: See TracTickets for help on using tickets.