Elegant solution to interview question about boost::fusion::vector

Hello everyone, I have stumbled over m2pq36bk97.fsf@boostpro.com in comp.lang.c++.moderated. I had never used boost before but I always try to solve interview questions. I found a solution that works, but I have the feeling that there must be a more elegant solution. The problem that was presented in the interview was the following: typedef boost::fusion::vector<int, double, float> row; std::vector<row> M; template <typename T> typename T::value_type Accumulate (T const &t) { typedef typename T::value_type value_type; return std::accumulate (t.begin (), t.end (), value_type ()); } Provide a function fun so that Accumulate (fun<0>(M)); computes the sum of the first column of M, or more generally Accumulate (fun<x>(M)); computes the sum of the xth column of M. The solution that was provided in m2pq36bk97.fsf@boostpro.com did not work out of the box, but I was able to fix it into the following solution: // Functor that extracts nth element of row vector. template <unsigned N> struct tuple_at { template <class Vector> typename boost::fusion::result_of::at_c<const Vector,N>::type operator()(Vector const& t) const { return boost::fusion::at_c<N, Vector>(t); } }; template <unsigned N, class M> auto fun(M const& x) -> decltype(x | boost::adaptors::transformed(tuple_at<N>())) { return x | boost::adaptors::transformed(tuple_at<N>()); } so that int main () { M.push_back(row (1, 1.0, 2.8)); M.push_back(row (2, 0.1, 2.8)); M.push_back(row (3, 0.01, 2.8)); std::cout << Accumulate(fun<1> (M)); } prints 1.11 as expected. However, I think that I should be able to achieve the same without the template tuple_at. I tried using a lambda: template <unsigned N, class M> auto fun(M const& x) -> decltype(x | boost::adaptors::transformed( [] (typename M::value_type const& x ) { return boost::fusion::at_c<N> (x); })) { auto retval = x | boost::adaptors::transformed( [] (typename M::value_type const& x ) { return boost::fusion::at_c<N> (x); }); return retval; } Unfortunately, this does not compile ("Lambda expression in an unevaluated operand"). I'm also not sure whether boost::adaptor::transformed can work with lambdas. I also tried to generate a functor object from boost::fusion::at_c using the following code from the internet: template<typename T> std::function<T> make_function (T* t) { return { t }; } template <unsigned N, class M> auto fun (M const& x) -> decltype(make_function(&boost::fusion::at_c<N, const M>)) { auto retval = make_function(&boost::fusion::at_c<N, const M> ); return retval } but this yields an error that I can't decipher yet: at.hpp:62:15: Implicit instantiation of undefined template 'boost::fusion::extension::at_impl<boost::fusion::non_fusion_tag>::apply<const std::__1::vector<boost::fusion::vector<int, double, float, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, std::__1::allocator<boost::fusion::vector<int, double, float, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>>>, mpl_::int_<2>>' The ideal solution would be one where I don't have to write the functor object manually. Even more elegantly, I should be able to leave out the return type and let the compiler figure it out automatically. Unfortunately, I use llvm gcc 4.2, so the automatic return type evaluation is out of reach (although boost without this feature seems to be quite cumbersome). Can anyone provide some insights? Thanks in advance, Stuart

AMDG On 03/29/2013 09:43 AM, Stuart wrote:
// Functor that extracts nth element of row vector. template <unsigned N> struct tuple_at { template <class Vector> typename boost::fusion::result_of::at_c<const Vector,N>::type operator()(Vector const& t) const { return boost::fusion::at_c<N, Vector>(t); } };
<snip>
However, I think that I should be able to achieve the same without the template tuple_at.
<snip>
boost::phoenix::at_c<N>(boost::phoenix::placeholders::_1) In Christ, Steven Watanabe

On 03/29/2013 09:43 AM, Stuart wrote:
// Functor that extracts nth element of row vector. template <unsigned N> struct tuple_at { template <class Vector> typename boost::fusion::result_of::at_c<const Vector,N>::type operator()(Vector const& t) const { return boost::fusion::at_c<N, Vector>(t); } };
<snip>
However, I think that I should be able to achieve the same without the template tuple_at.
<snip>
On 03/29/13 18:54, Steven Watanabe wrote:
boost::phoenix::at_c<N>(boost::phoenix::placeholders::_1)
In Christ, Steven Watanabe
Wow, many thanks! Stuart
participants (2)
-
Steven Watanabe
-
Stuart