拥有私人会员的课程
std::unordered_map<std::string, size_t> myMap;
和相应的getter
std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}
我通过两次应用std :: unordered_map :: find()来观察奇怪的行为,每次都保存返回的迭代器,例如
auto pos1 = test.getMyMap().find("a");
auto pos2 = test.getMyMap().find("a");
Altough我寻找相同的钥匙&#34; a&#34;迭代器指向不同的元素。以下示例代码说明了问题:
#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;
}
使用g ++ -std = c ++ 11进行编译并运行
b 2
a 1
第一行意外。它应该是&#34; 1&#34;。
将代码更改为
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
此外,只需在主文件中创建unordered_map并应用find()即可。似乎问题与getter方法有关,可能与返回值优化有关。你对这种现象有什么解释吗?
答案 0 :(得分:0)
这是因为您的代码中有undefined behavior。 getMyMap
会返回地图的副本,这是在表达式test.getMyMap().find("a")
完成后会被破坏的副本。
这意味着您有两个指向不再存在的映射的迭代器。
解决方案非常简单:让getMyMap
返回一个常量引用:
std::unordered_map<std::string, size_t> const& getMyMap() const;
它似乎适用于后一种情况,因为它是未定义行为的陷阱,它可能有时似乎就像它起作用,而实际上它并没有。
答案 1 :(得分:0)
test.getMyMap().find("a");
对原始find
的副本执行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");