On Sat, Apr 28, 2012 at 9:45 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
Is it expected behavior of adaptors ?

I think so. Here's my guess what's going on. Consider what the dereference function might look like for an iterator to the range

vec | transformed(bind(&transform, _1)) |  indirected

foo& dereference()
{
    int& i = *vec_it; // dereference iterator to vec
    foo_ptr = transform(i); // pass i through bind(&transform, _1)
    foo& x = *foo_ptr; // pass foo_ptr through indirected
    return x;
}

Sadly, the only foo_ptr "backing" the foo& goes out of scope once the foo& is returned, so that foo object is deleted and you get a dangling reference.

I don't think there's an obvious alternate implementation that will allow you to get away with the above. When you start chaining together range adaptors, especially transforms, you have to consider whether the argument to the transformation function needs to persist for the result to be remain valid.


When you put it that way I can see your point, but just from the code the OP presented the intermediate shared_ptr's should persist until
the end of the expression.

Just musing here, but how about if the dereference function you imagined returned a proxy reference, to keep the shared_ptr alive? Not
sure how I'd implement that in practise, since it would be required to know foo_ptr was a shared_ptr, but maybe it could done at the level
of the indirected adaptor rather than the indirection iterator.

- Rob.