Class 无序映射::find()和两个迭代器

Class 无序映射::find()和两个迭代器,class,c++11,iterator,return-value,unordered-map,Class,C++11,Iterator,Return Value,Unordered Map,与私人成员一起上课 std::unordered_map<std::string, size_t> myMap; 尽管我寻找相同的键“a”,迭代器指向不同的元素。以下示例代码说明了该问题: #include <iostream> #include <unordered_map> #include <vector> #include <string> class MyMap{ public: MyMap(){ myMap

与私人成员一起上课

std::unordered_map<std::string, size_t> myMap;
尽管我寻找相同的键“a”,迭代器指向不同的元素。以下示例代码说明了该问题:

#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>

class MyMap{
 public:
  MyMap(){
    myMap= {
      {"a", 1},
      {"b", 2}
    };
  }

  std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}

private:
  std::unordered_map<std::string, size_t> myMap;
};

int main(){

  MyMap test;

  auto pos1 = test.getMyMap().find("a");
  auto pos2 = test.getMyMap().find("a");
  std::cout << pos1->first << "\t" << pos1->second << std::endl;
  std::cout << pos2->first << "\t" << pos2->second << std::endl;
}
其中第一行是意外的。它应该是“a 1”

将代码更改为

  auto pos3 = test.getMyMap().find("a");
  std::cout << pos3->first << "\t" << pos3->second << std::endl;
  auto pos4 = test.getMyMap().find("a");
  std::cout << pos4->first << "\t" << pos4->second << std::endl;
此外,只需在主文件中创建无序的_映射并应用find()即可。问题似乎与getter方法有关,可能与返回值优化有关。您对这种现象有什么解释吗?

这是因为您的代码中有。
getMyMap
返回映射的副本,该副本在表达式
test.getMyMap().find(“a”)
完成后被销毁

这意味着您有两个迭代器指向不再存在的映射

解决方案非常简单:让
getMyMap
返回一个常量引用:

std::unordered_map<std::string, size_t> const& getMyMap() const;
std::无序映射常量&getMyMap()常量;

在后一种情况下,它似乎是有效的,因为这是一个未定义行为的陷阱,有时它可能看起来是有效的,而实际上它不是在原始
myMap
的副本上查找
,该副本在表达式完成后被销毁,使迭代器
pos1
pos2
成为不存在的映射,调用未定义的行为

相反,您可以像下面这样玩:

  auto mymap = test.getMyMap() ;   // Store a copy

  auto pos1 = mymap.find("a");    // Then do stuff on copy
  auto pos2 = mymap.find("a");

我觉得有点傻。。。@JoachimPileborg的答案为我的案例提供了完美的解决方案。非常感谢你们两位!
  auto pos3 = test.getMyMap().find("a");
  std::cout << pos3->first << "\t" << pos3->second << std::endl;
  auto pos4 = test.getMyMap().find("a");
  std::cout << pos4->first << "\t" << pos4->second << std::endl;
a   1
a   1
std::unordered_map<std::string, size_t> const& getMyMap() const;
  auto mymap = test.getMyMap() ;   // Store a copy

  auto pos1 = mymap.find("a");    // Then do stuff on copy
  auto pos2 = mymap.find("a");