I have a vector of vectors or some nested data structure of that sort. I want to loop over the outer structure and summarize the inner structure, like taking averages of all the vectors or what not. Once I saw that in the code three times I thought it was time to abstract it out. So the plan was to have a generic loop function that takes a functor type for the action to perform inside the loop. So far so good. In many instances that action is a standard algorithm or composition thereof, so why not use functors like those returned by bind(accumulate, _1, _2, 0) instead of writing little polluting classes like BinFunc below? But the compiler is at a loss guessing the types, and it looks to me like it is for a good reason, because to instantiate the accumulate template it has to know the precise signature of my loop function and the converse too. Can the lambda experts shed light on this? It seems a quite natural use case.
Thanks
Antonio
PS: in an ideal world the following example can be done combining transform call_begin and call_end, but that an whole different story
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <vector>
#include <numeric>
#include <functional>
using namespace boost::lambda;
template<class Func, class NestedIt, class It>
void loop_func(NestedIt start, NestedIt stop, It dest, Func f) {
for(;start < stop; start++, dest++) {
*dest = f(start->begin(), start->end());
}
}
class BinFunc:
public std::binary_function<std::vector<int>::iterator,
std::vector<int>::iterator, int> {
public:
int operator()
(std::vector<int>::iterator b,
std::vector<int>::iterator e) {
return accumulate(b,e,0);
}
};
int main() {
std::vector<int> d;
std::vector<std::vector<int> > s;
loop_func(s.begin(), s.end
(), d.begin(),
BinFunc()); //flies with gcc
loop_func(s.begin(), s.end(), d.begin(),
bind<int>(std::accumulate, _1, _2, 0.0)); //does not
}
bind_test.cpp: In function 'int main()':
bind_test.cpp:32: error: invalid initialization of reference of type 'const int&' from expression of type '<unknown type>'
/usr/include/boost/lambda/detail/bind_functions.hpp:532: error: in passing argument 1 of 'const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<4, boost::lambda::function_action<4, boost::lambda::detail::unspecified> >, typename boost::lambda::detail::bind_tuple_mapper<const Arg1, const Arg2, const Arg3, const Arg4, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>::type> > boost::lambda::bind(const Arg1&, const Arg2&, const Arg3&, const Arg4&) [with Arg1 = int, Arg2 = boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, Arg3 = boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, Arg4 = double]'