Boost logo

Boost :

From: Michael Fawcett (michael.fawcett_at_[hidden])
Date: 2007-10-05 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 kd-tree). 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 kd-tree), 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