繁体   English   中英

重载operator()以获取新结构

[英]Overloading operator() for a new struct

我在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()的方式可能是什么问题吗? 我究竟做错了什么? 另外,是否应该重载<或==之类的其他版本的运算符?

您提供的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相等”

“平等”的最后定义是调用set::findstd::set使用的内容。

解决方案:虽然您当然可以提出一些可以满足上述规则的排序,但是也许可以进行一些重构。

如果您的TypedObject具有“地址标识”(即,任何对象都仅等于其自身),则可以使用默认比较-它非常适合指针:

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 ,然后从指针Comparator调用它。

最后,如果您的设备set拥有对象(即对象在离开设备集时被销毁),那么最好使用

std::set<TypedObject> mySet;

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

您的订单比较是错误的,因为基于相等性,它将无法创建BST,因此正确的代码应如下所示(比较器中的<注意)

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM