#c #stl #map #iterator #g
#c #stl #Карта #итератор #g
Вопрос:
Я пишу свою собственную реализацию контейнера карты C STL. Теперь я пытаюсь реализовать итератор. Это должно позволить вам сделать что-то вроде iter-> first и iter-> second, которые возвращают ключ / значение соответственно и где iter является объектом, а не указателем. Мне интересно, как я должен это перегрузить? Это немного сбивает с толку, потому что я не уверен, каким должен быть возвращаемый тип; я полагаю, это должен быть объект с членами first / second. Обычно ли возвращать ссылку на объект-оболочку / интерфейс или что-то в этом роде?
Ответ №1:
Если вы действительно имеете в виду стандартную библиотеку C , то value_type
of a map
— это a pair
. Пара имеет члены first
и second
. Разыменование итератора в a map
дает вам pair
.
Комментарии:
1. Даже если спрашивающий действительно имеет в виду STL,
value_type
of amap
по-прежнему является apair
;-p2. @SteveJessop: Я не могу говорить об этом, но если это так, то отлично!
Ответ №2:
Да, вам понадобится прокси для хранения соответствующей ссылки.
Что касается типа: итераторы стандартной библиотеки обычно ссылаются на что-то типа value_type
. Для map<K,V>
, тип значения std::pair<K, V>
(или, скорее, pair<key_type, mapped_type>
) , из которого вы получаете first
/ second
interface .
(Одна из лекций Стефана Лававея объясняет, как реализация MSVC использует ту же базовую структуру данных для set
и map
; единственное отличие состоит в том, что set::value_type
равно set::key_type
, в то время map::value_type
как есть pair<key_type, mapped_type>
. Таким образом, вы можете отличить их друг от друга с помощью простой проверки признаков, но интерфейс итератора практически идентичен.)
Ответ №3:
value_type стандартной карты равен std::pair<const KeyType, MappedType>
.
Для достижения нормальной семантики указателя operator*
возвращает ссылку, тогда operator->
как возвращает указатель.
//minimal example
#include <utility>
#include <cstdio>
struct It
{
std::pair<const int, int> pair;
std::pair<const int, int>* operator->() { return amp;pair; }
std::pair<const int, int>amp; operator*() { return pair; }
};
int main()
{
It it = {std::make_pair(10, 20) };
(*it).second = 30;
std::printf("%d %dn", it->first, it->second);
}
Ответ №4:
std::map<K,V>::iterator
выполняет итерацию по объектам типа std::pair<K,V>
.
Ответ №5:
Ответ на ваш вопрос — да. Вы должны вернуть прокси-объект или ссылку на прокси-объект, чтобы получить такое поведение.