On 28 August 2014 20:50, Robert Jones <robertgbjones@gmail.com> wrote:
Can anyone explain why my last output line is garbage?

int main( )
{
    using boost::adaptors::reversed;
    using boost::adaptors::transformed;
    using boost::counting_range;
    using boost::phoenix::arg_names::_1;

    print_it( counting_range( 1, 5 ) );
    print_it( counting_range( 1, 5 ) | reversed );

    print_it( counting_range( 1, 5 ) |            transformed( doubled ) );
    print_it( counting_range( 1, 5 ) | reversed | transformed( doubled ) );

    print_it( counting_range( 1, 5 ) |            transformed( bind( doubled, _1 ) ) );
    print_it( counting_range( 1, 5 ) | reversed | transformed( bind( doubled, _1 ) ) );
}


The counting_range instance is a unnamed temporary, since the adaptors are applied to this temporary the adapted iterators may live beyond the lifetime of the source. If you where to add the line:

const auto& rng = counting_range(1, 5)

and then you did:
print_it(rng | reversed | transformed(bind(doubled, _1)));

it should then work since there are no issues with chaining the adaptors since the iterators are always copied from the base range instances during the chaining process. One has to manage the lifetime of the source to ensure it lives beyond the lifetime of the iterators.
 

Thx, Rob.

Regards,
Neil Groves