Following the Expressions as Fusion Sequences section of the Proto User Guide, I get to the point where I iterate over a flattened proto expression: _1 + 2 + 3 + 4
:
#include <iostream>
#include <boost/phoenix.hpp>
namespace proto = boost::proto;
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
struct display
{
template<typename T>
void operator()(T const &t) const
{
std::cout << t << std::endl;
}
};
boost::proto::terminal<int>::type const _1 = {1};
int main(int argc, char *argv[])
{
fusion::for_each(
fusion::transform(
proto::flatten(_1 + 2 + 3 + 4)
, proto::functional::value()
)
, display()
);
return 0;
}
The _1
placeholder is defined as shown above using proto::terminal
. I'd also like to use
Boost Phoenix; however, if I instead use the version of _1
defined in boost::phoenix::arg_names
in the call to fusion::for_each
, I get an error: cannot bind ‘std::ostream {aka std::basic_ostream}’ lvalue to ‘std::basic_ostream&&’. Can I use Phoenix placeholders like this with a Fusion transform?
There is no ostream inserter for phoenix::arg_names::_1
. We can easily add one, though. This compiles for me with clang++ (trunk):
#include <iostream>
#include <boost/phoenix.hpp>
namespace proto = boost::proto;
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
struct display
{
template<typename T>
void operator()(T const &t) const
{
std::cout << t << std::endl;
}
};
namespace boost { namespace phoenix
{
template<int N>
std::ostream& operator<<(std::ostream& sout, argument<N> const& arg)
{
return sout << "_" << N;
}
}}
int main()
{
fusion::for_each(
fusion::transform(
proto::flatten(phoenix::arg_names::_1 + 2 + 3 + 4)
, proto::functional::value()
)
, display()
);
}