views:

77

answers:

1

Hi, I'm writing a member function that uses a member variable pointer as an iterator. However I want to reference the pointer within the function purely for readability's sake. Like so:

/* getNext will return a pos object each time it is called for each node
 * in the tree. If all nodes have been returned it will return a Pos
 * object (-1, -1).
 * TODO: Add a lock boolean to tree structure and assert unlocked for
 *       push/pop.
 */
Pos BTree::getNext () const
{
    BTreeNode*& it = this->getNextIter;

    while (it)
    {
        if (it->visited)
        {
            /* node has been visited already, visit an unvisited right
             * child node, or move up the tree
             */
            if (   it->child [BTREE_RIGHT] != NULL
                && !it->child [BTREE_RIGHT]->visited)
            {
                it = it->child [BTREE_RIGHT];
            }
            else
            {
                it = it->parent;
            }
        }
        else
        {
            /* if unvisited nodes exist on the left branch, iterate
             * to the smallest (leftmost) of them.
             */
            if (   it->child [BTREE_LEFT] != NULL
                && !it->child [BTREE_LEFT]->visited)
            {
                for (;
                     it->child [BTREE_LEFT] != NULL;
                     it = it->child [BTREE_LEFT]) {}
            }
            else
            {
                it->visited = 1;
                return it->pos;
            }
        }
    }

    it = this->root;
    this->setTreeNotVisited (this->root);
    return Pos (-1, -1);
}

This is basically what I'm going for, where this->getNextIter is a BTreeNode*. However I get the error:

    btree.cpp:238: error: invalid initialization of reference of type
'DataTypes::BTreeNode*&' from expression of type 'DataTypes::BTreeNode* const'

What is the appropriate syntax for this kind of thing?

Cheers,

Rhys

+3  A: 

Your member function is const-qualified, so you cannot modify the member variable getNextIter. You need to use a const reference:

BTreeNode * const & it = getNextIter;

However, in your function, you modify it, so instead you probably need to remove the const-qualification from the member function or make the getNextIter member variable mutable.

When you have a member function that is const-qualified, all non-mutable member variables are const-qualified inside of the member function, hence why the compiler reports that when you try to use getNextIter inside of getNext(), it has a type of DataTypes::BTreeNode* const (note the const).

James McNellis
Ah yes, of course I dismissed the obvious... Mutable iterator is the solution! Thankyou good sir!
Fecal Brunch
@Fecal Brunch: Out of curiosity, why not use the standard STL iterator interface instead?
James McNellis
@James: I was wondering about the same thing, the most obvious drawback of the method here is that `getNextIter` is mutating the data structure. It makes it impossible to walk the tree twice in parallel for example.
Matthieu M.
@James: Ah, we're not using STL for this assignment... Did you mean why not use an STL data structure? Or is there some way to use an STL iterator for your own data types?
Fecal Brunch
@Fecal Brunch: I mean, why not use the STL iterator interface by overloading the `*`, `->`, prefix and postfix `++`, `==` and `!=` operators? It would make the code much more idiomatic.
James McNellis