我正在创建一个地图,仅用于学习目的,以存储一些键值对。如果我使用begin()
函数打印第二个地图字段,我可以打印地图的第二个字段,但是当我尝试使用end()
对地图的最后一个元素执行相同操作时,它无法打印第二场。以下是我的代码:
#include <iostream>
#include <cstdlib>
#include <map>
#include <string>
#include <stdio.h>
using namespace std;
map<int,std::string> arr;
map<int,std::string>::iterator p;
int main(int argc, char** argv) {
arr[1] = "Hello";
arr[2] = "Hi";
arr[3] = "how";
arr[4] = "are";
arr[5] = "you";
p = arr.begin();
printf("%s\n",p->second.c_str());
p = arr.end();
printf("%s\n",p->second.c_str());
return 0;
}
答案 0 :(得分:6)
取消引用end()
为undefined behavior,因为end()
会将迭代器返回到地图末尾的1。如果你想要最后一个元素,那么你可以使用
p = --arr.end();
你不能使用
p = arr.rbegin()
因为您无法将反向迭代器分配给前向迭代器(live example)。如果要使用rbegin()
,则必须创建反向迭代器。
map<int,std::string>::reverse_iterator rit;
rit = arr.rbegin();
// or
auto rit = arr.rebegin(); //C++11 or higher required for this
或者您可以this answer使用visitor将其转换为转发迭代器
一如既往,您应该检查以确保您拥有有效的迭代器。如果容器为空begin() == end()
,则取消引用任何一种都是未定义的行为。
答案 1 :(得分:2)
您可以使用--arr.end()
或arr.rbegin()
。
arr.end()
将迭代器返回到最后一个元素之后的元素。这允许更容易的写循环。此元素仅用于比较。不允许取消引用它。
答案 2 :(得分:2)
要打印最后一个元素,请使用reverse iterator:
map< int,std::string>::reverse_iterator p;
p = arr.rbegin();
if( p != arr.rend() ) {
// Do whatever with, it points to the last element
} else {
// map is empty
}
std::map::end
会将迭代器返回到最后一个元素,并且取消引用它是未定义的行为。
来自en.cppreference的std::map::end
返回元素的最后一个元素后面的元素的迭代器 容器。该元素充当占位符;试图访问它 导致未定义的行为。
答案 3 :(得分:1)
std :: SOMETHING.end()不返回最后一个元素,它返回past-the-end元素。检查C ++ documentation。从本质上讲,你正在做的是尝试尊重未定义的内存位置。
答案 4 :(得分:1)
正如其他帖子中已经指出的那样end()
是一个迭代器,它位于地图中最后一个元素之后的一个位置。因此,你不应该试图得到它的领域。要获取最后一个元素,您可以使用rbegin()
。