对新结构的Oploading Operator()

Overloading operator() for a new struct

本文关键字:Oploading Operator 结构 新结构      更新时间:2023-10-16

我在c:

中定义了一个新的 struct
typedef struct TypedObject {
    ObjectType type;
    void * value;
} TypedObject; 

其中objecttype是一个枚举:

typedef enum ObjectType {
    type_node,
    type_int,
    type_error,
} ObjectType; 

我想创建一组C TypedObject指针,从以前的问题中,我知道我需要超载operator(),以便在插入集合的TypedObject指针之间进行比较。

因此,我按照以下方式进行操作:

#ifdef __cplusplus
typedef struct {
    bool operator() (const TypedObject *lhs, const TypedObject *rhs){
        return (lhs->type==rhs->type) && (lhs->value==rhs->value);
    }
} ObjComparator;
#endif

假设我定义了一个集:

std::set<TypedObject *, ObjComparator> mySet;

您可以假设我使用迭代器进行迭代。

我想将TypedObject x插入集合。我使用mySet.insert(&x)插入其地址。但是,一旦使用mySet.find(&x),它将无法找到x。对operator()进行了调用,但并未按预期进行比较。

知道我超负荷operator()的方式可能会出现什么问题?我究竟做错了什么?另外,我是否应该超载其他版本的运算符,例如&lt;或==?

您提供的Comparator类应实现订单比较,以便std::set可以使用它来构建二进制搜索树。

这意味着您的operator()不应对称 - 默认情况下它是"小于"比较。

通常,Comparator类的operator()应该代表您的班级的严格订单关系,因此应为

  • 传递-C(a,b) && C(b,c)表示C(a,c)
  • 反对称 - C(a,b)表示!C(b,a)
  • 总计-!C(a,b) && !C(b,a)的意思是" A和B相等"

"平等"的最后一个定义是std::set调用set::find时使用的。

解决方案:虽然您肯定可以提出一些订购以满足上述规则的订购,但也许您可以使用一些重构来完成。

如果您的TypedObject s具有"地址身份"(即任何对象仅等于自身(,则您可以使用默认比较 - 它非常适合指针:

std::set<TypedObject *> mySet;  

如果您需要比较成员,则通常的方法将是这样的:

bool operator() (const TypedObject *lhs, const TypedObject *rhs)
{
    if(lhs->value < rhs->value) return true;
    if(rhs->value < lhs->value) return false;
    return (lhs->type < rhs->type)
}

请注意,如何仅在operator<上为会员归还。实际上,最好定义operator<比较TypedObject s,然后从指针Comparator调用它。

最后,如果您的set拥有对象(即离开集合时对象被破坏(,那么也许最好只使用

std::set<TypedObject> mySet;

使用operator<TypedObject重载。您仍然可以从集合中获得对象的指针,并在C API中使用它们,并且您无需处理额外的比较器类和内存管理。

您的订单比较是错误的,因为基于平等,它将无法创建BST,因此正确的代码应如下(Note&lt;在比较器中(

typedef enum ObjectType {
    type_node,
    type_int,
    type_error,
} ObjectType; 
typedef struct {
    ObjectType type;
    void * value;
} TypedObject; 

typedef struct {
    bool operator() (const TypedObject *lhs, const TypedObject *rhs){
        return (lhs->type==rhs->type) && (lhs->value<rhs->value);
    }
} ObjComparator;
int main()
{
  std::set<TypedObject *, ObjComparator> mySet;
  TypedObject obj;
  obj.type=type_int;
  obj.value=(void*)new int;
  //*(obj.value)=4;
  auto insert  = mySet.insert(&obj);
  std::cout<<insert.second<<std::endl;
  if(mySet.find(&obj) == mySet.end())
  {
      std::cout<<"Not Found..."<<std::endl;
  }
  else
  {
      std::cout<<"Found..."<<std::endl;
  }
  return 0;
}