无法使用 end() 获取地图的第二个字段

Unable to get second field of map using end()

我正在创建一个地图,只是为了学习目的来存储一些键值对。如果我使用 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;

}

std::SOMETHING.end() 不是 return 最后一个元素,它 return 是尾后元素.检查 C++ documentation。本质上,您正在做的是尝试引用未定义的内存位置。

取消引用 end()undefined behavior 作为 end() returns 指向 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 by visitor

将其转换为正向迭代器

与往常一样,您应该检查以确保您有一个有效的迭代器。如果容器为空 begin() == end() 并且解除引用是未定义的行为。

来源:http://en.cppreference.com/w/cpp/container/map/end

您可以使用 --arr.end()arr.rbegin()

arr.end() returns 指向最后一个元素之后的元素的迭代器。这样可以更轻松地编写循环。该元素仅用于比较。取消引用它是不允许的。

正如在其他帖子中已经指出的那样,end() 是一个迭代器,位于地图中最后一个元素之后的一个位置。因此,您不应尝试获取其字段。要获取最后一个元素,您可以使用 rbegin().

要打印最后一个元素,请使用 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 将 return 迭代器指向最后一个元素并取消引用它是未定义的行为。

std::map::end 在 en.cppreference

Returns an iterator to the element following the last element of the container. This element acts as a placeholder; attempting to access it results in undefined behavior.