I'm implementing a map as part of my HW assignment. The map should support two types of iterators:
I have the following methods:
Map::const_iterator begin() const;
Map::const_iterator end() const;
Map::iterator begin();
Map::iterator end();
However when I test my implementation with the following code:
for(Map<std::string,int>::const_iterator it = msi.begin(); it != msi.end(); ++it) {
std::cout << *it << std::endl;
}
I get the following problem:
map_test.cpp:49:43: error: no viable conversion from 'Map<basic_string<char>, int>::iterator' to 'Map<std::string, int>::const_iterator'
for(Map<std::string,int>::const_iterator it = msi.begin(); it != msi.end(); ++it) {
^ ~~~~~~~~~~~
./map_new.h:57:3: note: candidate constructor not viable: no known conversion from 'Map<basic_string<char>, int>::iterator' to 'const
Map<basic_string<char>, int>::const_iterator &' for 1st argument
const_iterator(const Map<KeyType, DataType>::const_iterator& sIterator):
^
Which means that the compiler selects the wrong begin/end methods.
How can I solve this problem?
To avoid invalidation of references to elements you can use a std::deque if you do not insert or erase in the middle. To avoid invalidation of iterators you can use a std::list.
A const iterator points to an element of constant type which means the element which is being pointed to by a const_iterator can't be modified. Though we can still update the iterator (i.e., the iterator can be incremented or decremented but the element it points to can not be changed).
3. Dereferencing: An input iterator can be dereferenced, using the operator * and -> as an rvalue to obtain the value stored at the position being pointed to by the iterator. 4. Incrementable: An input iterator can be incremented, so that it refers to the next element in the sequence, using operator ++().
By providing an implicit conversion from iterator
to const_iterator
. You can do this by giving const_iterator
a constructor that takes an iterator
, or by providing iterator
with a const_iterator
conversion operator.
This approach is used in the standard library when you do this kind of thing:
std::vector<int> v;
std::vector<int>::const_iterator it = v.begin();
In C++11, you have methods that return const_iterators
directly, even for non-const instances. But these need a different name, because you cannot overload by return type:
std::vector<int> v;
std::vector<int>::const_iterator it = v.cbegin();
You may also create cbegin()
and cend()
member functions that will return const iterators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With