迭代器 -> second 是什么意思?

191

C++中,std::map<>::iterator的类型是什么?

我们知道,类型为std::map<A,B>::iterator的对象it具有重载的operator ->,该运算符返回一个std::pair<A,B>*,并且std::pair<>有一个firstsecond成员。

但是,这两个成员分别对应什么,为什么我们必须访问存储在映射中的值作为it->second


15
std::map 存储一个 和一个 map::iterator.second 指的是这个 - Alok Save
3个回答

308

我相信你知道 std::vector<X> 存储了很多个 X 对象,对吧?但如果你有一个 std::map<X, Y>,它实际存储的是许多 std::pair <const X,Y> 的组合。这正是 map 的作用——将键和相关的值配对在一起。

当你遍历一个 std::map 时,你正在遍历所有这些 std::pair。当你解引用其中一个迭代器时,你会得到一个包含键和其相关值的 std::pair

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

现在,如果你执行*it,你将获得映射中第一个元素的std::pair

现在std::pair类型通过两个成员变量firstsecond来访问其元素。因此,如果你有一个名为pstd::pair<X,Y>p.first是一个X对象,而p.second是一个Y对象。

现在你知道对std::map迭代器进行解引用会给你一个std::pair,然后你可以使用firstsecond访问它的元素。例如,(*it).first将给出键,(*it).second将给出值。这等同于it->firstit->second


5
在编程中,为什么他们不直接使用[0]和[1](分别表示“第一”和“第二”)像其他地方一样呢?请问你的想法是什么? - user1052335
28
因为 operator[] 必须返回一个特定类型,但是 firstsecond 可能有不同的类型。另一方面,std::tuple 有一个特殊的助手函数 std::get,用于通过索引访问其元素。 - Joseph Mansfield
官方文档的补充:map成员类型下有value_type,它是指向 pair 的引用,并且可以看到其成员变量 firstsecond - Xiang
为什么他们不直接称之为 keyval 或者甚至是 kv,这样更加符合逻辑和易于推断,而不是使用像 first 和 second 这样晦涩难懂的术语? - Leslie Krause

23

当一个 std::map 的键为 K,值为 V 时,它的元素类型(也是通过对该 map 的迭代器进行解引用获得的表达式的类型)为 std::pair<const K, V> - 键是 const,以防止您干扰 map 值的内部排序。

std::pair<> 有两个名为 firstsecond 的成员(请参见这里),具有相当直观的含义。因此,给定一个指向某个 map 的迭代器 i,表达式:

i->first

等同于:

(*i).first

指向迭代器所指的 pair 对象中的第一个 (const) 元素 - 即它指向 map 中的一个 。相反,以下表达式:

i->second

等价于:

(*i).second

指的是pair的第二个元素 - 也就是映射中对应的


10
“键”和“值”这两个词比“第一”和“第二”更直观,因为前者暗示着键值对的关系而非排序关系。 - ahoffer
@ahoffer 让我们重载它 :D - Noob

1

用于地图和无序地图。

map存储键值对,其中i->first表示键,i->second反映值。

#include<bits/stdc++.h>
#define long long int
using namespace std;
int32_t main(){
  map<int,int> m;
  m.insert({1,2});
  m.insert({2,4});
  for(auto i:m){
      cout<<"key - "<<i.first<<" "<<" Value - "<<i.second<<endl;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接