Что означает итератор-> second?

157

В C ++, какой тип std::map<>::iterator?

Мы знаем, что объект itтипа std::map<A,B>::iteratorимеет перегруженную версию, operator ->которая возвращает a std::pair<A,B>*, и что std::pair<>элемент a имеет firstи second.

Но чему соответствуют эти два члена и почему мы должны получить доступ к значению, хранящемуся на карте, как it->second?

Noich
источник
14
A std::mapхранит ключ и значение . map::iterator.secondотносится к стоимости .
Alok Save

Ответы:

247

Я уверен, что вы знаете, что в std::vector<X>магазине хранится целая куча Xпредметов, верно? Но если у вас есть std::map<X, Y>, то, что он на самом деле хранит, это целая куча std::pair<const X, Y>с. Это именно то, что карта - она ​​соединяет вместе ключи и связанные значения.

Когда вы итерируете по a std::map, вы повторяете по всем этим std::pairs. Когда вы разыменовываете один из этих итераторов, вы получаете std::pairключ, содержащий его значение.

std::map<std::string, int> m = /* fill it */;
auto it = m.begin();

Здесь, если вы сейчас это сделаете *it, вы получите std::pairпервый элемент на карте.

Теперь тип std::pairдает вам доступ к его элементам через два члена: firstи second. Так что если у вас есть std::pair<X, Y>вызываемый p, p.firstявляется Xобъектом и p.secondявляется Yобъектом.

Итак, теперь вы знаете, что разыменование std::mapитератора дает вам std::pair, тогда вы можете получить доступ к его элементам с помощью firstи second. Например, (*it).firstдаст вам ключ и (*it).secondдаст вам значение. Это эквивалентно it->firstи it->second.

Джозеф Мэнсфилд
источник
4
Почему они просто не используют [0] и [1] (для «первого» и «второго»), как все остальное в программировании?
21
@AdamCross Потому что operator[]должен возвращать тип специфический , но firstи secondмогут иметь различные типы. С другой стороны, std::tupleимеет специальную вспомогательную функцию std::getдля доступа к своим элементам по индексу.
Джозеф Мэнсфилд
16

Тип из элементов std::map(который является также типом выражения , полученного путем разыменования этой карты) , чей ключ Kи значения является Vэто std::pair<const K, V>- ключ , constчтобы предотвратить вас от вмешательства внутренней сортировки значений карты.

std::pair<>имеет два члена по имени firstи second(см. здесь ), с довольно интуитивным значением. Таким образом, учитывая итератор iдля определенной карты, выражение:

i->first

Что эквивалентно:

(*i).first

Относится к элементу first ( const) pairобъекта, на который указывает итератор, т.е. к ключу на карте. Вместо этого выражение:

i->second

Что эквивалентно:

(*i).second

Относится ко второму элементу pair- т.е. к соответствующему значению на карте.

Энди Проул
источник
5
Слова «ключ» и «значение» были бы более интуитивными, чем «первый» и «второй», что подразумевает порядок.
августа