PhonoDots
PhonoDots

Reputation: 149

Iterator on binary tree compilation error

I get the following compilation error:

error: invalid conversion from 'const IntervalST' to 'IntervalST' [-fpermissive]

when I compile my code. The code is quite big but here are the relevant parts:

the class IntervalST:

template <class Key> class intervalST_const_iterator;

template <class Key> class IntervalST
{
private:
    Interval<Key> *root;

    //friend class intervalST_const_iterator<Key>;//allow the iterator class to access the private section of intervalST

    bool isRed(Interval<Key> *interval);
    Interval<Key> *rotateLeft(Interval<Key> *h);
    Interval<Key> *rotateRight(Interval<Key> *h);
    Interval<Key> *put(Interval<Key> *h,Key lo, Key hi, Key val);
    Interval<Key> *moveRedLeft(Interval<Key> *h);
    Interval<Key> *moveRedRight(Interval<Key> *h);
    Interval<Key> *deleteMin(Interval<Key> *h, Key hi);
    Interval<Key> *balance(Interval<Key> *h);
    Interval<Key> *remove(Interval<Key> *h, Key lo, Key hi);
    Interval<Key> *min(Interval<Key> *h);
    Interval<Key> *addDuplicate(Interval<Key> *h, Key hi);
    Interval<Key> *removeDuplicate(Interval<Key> *h, Key low, Key hi);
    Interval<Key> *getPointerToKey(Key low);

    void flipColors(Interval<Key> *h);
    void destroy(Interval<Key> *h);
    void printTree(Interval<Key> *h, int indent);
    Key maxVal(Interval<Key> *h);
    int size(Interval<Key> *h);
    bool isBST(Interval<Key> *x, Key min, Key max);
    inline bool isBST(){return isBST(root,0,0);}
    bool isSizeConsistent(Interval<Key> *x);
    inline bool isSizeConsistent(){return isSizeConsistent(root);}
    bool is23(Interval<Key> *x);
    inline bool is23(){return is23(root);}
    bool isBalanced();
    bool isBalanced(Interval<Key> *x,int black);
    int getKeySize(Key low);
    int compare(Key a, Key b);

public:

    //don't forget to build the constructor
    //and overload the =equal operator
    typedef intervalST_const_iterator<Key> const_iterator;//const iterator on a tree


    const_iterator begin() const;
    const_iterator end() const;

    IntervalST():root(NULL){};
    ~IntervalST();
    void remove(Key lo, Key hi);
    void put(Key lo, Key hi);
    inline int size(){return size(root);}
    inline bool isEmpty(){return root == NULL;}
    void print(int indent = 0);
    void check();


};

The compiler is complaining on the implementation of the begin() method of the class IntervalST

begin() and end() method:

template <typename Key> typename IntervalST<Key>::const_iterator IntervalST<Key>::begin() const
{
return const_iterator(root,this);//<-----------code complaining here
}

template <typename Key> typename IntervalST<Key>::const_iterator IntervalST<Key>::end() const
{
return const_iterator(NULL,this);
}

here is the iterator class:

template <class Key> class intervalST_const_iterator
{
//friend class IntervalST<Key>;

private:
    Interval<Key> *interval;
    IntervalST<Key> *tree;

public:
    intervalST_const_iterator(Interval<Key> *p, IntervalST<Key> *t): interval(p), tree(t){}
    bool operator != (const intervalST_const_iterator & other) const
    {
        return this->interval != other.interval;
    }
    bool operator == (const intervalST_const_iterator & other) const
    {
        return this->interval == other.interval;
    }
    Interval<Key> operator *() const
    {
        return *(this->interval);
    }
    intervalST_const_iterator<Key> & left() const
    {
        return (interval = interval->left);
    }
    intervalST_const_iterator<Key> & right() const
    {
        return (interval = interval->right);
    }
};

Why is this happening? and how to solve it? Surprisingly the implementation of the end() method is almost the same as the implementation of the begin() method. thanks for your help

Upvotes: 1

Views: 236

Answers (2)

Sean
Sean

Reputation: 987

Your member function Interval<Key>::begin(), is marked const, so any use of this must also be const. In this case, the constructor for your iterator class accepts pointers to non-const Interval<Key> objects, so passing this here is not allowed. You should add the const keyword to all the Interval<Key> pointers in your intervalST_const_iterator class, starting with the constructor arguments.

For similar reasons, your left() and right() member functions of intervalST_const_iterator will also fail to compile because they too are marked const, yet they modify the interval field of the iterator.

Note that in the conventions of the C++ template library, a const_iterator is not itself constant, but the container object it iterates over is constant. As opposed to a non-constant iterator that allows you to add/remove/modify elements of the container. Both const/non-const iterators must be themselves mutable so you can step them through each element.

Update: In your iterator class, your member variables must be constant:

const Interval<Key> *interval;
const IntervalST<Key> *tree;

Then, the iterator's member functions must also use constant interval pointers:

intervalST_const_iterator(const Interval<Key> *p, const IntervalST<Key> *t)
const Interval<Key> operator *() const

Upvotes: 6

Slava
Slava

Reputation: 44238

Your intervalST_const_iterator class constructor expects non const pointers to Interval<Key> and IntervalST<Key>:

intervalST_const_iterator(Interval<Key> *p, IntervalST<Key> *t);

In const method of IntervalSTyou try to create intervalST_const_iterator:

template <typename Key> typename IntervalST<Key>::const_iterator IntervalST<Key>::begin() const
{
   return const_iterator(root,this);//<-----------code complaining here
}

this has type const IntervalST * but you try to pass it as IntervalST * as constructor of intervalST_const_iterator expects.

Upvotes: 2

Related Questions