0

I am extending stl container with a self defined container so as to provide more flexible control on the operations of the elements

class MyContainer; template <typename T> class myiterator :public iterator<bidirectional_iterator_tag, T> { friend class MyContainer; private: T *pointer; myiterator(T *pt):pointer(pt) {} public: T& operator*() {return (*pointer);} const myiterator<T>& operator++() { pointer->current_iterator++; return *this; } bool isEnd(void) const { return pointer->current_iterator == pointer->data.end(); } }; class MyContainer { friend class myiterator<MyContainer>; public: typedef myiterator<MyContainer> iterator; typedef myiterator<MyContainer const> const_iterator; private: map<int, int> data; map<int, int>::const_iterator current_iterator; public: MyContainer() {current_iterator = data.begin(); } void addDataPair(int key, int value) {data[key] = value;} int first() const {return (*current_iterator).first;} int second() const {return (*current_iterator).second;} iterator begin() { current_iterator = data.begin(); return iterator(this); } const_iterator begin() const { return const_iterator(this); } }; 

This code run ok, if I use iterator as follow

MyContainer h; h.addDataPair(1, 1); h.addDataPair(2, 2); h.addDataPair(3, 3); for (MyContainer::iterator it=h.begin(); !it.isEnd(); ++it) { cout << (*it).first() << " " << (*it).second() << endl; } 

But it won't compile if I change iterator to const_iterator. I read some article, which mention that to define constant iterator, we simply replace the value_type from X to X const, that's how I did in my code. But I soon find that it might won't work in my case because the reference returned by an iterator is the container itself in my case. I don't know then how to make the const_iterator work without duplicate the coding.

In addition, my iterator is derived from std::iterator but I found that I cannot override the constructor for my iterator. Is that any way that I can pass more than one parameters into my iterator besides the T *pt ? Thanks.

6
  • This is a bit odd. MyContainer appears to be both a container and an iterator. Commented Apr 20, 2012 at 4:23
  • I know :) Because I don't want the code to modify the map<int, int>'s element directly so I write a wrapper to control that while they are trying to access the map data with operator[], operator++ , etc. I was going to inherit std::map to do so but seems that it is not recommended to do so because of the virtual destructor. Anyway, this is the only way I can think of to keep the interface as close as the map and add some controls. Commented Apr 20, 2012 at 4:32
  • What are you wanting that a const map wouldn't provide? Commented Apr 20, 2012 at 4:41
  • Do you want there to be any difference between a const_iterator and an iterator of your container? Commented Apr 20, 2012 at 5:07
  • Hi Vaughn, since the data stored in the map is really sensitive and I don't want them to be changed for some case, so I need a const_iterator in that siutation. Commented Apr 20, 2012 at 5:58

1 Answer 1

1

First problem:

If you change this:

for (MyContainer::iterator it=h.begin(); !it.isEnd(); ++it) 

to

for (MyContainer::const_iterator it=h.begin(); !it.isEnd(); ++it) 

then you get a non-const iterator from begin() and end() and try to initialize a const_iterator from it, but that's a different type and your my_iterator template doesn't have a constructor that allows construction from a different type.

You can fix that by adding:

template<typename> friend class myiterator; template<typename T2> myiterator(myiterator<T2> const& i) : pointer(i.pointer) { } 

You should also make operator* const (it doesn't alter the iterator to dereference it.)

But there's still a bigger problem, a const_iterator points to a const MyContainer, but const_iterator::operator++ needs to alter that object, which it can't because it's const. So you can't increment your const_iterator i.e. can't use it to iterate! You might want to rethink that design.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.