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");