【问题标题】:Unable to get second field of map using end()无法使用 end() 获取地图的第二个字段
【发布时间】:2015-09-27 20:10:22
【问题描述】:

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

}

【问题讨论】:

标签: c++ dictionary std stdmap c++-standard-library


【解决方案1】:

取消引用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 by visitor 将其转换为前向迭代器

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

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

【讨论】:

  • "begin() == end()" - 我认为arr.empty() 更清晰。它也可能更快。
  • @NO_NAME 我只是在演示如果容器为空,使用begin() 与end() 相同。
【解决方案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 会将迭代器返回到最后一个元素,取消引用它是未定义的行为。

来自std::map::end en.cppreference

返回一个迭代器到最后一个元素之后的元素 容器。该元素充当占位符;试图访问它 导致未定义的行为。

【讨论】:

    【解决方案3】:

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

    arr.end() 将迭代器返回到最后一个元素之后的元素。这允许更容易编写循环。此元素仅用于比较。不允许取消引用它。

    【讨论】:

      【解决方案4】:

      std::SOMETHING.end() 不返回最后一个元素,它返回最后一个元素。检查 C++ documentation。本质上,您正在做的是试图尊重未定义的内存位置。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2016-07-05
          • 1970-01-01
          • 1970-01-01
          • 2021-02-23
          • 1970-01-01
          • 1970-01-01
          • 2013-02-06
          • 1970-01-01
          • 2021-12-10
          相关资源
          最近更新 更多