Boost logo

Boost Users :

Subject: [Boost-users] [phoenix] or [lamdba] Operating on containers of smart pointers.
From: Raindog (raindog_at_[hidden])
Date: 2008-10-23 02:21:41


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?

Thanks!

|

|
|


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