
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. I think operator*() returns a reference now, but I could be wrong. ------------------------------------------------------------------------------- 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);} node_ptr operator->() {return m_node;} node_type const & operator*() const {return (*m_node);} const_node_ptr operator->()const {return const_node_ptr(m_node);} node_df_traversal_iterator & operator++() { if(m_queue.empty()) { m_node.reset(); return (*this); } m_queue.pop_front(); node_ptr_iterator begin = m_node->child_ptr_begin(); node_ptr_iterator end = m_node->child_ptr_end(); for(node_ptr_iterator child = begin; child != end; ++child ) m_queue.push_front( *child ); // depth first if(m_queue.empty()) { m_node.reset(); } else m_node = m_queue.front(); return (*this); } }; node_df_traversal_iterator begin() { return node_df_traversal_iterator(m_root); } node_df_traversal_iterator end() { return node_df_traversal_iterator( node_ptr() ); } const node_df_traversal_iterator begin() const { node_ptr root = boost::const_pointer_cast<node_type>(m_root); return node_df_traversal_iterator(root); } const node_df_traversal_iterator end() const { return node_df_traversal_iterator( node_ptr() ); } -- nico galoppo von borries @ address: 105 creel st., chapel hill comp. graphics phd. student @ north carolina, 27516 USA UNC, chapel hill @ phone: +1 (919) 962-1898 (office) @ +1 (919) 942-7609 (home) @ email: nico at cs dot unc dot edu @ homepage: http://www.cs.unc.edu/~nico --- debian linux :: vim powered