Thank you for explanation.
On Sat, Apr 28, 2012 at 7:10 AM, tolik levchik <endight@gmail.com> wrote:The following code gives me segfault. But if `foo_ptr` is `foo*` it works fine.#include <vector>#include <boost/range/adaptor/indirected.hpp>#include <boost/range/adaptor/transformed.hpp>#include <boost/range/algorithm/for_each.hpp>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>struct foo{foo(int _i):i(_i){}virtual void bar() const{std::cout << "foo::bar::i " << i << std::endl;}int i;};typedef boost::shared_ptr<foo> foo_ptr;//typedef foo* foo_ptr;foo_ptr trasform(int i){return foo_ptr(new foo(i));}int main(){std::vector<int> vec;vec.push_back(1);using namespace boost::adaptors; using boost::bind;boost::for_each(vec| transformed(bind(&trasform, _1))| indirected,bind(&foo::bar, _1));}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.
HTH,
- Jeff
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users