This relates to my previous question here.
Here's a summary of that thread: I am trying to implement a doubly-linked-list class called my_list
in C++, including iterators and I want automatic implicit conversion of iterator to const_iterator.
My original thought was to have something like
template<class T>
class my_list_iterator<T>
{
node<T> pos_;
/* code */
operator my_list_iterator<const T>(){return my_list_iterator<const T>(pos_);}
};
and then inside my_list
define iterator
as my_list_iterator<T>
and const_iterator
as my_list_iterator<const T>
.
However, as pointed out by Miled Budneck in the previous thread, this won't work because a pointer to node<T>
cannot convert to a pointer to node<const T>
. He suggested I re-implement the const iterator as a pointer to const node instead.
While that works, by looking around I also found one other possible way to define the iterator class:
template<class T, class Pointer, class Reference>
class my_list_iterator {
node<T>* pos_;
/* code */
operator my_list_iterator<T,const Pointer,const Reference>() {return my_list_iterator<T,const Pointer,const Reference>(pos_);}
};
Then I can define my_list<T>::iterator
as my_list_iterator<T,T*,T&>
and my_list<T>::const_iterator
as my_list_iterator<T,const T*,const T&>
. I thought the last line would take care of the implicit conversion issue, but it seems to not be used at all.
For reference, here is the complete code:
template<class T> class node {
node(const T& t = T()):data(t),next(0),prev(0) {}
T data;
node* next;
node* prev;
friend class my_list<T>;
template<class U,class Pointer,class Reference> friend class my_list_iterator;
};
template<class T,class Pointer,class Reference> class my_list_iterator {
public:
// increment and decrement operators
my_list_iterator operator++();
my_list_iterator operator++(int);
my_list_iterator operator--();
my_list_iterator operator--(int);
// bool comparison iterators
bool operator==(const my_list_iterator& other) const {return pos_==other.pos_;}
bool operator!=(const my_list_iterator& other) const {return pos_!=other.pos_;}
// member access
Reference operator*() const {return pos_->data;}
Pointer operator->() const {return &(pos_->data);}
// conversion to constant
operator my_list_iterator<T,const Pointer,const Reference>() {return pos_;}
private:
node<T>* pos_;
explicit my_list_iterator(node<T>* p=0):pos_(p) {}
friend class my_list<T>;
};
and the error message in the end
note: no known conversion for argument 1 from ‘my_list<int>::iterator’ {aka ‘my_list_iterator<int, int*, int&>’} to ‘const my_list_iterator<int, const int*, const int&>&’
So why does this code not work? Is there any small modification I can make to make it work, or is this design impossible to implement?