Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2006-02-22 12:36:16


Nico Galoppo <nico_at_[hidden]> writes:

> David Abrahams wrote:
>
> > It's not a constness problem, exactly. The problem is that the result
> > of
> >
> > *ab.begin()
> >
> > is an rvalue (i.e. returned by value, not by reference). Yet the
> > filter_iterator thinks it is iterating over lvalues: its reference
> > type is Hybrid::Graph<node_traits>::const_node_ptr&, and the compiler
> > is complaining that you can't initialize such a reference with a
> > non-lvalue. It's hard to come up with a complete analysis with the
> > little information I have here, but I believe
> >
> > Hybrid::Graph<Hybrid::ArticulatedModelNodeTraits<MyTypes>
> >::node_df_traversal_iterator
> >
> > is misreporting its reference type or its category. An iterator whose
> > operator* returns by value cannot be a forward iterator; it can only
> > be an input iterator.
> >
> >
>
> I must admit, I'm only a novice at writing my own iterators. I've given it a try
> (see below), but something must be doing something wrong as you said.

Novices should not write their own iterators without the help of
boost::iterator_facade or iterator_adaptor. There are too many ways
to get it wrong.

> I think
> operator*() returns a reference now, but I could be wrong.

"Now" meaning you juste fixed it, or has it always been returning a
reference?

BTW, I also wonder if building your own graph classes is the best
course of action when Boost provides a Graph library.

> -------------------------------------------------------------------------------
>
> class node_df_traversal_iterator : public
> std::iterator<std::forward_iterator_tag,node_type>
> {
> protected:
>
> node_ptr m_node; ///< Current node being visited in traversal.
> node_ptr_container m_queue; ///< Remaining unvisited nodes in traversal.
>
> public:
>
> node_df_traversal_iterator(node_ptr node)
> : m_node(node)
> {
> if(node)
> m_queue.push_back(node);
> }
>
> bool operator== ( node_df_traversal_iterator const & other ) const{
> return (other.m_node==m_node); }
> bool operator!= ( node_df_traversal_iterator const & other ) const{
> return !((*this)==other); }
> node_type & operator*() {return (*m_node);}

Yep, looks like a reference.

> node_ptr operator->() {return m_node;}
> node_type const & operator*() const {return (*m_node);}

This is where your problem is. The const-ness of an iterator should
never affect the constness of the elements it traverses.

I suggest, strongly, that you go through the tutorial at

http://www.boost.org/libs/iterator/doc/iterator_facade.html#tutorial-example

and build your iterators around that.

HTH,

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net