没有成员作为唯一标识符的两个类实例的比较

Comparison of two class instances not having members as unique identifiers

本文关键字:两个 比较 实例 成员 唯一 标识符      更新时间:2023-10-16

考虑两个类,NodeEdge,分别代表多重图的节点和边缘(请参阅下面的MWE代码(。我的目的是使用三个unordered_map

(a( 从Node变量到Edge数据,

(b( 从Edge变量到Node数据,以及

(c( 从Node对到double变量。

我尝试为Node*Edge*编写bool operator==()函数,为Node*Edge*pair<Node*,Node*>编写哈希函数。

我的第一个问题与Edgebool operator==()功能有关。尽管 Node s 的标签肯定是唯一的,但对于具有相同 start s 和 end s (( 的多个边,此bool operator==()函数是不正确的。是否有机会使用例如Edge的内存地址来构造正确的bool operator==()函数?

第二个问题是,如果只假设简单的边,这些函数是否只导致保存不同的Node/Edge/pair<Node,Node>对象。

所以,我的MWE如下:

#include<string>
#include<vector>
#include<utility>
#include<unordered_map>
#include<iostream>
#include <bits/stdc++.h> 
using namespace std;

class Node
{
   public:
      Node(){};
      string label;
      bool operator==(const Node* other) const
      {return label == other->label;};
};
class Edge
{
   public:
      Edge(){};
      Node *start, *end;
      double weight;
      bool operator==(const Edge* other) const
      {return start->label == other->start->label && 
       end->label == other->end->label;};
      //{return this == *other;}
};
namespace std
{
   template <>
   struct hash<Node*>
   {
      size_t operator()(const Node* node) const
      {return hash<string>()(node->label);}
   };
   template <>
   struct hash<Edge*>
   {
      size_t operator()(const Edge* edge) const
      {
         auto hash1 = hash<Node*>()(edge->start);
         auto hash2 = hash<Node*>()(edge->end);
         return hash1 ^ hash2; 
      }
   };
   template <>
   struct hash<pair<Node*,Node*>>
   {
      size_t operator()(const pair<Node*, Node*>& p) const
      { 
          auto hash1 = hash<Node*>()(p.first); 
          auto hash2 = hash<Node*>()(p.second);
          return hash1 ^ hash2; 
      } 
   };
}; 
int main()
{
   Edge* edge;
   Node* node;
   unordered_map<Node*,Edge> n2e;
   unordered_map<Edge*,Node> e2n;
   unordered_map<pair<Node*,Node*>,double> np2w;
   edge = new Edge();
   edge->weight = 1.0;
   edge->start = new Node();
   edge->start->label = "A";
   edge->end = new Node();
   edge->end->label = "B";
   n2e[edge->start] = *edge;
   e2n[edge] = *(edge->start);
   np2w[make_pair(edge->start, edge->end)] = edge->weight;
   edge = &n2e[edge->start];
   node = &e2n[edge];
   return 0;
}

你主要定义operator==(const Edge&, const Edge*)
而你需要operator==(const Edge*, const Edge*),但后者无法定义。

您必须编写定义operator()(const Edge*, const Edge*) const并在std::unordered_map中提供的类。

struct MyEdgeComp
{
    bool operator()(const Edge* lhs, const Edge* rhs) const {
        return *lhs == *rhs; // Assuming you implement it
    }
};
std::unordered_map<Edge*, Node, std::hash<Edge*>, MyEdgeComp> e2n;