在 C++ 中为无序映射获取给定输入键的错误值
Obtaining wrong Value of a given input Key for an unordered map in C++
我正在尝试使用自定义构建哈希函数将对象存储在无序映射中,下面是代码,
#include <iostream>
#include <unordered_map>
#include <string>
//Class that I want to store in unordered map
class Tree{
public:
int val;
std::pair<int,int> location;
Tree(int val,std::pair<int,int> location){
this->location = location;
this->val = val;}
};
//I guess this operator is internally used by the unordered map to compare the Values in the maps.
//This function returns True only when the val of both the nodes are equal.
bool operator ==(const Tree& node1, const Tree& node2){
return node1.val == node2.val;}
//Custom build Hash Function for assigning Keys to the Values.
class HashFunction{
public:
size_t operator()(const Tree& node) const{
std::hash<int> Hash;
return Hash(node.val);
}
};
//Created a class dictionary using the std::unordered_map to store the objects.
class dictionary{
public:
std::unordered_map<Tree,Tree*,HashFunction> dict;
void append(Tree node){
this->dict[node] = &node;}
Tree* get(Tree node){
return this->dict[node];}
};
int main(){
Tree obj1(1,std::make_pair(1,6));
Tree obj2(2,std::make_pair(2,5));
Tree obj(2,std::make_pair(3,4));
dictionary dict;
dict.append(obj1);
dict.append(obj2);
std::cout<<"#################"<<std::endl;
std::cout<<dict.get(obj)->location.first<<std::endl;
}
得到的结果是'3'(如obj.val),而不是'2'(如obj2.val)。
我在main函数中创建了Treeclassobj1、obj2、obj三个对象。 obj1和obj2存放在字典中,obj用于查找字典中的匹配对象。由于哈希函数使用对象的 val 来创建键,因此 obj2 和 obj 将具有相同的键,但是当我尝试使用 obj 作为输入访问字典时,字典应该 return obj2 而不是我获取字典中没有的 obj,我不明白为什么会这样。
任何建议,将不胜感激。
提前致谢:)
在 dictionary::append
中,您插入一个指向局部变量 (node
) 的指针作为值:
this->dict[node] = &node;
一旦函数结束,该指针将不再有效。
稍后尝试取消引用该指针会导致 undefined behavior。这种未定义的行为(在您的情况下)通过访问错误的对象(特别是 dictionary::get
函数的参数)表现出来。情况可能更糟。
要修复它,您只需将函数更改为:
void append(Tree& node){
this->dict[node] = &node;}
你仍然会依赖 main
中的对象来保持存在,但至少它应该做你看起来想要的事情。
我正在尝试使用自定义构建哈希函数将对象存储在无序映射中,下面是代码,
#include <iostream>
#include <unordered_map>
#include <string>
//Class that I want to store in unordered map
class Tree{
public:
int val;
std::pair<int,int> location;
Tree(int val,std::pair<int,int> location){
this->location = location;
this->val = val;}
};
//I guess this operator is internally used by the unordered map to compare the Values in the maps.
//This function returns True only when the val of both the nodes are equal.
bool operator ==(const Tree& node1, const Tree& node2){
return node1.val == node2.val;}
//Custom build Hash Function for assigning Keys to the Values.
class HashFunction{
public:
size_t operator()(const Tree& node) const{
std::hash<int> Hash;
return Hash(node.val);
}
};
//Created a class dictionary using the std::unordered_map to store the objects.
class dictionary{
public:
std::unordered_map<Tree,Tree*,HashFunction> dict;
void append(Tree node){
this->dict[node] = &node;}
Tree* get(Tree node){
return this->dict[node];}
};
int main(){
Tree obj1(1,std::make_pair(1,6));
Tree obj2(2,std::make_pair(2,5));
Tree obj(2,std::make_pair(3,4));
dictionary dict;
dict.append(obj1);
dict.append(obj2);
std::cout<<"#################"<<std::endl;
std::cout<<dict.get(obj)->location.first<<std::endl;
}
得到的结果是'3'(如obj.val),而不是'2'(如obj2.val)。
我在main函数中创建了Treeclassobj1、obj2、obj三个对象。 obj1和obj2存放在字典中,obj用于查找字典中的匹配对象。由于哈希函数使用对象的 val 来创建键,因此 obj2 和 obj 将具有相同的键,但是当我尝试使用 obj 作为输入访问字典时,字典应该 return obj2 而不是我获取字典中没有的 obj,我不明白为什么会这样。 任何建议,将不胜感激。 提前致谢:)
在 dictionary::append
中,您插入一个指向局部变量 (node
) 的指针作为值:
this->dict[node] = &node;
一旦函数结束,该指针将不再有效。
稍后尝试取消引用该指针会导致 undefined behavior。这种未定义的行为(在您的情况下)通过访问错误的对象(特别是 dictionary::get
函数的参数)表现出来。情况可能更糟。
要修复它,您只需将函数更改为:
void append(Tree& node){
this->dict[node] = &node;}
你仍然会依赖 main
中的对象来保持存在,但至少它应该做你看起来想要的事情。