我在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;或==?
答案 0 :(得分:1)
您提供的Comparator
类应实施订单比较,以便std::set
可以使用它来构建二进制搜索树。
这意味着您的operator()
不应该是对称的 - 默认情况下它是&#34;小于&#34;比较。
一般来说,operator()
类的Comparator
应代表您班级的严格顺序关系,因此它应该是
C(a,b) && C(b,c)
表示C(a,c)
C(a,b)
表示!C(b,a)
!C(a,b) && !C(b,a)
表示&#34; a和b相等&#34; &#34;平等的最后定义&#34;是std::set
在您致电set::find
时使用的内容。
解决方案虽然您确实可以提出一些符合上述规则的排序,但也许您可以使用一些重构。
如果您的TypedObject
拥有&#34;地址标识&#34; (即任何对象只等于它自己),那么你可以使用默认比较 - 它适用于指针:
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中使用它们,并且您不需要处理额外的比较器类和内存管理。
答案 1 :(得分:0)
您的订单比较是错误的,因为基于相等性它将无法创建BST,因此正确的代码应如下所示(注意&lt;在比较器中)
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlConnection sqlcon1 = new SqlConnection(@"Data Source=PRATHISTA;Initial Catalog=CRMT;Integrated Security=True");
sqlcon1.Open();
SqlCommand cmd1 = new SqlCommand("select * from Requirement", sqlcon1);
try
{
SqlDataReader sda1 = cmd1.ExecuteReader();
while (sda1.Read())
{
string sId = sda1.GetString("Requirement_Id");
// i get the error here;
}
sda1.Close();
sqlcon1.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error:" + ex);
}
}