
Nico Galoppo <nico@crossbar.net> 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