Я реализую карту как часть моего задания HW. Карта должна поддерживать два типа итераторов:
У меня есть следующие методы:
Map::const_iterator begin() const;
Map::const_iterator end() const;
Map::iterator begin();
Map::iterator end();
Однако, когда я тестирую свою реализацию со следующим кодом:
for(Map<std::string,int>::const_iterator it = msi.begin(); it != msi.end(); ++it) {
std::cout << *it << std::endl;
}
Я получаю следующую проблему:
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):
^
Это означает, что компилятор выбирает неправильные методы начала / конца.
Как я могу решить эту проблему?
Предоставляя неявное преобразование из iterator
в const_iterator
, Вы можете сделать это, дав const_iterator
конструктор, который принимает iterator
или предоставляя iterator
с const_iterator
оператор преобразования.
Этот подход используется в стандартной библиотеке, когда вы делаете такие вещи:
std::vector<int> v;
std::vector<int>::const_iterator it = v.begin();
В C ++ 11 у вас есть методы, которые возвращают const_iterators
напрямую, даже для неконстантных случаев. Но им нужно другое имя, потому что вы не можете перегрузить типом возвращаемого значения:
std::vector<int> v;
std::vector<int>::const_iterator it = v.cbegin();
Вы также можете создать cbegin()
а также cend()
функции-члены, которые будут возвращать константные итераторы.
У вас есть несколько вариантов, чтобы избежать этой проблемы.
Определите объект следующим образом:
const Map<string, int> msi;
Определите оператор в своем классе итератора для преобразования Map :: const_iterator в Map :: iterator