我使用了一个非常简单的结构,映射,定义如下:struct mapping{ int code; string label; bool operator<(const mapping& map) const { return code < map.code; } bool operator==(const mapping& map) const { return label.compare(map.label) == 0 ; }};我想创建一组按他们的代码排序的映射。为此,我重载了 当我尝试插入具有相同代码但不同标签的映射时,问题就出现了。实际上,在该过程的第二步中,我不知道之前是否插入了具有相同标签的映射。所以,我需要调用 find() 函数来确定是否是这种情况。如果没有插入具有相同标签的映射,没关系,我只需要插入这个新的映射(但它的代码将暂时与其他映射相同)。如果存在具有相同标签的一个映射,我只需要更新其代码。我认为像我那样重载 == 运算符应该就足够了,但情况并非如此,如下面的代码所示。mapping m = {1,"xxx"};mapping m2 ={1, "yyy"};this->fn[0].insert(m);set<mapping>::iterator itTmp;itTmp = this->fn[0].find(m2);if (itTmp != this->fn[0].end() ) { cout << "m2 exists "<<endl; if ( !(*itTmp == m2) ){ cout << "But it is different according to the definition of the == operator "<<endl; }}相关输出为:m2 existsBut it is different according to the definition of the == operator我如何解决这个问题并设法处理具有非常不同语义的运算符 谢谢,约安 最佳答案 如果一个类可以按其多个字段进行合理排序,则它根本不应该有关系运算符(除了 operator== 和 operator!= )。是的,std::map 和 std::set 默认使用 std::less 作为比较器(它在内部使用 operator<),但这只是为了方便,所以你不需要编写一个函数对象来创建一个 set<double> ,其中 double 有一个规范的排序顺序(因此定义一个(内置) operator< )。它们还提供了一个比较器模板参数,您可以并且应该使用它来准确地提供该容器(如关系数据库)所需的索引。还有一些容器(在 boost 中)为一组元素维护多个索引。例如,考虑一个 point2d 类:struct point2d { int x, y; };可以合理地希望通过 point2d 或 x 索引 y 的容器,因此按照上述,point2d 根本不应该定义 operator<。为了避免类的每个用户都发明自己的排序函数对象,可以将它们与 point2d 一起提供:struct less_point2d_by_x { typedef bool result_value; // the mixed overloads are for use in std::lower_bound and similar bool operator()( int lhs, int rhs ) const { return lhs < rhs; } bool operator()( int lhs, point2d rhs ) const { return lhs < rhs.x; } bool operator()( point2d lhs, int rhs ) const { return lhs.x < rhs; } bool operator()( point2d lhs, point2d rhs ) const { return lhs.x < rhs.x; }};// same for _y用法:std::vector<point2d> v = ...;std::sort(v.begin(), v.end(), less_point2d_by_x()); // sort by xstd::sort(v.begin(), v.end(), less_point2d_by_y()); // sort by ystd::set<point2d, less_point2d_by_x> orderedByX;std::set<point2d, less_point2d_by_y> orderedByY;如果您不害怕模板,您甚至可以将关系运算符模板化,如下所示:template <template <typename T> class Op=std::less>struct point2d_by_x { typedef bool result_value; // the mixed overloads are for use in std::lower_bound and similar bool operator()( int lhs, int rhs ) const { return Op<int>()(lhs, rhs); } bool operator()( int lhs, point2d rhs ) const { return Op<int>()(lhs, rhs.x); } bool operator()( point2d lhs, int rhs ) const { return Op<int>()(lhs.x, rhs); } bool operator()( point2d lhs, point2d rhs ) const { return Op<int>()(lhs.x, rhs.x); }};// same for _y用法:std::vector<point2d> v = ...;std::sort(v.begin(), v.end(), point2d_by_x<std::less>()); // sort ascending by xstd::sort(v.begin(), v.end(), point2d_by_x<>()); // samestd::sort(v.begin(), v.end(), point2d_by_x<std::greater>()); // sort descending by x// find the position where a `point2d` with `x = 14` would go in the ordering:std::lower_bound(v.begin(), v.end(), 14, point2d_by_x<std::greater>());std::set<point2d, point2d_by_x<std::less> > increasingXOrder;std::set<point2d, point2d_by_y<std::less> > increasingYOrder;关于c++ - 一组具有不同 == 和 < 运算符语义的结构体,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11135463/
10-15 00:29