Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2005-05-19 04:55:47


The following code currently fails to compile because of a subtle
interaction between bind-produced function objects and the current
implementation of transform_iterator's 'dereference' function (the
same applies to 'filter_iterator' and most likely the rest of the
adaptors in the library):

    #include <boost/iterator/transform_iterator.hpp>
    #include <boost/bind.hpp>

    int add_two( int x ) { return x + 2; }

    int main()
    {
        int x[] = { 0 };
        *boost::make_transform_iterator(
             boost::make_transform_iterator( x, boost::bind( &add_two, _1 ) )
           , boost::bind( &add_two, _1 )
           );
    }

The problem here is that the result of 'boost::bind( &add_two, _1 )'
takes its argument by reference, while transform_iterator's
'dereference' implementation is:

    typename super_t::reference dereference() const
    { return m_f(*this->base()); }
                 ^^^^^^^^^^^^^

In our case, '*this->base()' produces a temporary 'int' which cannot
be directly passed to 'm_f'.

Effectively, the issue prevents you from layering any iterator
adaptors built with 'boost::bind' on top of 'transform_iterator',
which, needless to say, is BAD.

My sugesstion would be to replace the above with

    typename super_t::reference dereference() const
    {
        typename iterator_reference<Iterator>::type x( *this->base() );
        return m_f( x );
    }

Comments?

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk