Using indirect_iterators for input
Hi all, I've been experimenting with indirect_iterator, which seems to be a very useful concept. However, I'm having some trouble getting it to work in the case where I want to fill a container with pointers to values, not just getting at the data. For example, this compiles but segfaults: std::vector < int * > v( 10 ); std::fill( boost::make_indirect_iterator( v.begin() ), boost::make_indirect_iterator( v.end() ), 1.0 ); Another case: std::vector< boost::shared_ptr<double> > v(10); std::vector< boost::shared_ptr<double> > w(10); // v gets filled somehow std::copy( boost::make_indirect_iterator( v.begin() ), boost::make_indirect_iterator( v.end() ), boost::make_indirect_iterator( w.begin() ) ); Why isn't this working? Also, some way to get it to work as a back_insert_iterator would be interesting, does this exist (aside from writing your own)? If not, are there any plans to incorporate it in future versions? -- Alex Borghgraef -- Alex Borghgraef
Alexander Borghgraef
Hi all,
I've been experimenting with indirect_iterator, which seems to be a very useful concept. However, I'm having some trouble getting it to work in the case where I want to fill a container with pointers to values, not just getting at the data. For example, this compiles but segfaults:
std::vector < int * > v( 10 ); std::fill( boost::make_indirect_iterator( v.begin() ), boost::make_indirect_iterator( v.end() ), 1.0 );
:) Yes, that's expected. When dereferenced, indirect_iterator gives you a reference onto an existing value.
Why isn't this working?
It wasn't designed to do that.
Also, some way to get it to work as a back_insert_iterator would be interesting, does this exist (aside from writing your own)?
Neither exists, but for either one, writing your own is possible using iterator_facade. The tutorial is at http://www.boost.org/libs/iterator/doc/iterator_facade.html#tutorial-example
If not, are there any plans to incorporate it in future versions?
There are no such plans. It would impose an overhead on other uses that people shouldn't have to pay. -- Dave Abrahams Boost Consulting www.boost-consulting.com
On 9/28/05, David Abrahams
:) Yes, that's expected. When dereferenced, indirect_iterator gives you a reference onto an existing value.
Why isn't this working?
It wasn't designed to do that.
But it is possible to do input with an indirect_iterator no? I mean, there's
the example from the
documentation (somewhat summarized):
char* pointers_to_chars[N];
char* pointers_to_mutable_chars[N];
boost::indirect_iterator
Also, some way to get it to work as a back_insert_iterator would be
interesting, does this exist (aside from writing your own)?
Neither exists, but for either one, writing your own is possible using iterator_facade. The tutorial is at
http://www.boost.org/libs/iterator/doc/iterator_facade.html#tutorial-example
Ok, I'll look into it, thanks. -- Alex Borghgraef
Alexander Borghgraef
But it is possible to do input with an indirect_iterator no? I mean, there's the example from the documentation (somewhat summarized):
Try compiling and running the example, then try compiling and running your "somewhat summarized" version. Notice anything? When your version crashes, it will reveal to you the important things you left out: our example initializes all those pointers to refer to valid locations first.
char* pointers_to_chars[N]; char* pointers_to_mutable_chars[N];
boost::indirect_iterator
mutable_indirect_first(pointers_to_mutable_chars), mutable_indirect_last(pointers_to_mutable_chars + N); boost::indirect_iterator const_indirect_first(pointers_to_chars), const_indirect_last(pointers_to_chars + N); std::transform(const_indirect_first, const_indirect_last, mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
And this is the error message:
/usr/include/boost/shared_ptr.hpp:247: typename boost::detail::shared_ptr_traits<T>::reference boost::shared_ptr<T>::operator*() const [with T = double]: Assertion `px != 0' failed.
Right; that's not a crash. It's an assertion.
I must say it's all a bit beyond me right now. Could you explain why things go wrong here?
indirect_iterator doesn't automagically create the things the pointers are supposed to be referring to, and dereferencing a NULL pointer is illegal. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com
On 9/29/05, David Abrahams
Try compiling and running the example, then try compiling and running your "somewhat summarized" version. Notice anything? When your version crashes, it will reveal to you the important things you left out: our example initializes all those pointers to refer to valid locations first.
Aha, indeed. And when I initialize the second 'empty' vector with zeros, it works indeed. Now I get it, thanks. P.S. I ordered your book and it arrived in the mail yesterday, so maybe I won't be posing so many stupid questions here any more in the near future :-) -- Alex Borghgraef
participants (2)
-
Alexander Borghgraef
-
David Abrahams