[Phoenix] : Using phoenix with zip_iterator

I have the following program where I make_zip_iterator on 2 vector<int>::iterator's and am trying to pass a Phoenix expression to std::for_each on the iterator. I wrote a lazy version of tuple.get<N> for that purpose. I get a compile error because the phoenix functor only accepts references, whereas the tuple element seems to get passed by value. What am I doing wrong? Manjunath #include <iostream> #include <vector> #include <algorithm> #include <boost/iterator/zip_iterator.hpp> #include <boost/tuple/tuple.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_statement.hpp> #include <boost/spirit/include/phoenix_scope.hpp> #include <boost/spirit/home/phoenix/function/function.hpp> using namespace boost::phoenix; using namespace boost::phoenix::arg_names; using namespace boost::phoenix::local_names; using namespace std; namespace fusion = boost::fusion; struct print_tuple { void operator()(const boost::tuple<int&, int&>& t) const { cout << t.get<0>() << " " << t.get<1>() << "\n"; } }; struct get0_ { template<typename Arg> struct result { typedef int type; }; template<typename Arg> int operator()(Arg a1) const { return a1.get<0>(); } }; function<get0_> get0; int main() { vector<int> a(10), b(10); for(unsigned i=0, e=a.size(); i!=e; ++i) { a[i] = i; b[i] = i; } std::for_each(a.begin(), a.end(), cout << arg1); std::for_each(boost::make_zip_iterator(boost::make_tuple(a.begin(), b.begin())), boost::make_zip_iterator(boost::make_tuple(a.end(), b.end())), cout << get0(arg1)); }

AMDG Manjunath Kudlur wrote:
I have the following program where I make_zip_iterator on 2 vector<int>::iterator's and am trying to pass a Phoenix expression to std::for_each on the iterator. I wrote a lazy version of tuple.get<N> for that purpose. I get a compile error because the phoenix functor only accepts references, whereas the tuple element seems to get passed by value. What am I doing wrong?
Your code works for me. What version of boost and what compiler are you using? In Christ, Steven Watanabe

Your code works for me. What version of boost and what compiler are you using?
I grabbed the most recent boost-trunk from SVN. Here is the output of my g++ -v. $ g++ -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) Here is the compiler error : zip.cpp: In member function ‘int get0_::operator()(Arg) const’: zip.cpp:33: error: expected primary-expression before ‘)’ token In file included from /usr/include/c++/4.4/algorithm:62, from zip.cpp:3: /usr/include/c++/4.4/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = boost::zip_iterator<boost::tuples::tuple<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >, _Funct = boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
]’: zip.cpp:51: instantiated from here /usr/include/c++/4.4/bits/stl_algo.h:4200: error: no match for call to ‘(boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >) (boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >)’ /home/kvm/boost/boost-trunk/boost/spirit/home/phoenix/core/actor.hpp:90: note: candidates are: typename boost::mpl::eval_if<typename Eval::no_nullary, boost::mpl::identity<boost::phoenix::detail::error_expecting_arguments>, boost::phoenix::eval_result<Eval, boost::phoenix::basic_environment<boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > ::type boost::phoenix::actor<Eval>::operator()() const [with Eval = boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >] /home/kvm/boost/boost-trunk/boost/spirit/home/phoenix/core/actor.hpp:107: note: typename boost::phoenix::actor<Eval>::result<boost::phoenix::actor<Eval>(T0&)>::type boost::phoenix::actor<Eval>::operator()(T0&) const [with T0 = boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >, Eval = boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >]
When I replace a1.get<0>() with boost::tuples::get<0>(a1) I get the following error : In file included from /usr/include/c++/4.4/algorithm:62, from zip.cpp:3: /usr/include/c++/4.4/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = boost::zip_iterator<boost::tuples::tuple<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >, _Funct = boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
]’: zip.cpp:51: instantiated from here /usr/include/c++/4.4/bits/stl_algo.h:4200: error: no match for call to ‘(boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >) (boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >)’ /home/kvm/boost/boost-trunk/boost/spirit/home/phoenix/core/actor.hpp:90: note: candidates are: typename boost::mpl::eval_if<typename Eval::no_nullary, boost::mpl::identity<boost::phoenix::detail::error_expecting_arguments>, boost::phoenix::eval_result<Eval, boost::phoenix::basic_environment<boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > ::type boost::phoenix::actor<Eval>::operator()() const [with Eval = boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >] /home/kvm/boost/boost-trunk/boost/spirit/home/phoenix/core/actor.hpp:107: note: typename boost::phoenix::actor<Eval>::result<boost::phoenix::actor<Eval>(T0&)>::type boost::phoenix::actor<Eval>::operator()(T0&) const [with T0 = boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >, Eval = boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >]
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Mon, Mar 15, 2010 at 11:07 PM, Manjunath Kudlur <keveman@gmail.com> wrote:
Your code works for me. What version of boost and what compiler are you using?
I grabbed the most recent boost-trunk from SVN. Here is the output of my g++ -v.
/* snip */
It compiles and runs fine for me other then this warning: testing.cpp(43) : warning C4267: 'initializing' : conversion from 'size_t' to 'unsigned int', possible loss of data I am using boost trunk, that is with VS2k5 though.

AMDG Manjunath Kudlur wrote:
Here is the compiler error : zip.cpp: In member function ‘int get0_::operator()(Arg) const’: zip.cpp:33: error: expected primary-expression before ‘)’ token
struct get0_ { template<typename Arg> struct result { typedef int type; };
template<typename Arg> int operator()(Arg a1) const { return a1.get<0>(); } };
Try a1.template get<0>();
zip.cpp:51: instantiated from here /usr/include/c++/4.4/bits/stl_algo.h:4200: error: no match for call to ‘(boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0> > > > > >) (boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >)’
Grrr. Phoenix doesn't support perfect forwarding. In Christ, Steven Watanabe

Try a1.template get<0>();
I tried this, and get the following error : /usr/lib/gcc/i386-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = boost::zip_iterator<boost::tuples::tuple<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >, _Funct = boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >
]’: zip.cpp:54: instantiated from here /usr/lib/gcc/i386-redhat-linux/4.3.2/../../../../include/c++/4.3.2/bits/stl_algo.h:3791: error: no match for call to ‘(boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >) (boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >)’ /x/mkudlur/boost/boost-trunk/boost/spirit/home/phoenix/core/actor.hpp:90: note: candidates are: typename boost::mpl::eval_if<typename Eval::no_nullary, boost::mpl::identity<boost::phoenix::detail::error_expecting_arguments>, boost::phoenix::eval_result<Eval, boost::phoenix::basic_environment<boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > ::type boost::phoenix::actor<Eval>::operator()() const [with Eval = boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >] /x/mkudlur/boost/boost-trunk/boost/spirit/home/phoenix/core/actor.hpp:107: note: typename boost::phoenix::actor<Eval>::result<boost::phoenix::actor<Eval> ()(T0&)>::type boost::phoenix::actor<Eval>::operator()(T0&) const [with T0 = boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >, Eval = boost::phoenix::composite<boost::phoenix::shift_left_eval, boost::fusion::vector<boost::phoenix::reference<std::basic_ostream<char, std::char_traits<char> > >, boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<get0_>, boost::phoenix::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >]
This is with g++ 4.3.2 on Fedora 10. So is this a bug? Can someone suggest a workaround to get it working? Thanks, Manjunath

On Tue, Mar 16, 2010 at 11:18 AM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Manjunath Kudlur wrote:
Try a1.template get<0>();
I tried this, and get the following error :
I already answered that. The problem is that Phoenix doesn't support perfect forwarding. I don't know of an easy solution.
Phoenix 2 is somewhat old now. If you feel up to it, work on Phoenix3 and add binders with using Boost.Functional.Forwarding and Boost.Fusion. That is about the closest to perfect forwarding that you can make something in C++. :)

Phoenix 2 is somewhat old now. If you feel up to it, work on Phoenix3 and add binders with using Boost.Functional.Forwarding and Boost.Fusion. That is about the closest to perfect forwarding that you can make something in C++. :)
I would like to give it a shot. Where can I get Phoenix3? Manjunath

On Tue, Mar 16, 2010 at 4:38 PM, Manjunath Kudlur <keveman@gmail.com> wrote:
Phoenix 2 is somewhat old now. If you feel up to it, work on Phoenix3 and add binders with using Boost.Functional.Forwarding and Boost.Fusion. That is about the closest to perfect forwarding that you can make something in C++. :)
I would like to give it a shot. Where can I get Phoenix3?
It is somewhere in the trunk (sandbox maybe? Pretty sure in the trunk, might need to wait for someone to respond that actually knows). Part of the requirement for Phoenix to be accepted as a full Boost Citizen was to Proto'fy it. Thus far it has barely been started (but it *has* been started, it has a base complete, just needs everything else to be recreated on top of it). It is mainly just converting Phoenix2 from its own system to using Proto, and taking advantage of other libraries that did not exist at the time Phoenix2 was created, like Fusion and Functional.Forwarding.

I tried svn co http://svn.boost.org/svn/boost/branches phoenix_v3 and that just seemed to have the old version (non Proto'fied). Anyone care to post instructions on how to get Phoenix v3 (even if it is pre^n-release)? Manjunath On Tue, Mar 16, 2010 at 4:11 PM, OvermindDL1 <overminddl1@gmail.com> wrote:
On Tue, Mar 16, 2010 at 4:38 PM, Manjunath Kudlur <keveman@gmail.com> wrote:
Phoenix 2 is somewhat old now. If you feel up to it, work on Phoenix3 and add binders with using Boost.Functional.Forwarding and Boost.Fusion. That is about the closest to perfect forwarding that you can make something in C++. :)
I would like to give it a shot. Where can I get Phoenix3?
It is somewhere in the trunk (sandbox maybe? Pretty sure in the trunk, might need to wait for someone to respond that actually knows). Part of the requirement for Phoenix to be accepted as a full Boost Citizen was to Proto'fy it. Thus far it has barely been started (but it *has* been started, it has a base complete, just needs everything else to be recreated on top of it). It is mainly just converting Phoenix2 from its own system to using Proto, and taking advantage of other libraries that did not exist at the time Phoenix2 was created, like Fusion and Functional.Forwarding. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Manjunath Kudlur
-
OvermindDL1
-
Steven Watanabe