triple fault
triple fault

Reputation: 14108

Wrong type of iterator used

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?

Upvotes: 7

Views: 7630

Answers (3)

juanchopanza
juanchopanza

Reputation: 227370

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();

Upvotes: 13

vershov
vershov

Reputation: 928

You have several options to avoid this problem.

  1. Use iterator instead of const_iterator in "for" loop
  2. Define object like the following:

    const Map<string, int> msi;
    
  3. Define operator at your iterator class to convert Map::const_iterator into Map::iterator

Upvotes: 2

Nikita
Nikita

Reputation: 960

You may also create cbegin() and cend() member functions that will return const iterators.

Upvotes: 2

Related Questions