[英]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::find
時std::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.