Оператор перегрузки-> для итератора STL

#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 a map по-прежнему является a pair ;-p

2. @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:

Ответ на ваш вопрос — да. Вы должны вернуть прокси-объект или ссылку на прокси-объект, чтобы получить такое поведение.