Оператор перегрузки-> для итератора STL - PullRequest
1 голос
/ 14 октября 2011

Я пишу собственную реализацию контейнера карты C ++ STL.Сейчас я пытаюсь реализовать итератор.Это должно позволить вам сделать что-то вроде iter-> first и iter-> second, которое возвращает ключ / значение соответственно и где iter является объектом, а не указателем.Мне интересно, как мне это перегрузить?Это немного сбивает с толку, потому что я не уверен, каким должен быть тип возвращаемого значения;это должен быть объект с членами первый / второй, я полагаю.Типично ли возвращать ссылку на объект-оболочку / интерфейс или что-то в этом роде?

Ответы [ 5 ]

6 голосов
/ 14 октября 2011

Если вы действительно имеете в виду стандартную библиотеку C ++, то value_type для map - это pair.В паре есть члены first и second.Разыменование итератора в map дает вам pair.

6 голосов
/ 14 октября 2011

Да, вам нужен прокси для хранения соответствующей ссылки.

Что касается типа: итераторы стандартной библиотеки обычно разыменовывают что-то типа value_type. Для map<K,V> типом значения является std::pair<K, V> (точнее, pair<key_type, mapped_type>), откуда вы получаете интерфейс first / second.

(Одна из лекций Стефана Лававея объясняет, как реализация MSVC ++ использует одну и ту же базовую структуру данных для set и map; единственное отличие состоит в том, что set::value_type равняется set::key_type, тогда как map::value_type равно pair<key_type, mapped_type> Таким образом, вы можете отличить их друг от друга с помощью простой проверки черт, но интерфейс итератора практически идентичен.)

3 голосов
/ 14 октября 2011

тип_значения стандартной карты: 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 &pair; }
  std::pair<const int, int>& operator*() { return pair; }
};

int main()
{
  It it = {std::make_pair(10, 20) };
  (*it).second = 30;
  std::printf("%d %d\n", it->first, it->second);
}
2 голосов
/ 14 октября 2011

std::map<K,V>::iterator перебирает объекты типа std::pair<K,V>.

1 голос
/ 14 октября 2011

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

...