智能指针作为无序映射键,并通过引用进行比较
Smart pointers as unordered_map key and compare them by reference
我想使用unordered_map
通过引用来比较元素。我试图通过插入智能指针作为键来实现这一点(因为我不想使用原始指针(,并实现了EqualFunction
来比较智能指针的底层引用。但是,地图无法正确查找元素。
#include <memory>
#include <unordered_map>
#include <iostream>
using namespace std;
class Node {};
typedef shared_ptr<Node> NodePtr;
struct HashFunction {
unsigned long operator()(const NodePtr& key) const {
return (unsigned long)key.get();
}
};
struct EqualFunction {
bool operator()(const NodePtr& t1, const NodePtr& t2) const {
return t1.get() == t2.get();
}
};
class Map
{
unordered_map<NodePtr, int, HashFunction, EqualFunction> map;
public:
void insert(NodePtr nodeToInsert, int val)
{
map.insert({nodeToInsert, val });
}
bool exist(NodePtr node) {
if (map.find(node) == map.end()) return false;
return true;
}
};
int main()
{
Node node; Map map;
auto nodePtr = make_shared<Node>(node);
map.insert(nodePtr, 1);
auto ptrToSameNode = make_shared<Node>(node);
if (map.exist(ptrToSameNode))
cout << "Node exists.";
else cout << "Node doesn't exist.";
}
上面的代码打印出"节点不存在",即使我在搜索同一个节点。
为什么不想使用原始指针?使用它们。智能指针用于管理所有权,而不是用于指向在其他地方创建的对象。
using NodePtr = Node*;
struct HashFunction {
size_t operator()(const NodePtr& key) const { return (size_t)key; }
};
struct EqualFunction {
bool operator()(const NodePtr& t1, const NodePtr& t2) const { return t1 == t2; }
};
...
int main()
{
Node node; Map map;
auto nodePtr = &node;
map.insert(nodePtr, 1);
auto ptrToSameNode = &node;
if (map.exist(ptrToSameNode))
cout << "Node exists.";
else cout << "Node doesn't exist.";
}
正如@Piotr Skotnicki在评论中所写,问题是您最初创建了3个Node
对象,即node
加上2个动态分配的复制node
的对象(通过make_shared
(。因此,然后(按地址(比较了Node
类的2个不同实例。
或者,您可以使用共享指针,但您需要动态创建Node
对象(而不是像代码中那样在堆栈上静态创建(。如果您不希望Map
"拥有"所包含的对象,您也可以使用弱指针,但是,您的比较会较慢(通过"锁定"执行,即从弱指针创建共享指针(,并且会有大量的运行时和内存开销。
相关文章:
- 智能指针作为无序映射键,并通过引用进行比较
- 将指针与引用进行比较
- 使用模板专用化来比较指针引用
- 类型ID指针和引用比较差异?
- 通过查看程序集来比较按值传递与按引用传递性能
- std::具有自定义比较函数结果的排序函数错误:必须调用对非静态成员函数的引用
- 比较地图对象及其引用C++
- 将 Java 的按值传递与C++的按值传递或引用进行比较
- 使用比较函数对引用类型失败
- 正确编写引用的比较运算符
- 在C++中,如何让(嵌套)比较函子引用封闭类的数据
- 比较未引用的映射迭代器(std::pairs):C2678
- 如何比较两个 std::istream 引用
- C++ std::sort 引用另一个列表的自定义比较函数
- 正在比较JNI对象引用
- C++ 无法将取消引用的字符指针与字符进行比较
- C++lambda通过引用捕获这个与捕获的比较
- 比较身份引用的标准方法
- 更好的std::在指针集合上查找,并将取消引用的值与常量引用值进行比较
- 通过引用比较链表中的节点