
Boost : 
From: Michael Fawcett (michael.fawcett_at_[hidden])
Date: 20071005 16:08:31
On 10/5/07, François Duranleau <duranlef_at_[hidden]> wrote:
> Why boost::function_output_iterator has no accessor to the wrapped
> function/functor?
>
> In STL, algorithms using an output iterator or a function/functor usually
> return the iterator or function/functor received in parameter (e.g.
> std::copy, std::for_each) because they are passed by copy. Then if I use a
> boost::function_output_iterator, I can get a copy of that iterator in
> return, but then there is no way to extract the function/functor.
>
> Example: I have a set of points stored in a structure for range query
> (e.g. a kdtree). There is a member function to get all points falling
> inside a given area and it produces its output in an output iterator. Now,
> suppose I only want to do some computation on those points for which I
> would actually don't need to store them all, e.g. an average of some kind.
> I could do the computation on the fly using a
> boost::function_output_iterator with a functor that accumulates the sum
> and the number of points and at the end, I would do the division. Alas, I
> can't unless the functor only keeps reference. I can't do it the classical
> way I could with std::for_each because I can't access the functor with
> boost::function_output_iterator.
>
> So, long story just to try to show that it would be useful, or is there
> some other considerations I didn't see that makes it a bad idea?
In the exact same scenario (except I'm using a Bounding Interval
Hierarchy, not a kdtree), I decided to make a within_if(bounds,
output_iterator, predicate), rather than just a within(bounds,
output_iterator) because I didn't know of the existance of
boost::function_output_iterator. I believe I'll be changing this with
my new knowledge.
Shouldn't you be able to accomplish what you want following the
example at http://www.boost.org/libs/iterator/doc/function_output_iterator.html
? You would have
struct averager
{
averager(float3& p, int &t)
: m_avg(&p), m_num(&t)
{}
void operator()(const float3& rhs) const
{
*m_avg += rhs;
*m_num++;
}
float3* m_str;
int *m_num;
};
float3 avg(0, 0, 0);
int total = 0;
kdtree.within(bounds,
boost::make_function_output_iterator(averager(avg, total)));
avg /= total;
Michael Fawcett
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk