Boost logo

Boost Users :

Subject: Re: [Boost-users] [phoenix] or [lamdba] Operating on containers of smart pointers.
From: Robert Jones (robertgbjones_at_[hidden])
Date: 2008-10-23 03:08:38


On Thu, Oct 23, 2008 at 7:21 AM, Raindog <raindog_at_[hidden]> wrote:

> I ran into a problem while cleaning up some old code. What I wanted to do
> was replace explicit for loops with some stl algorithms or BOOST_FOREACH.
> Below is the original function:
>
> |//in header file:
> ..snip
> typedef std::vector<Loki::SmartPtr<ADTChunk> > chunk_vec_t
> chunk_vec_t chunks;
> ..snip
>
> //in source file:
> uint32_t ADT::get_connectivity_data( std::vector< std::vector<uint8_t> >
> &output )
> {
> output.resize(chunks.size());
> for(chunk_vec_t::iterator it = chunks.begin(); it < chunks.end();
> ++it)
> {
> uint32_t success =
> (*it)->get_connectivity_data(output[it-chunks.begin()]);
> }
> return TRUE;
> }
>
> I asked on a separate website for some possibilities of replacing this code
> with boost::lambda, and the following almost correct suggestion was given to
> replace the loop:
>
> ||std::for_each( chunks.begin(), chunks.end(), bind(
> &chunk_vec_t::value::type::get_connectivity_data, _1,
> output[ std::distance( _1, chunks.begn() ]
> )
> );
>
> The problem is that the above obviously does not compile, so I made some
> changes and came up with this:
>
> ||std::for_each( chunks.begin(), chunks.end(), bind(
> &chunk_vec_t::value_type::StoredType::get_connectivity_data,
> _1, output[ std::distance( &_1, &chunks[0] ) ]
> )
> );
>
> The problem with the above is that
> "||&chunk_vec_t::value_type::StoredType::get_connectivity_data|" causes the
> VC9 compiler to crash =(
>
> So I made this change:
>
> |std::for_each( chunks.begin(), chunks.end(), bind(
> &ADTChunk::get_connectivity_data, _1,
> output[ std::distance( _1, chunks.begin() ) ] )
> );
>
> But now I get an error with the call to std::distance not being able to
> discern the arguments due to ambiguity.
>
> Next I thought that I might be able to use zip_iterator to assist in
> dealing with both of the containers, and then I realized it used tuples,
> which then made me thing that extracting the iterators from the tuples is
> going to take a lot of boiler plate code itself. Which led me to settle with
> the following code that is concise and easily readable but will only work
> if chunks is a vector essentially:
>
> BOOST_FOREACH(chunk_vec_t::value_type it, chunks)
> {
> output[std::distance(&it, &chunks[0])] =
> it->get_connectivity_data();
> }
>
> So, my final question is, given my above attempts, is there a way to do
> what the 1st and 5th(the one immediately above this line) code snippets do
> in a straight-forward manner using either boost::lambda, or, since it will
> be replaced eventually by phoenix v3, with phoenix v2?
>
>
I confess to having only given this a cursory glance over the first coffee
of the day, but
isn't this essentially a transform operation, for which the transform
algorithm would be
the clearest solution?

Cheers, Rob.



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net