C++ 在C++;如果它是反身真实的,那就工作吧?

C++ 在C++;如果它是反身真实的,那就工作吧?,c++,stl,stdmap,C++,Stl,Stdmap,我的项目中有一张地图。 每次我插入新元素时,我都希望确保我插入的新元素的键与地图中的其他元素至少相隔一个最小宽度。为此,我编写了一个自定义比较类,如下所示: class PulseCompare { public: PulseCompare(int minwidth_):minwidth(minwidth_){}; bool operator()(const int x, const int y) const { if(abs(x-y)>minwidth)

我的项目中有一张地图。 每次我插入新元素时,我都希望确保我插入的新元素的键与地图中的其他元素至少相隔一个最小宽度。为此,我编写了一个自定义比较类,如下所示:

class PulseCompare
{
public:
    PulseCompare(int minwidth_):minwidth(minwidth_){};
    bool operator()(const int x, const int y) const {
        if(abs(x-y)>minwidth) return false;
        else return true;
    }
private:
    int minwidth;
};
std::map<int,float,PulseCompare> pulsemap(PulseCompare(256));
if ( pulsemap.find(1600) == pulsemap.end() ) {
  // not found so I can insert
} else {
  // found
}
并创建了如下地图:

class PulseCompare
{
public:
    PulseCompare(int minwidth_):minwidth(minwidth_){};
    bool operator()(const int x, const int y) const {
        if(abs(x-y)>minwidth) return false;
        else return true;
    }
private:
    int minwidth;
};
std::map<int,float,PulseCompare> pulsemap(PulseCompare(256));
if ( pulsemap.find(1600) == pulsemap.end() ) {
  // not found so I can insert
} else {
  // found
}
但问题是,当map试图通过交换
x
y
的值来使用上述比较函数进行反射性比较时,对于这两种情况,map都会得到
true
,这通常不是像
这样的普通比较运算符的情况

在cplusplus文档页面的
std::map::key\u comp
上,它说

地图对象的比较对象在构造时设置。其类型(成员键\u比较)是映射模板的第三个模板参数。默认情况下,这是一个less对象,返回与运算符相同的值“
  • std::map
    中使用的比较器必须提供一个对象类型
  • 你的比较器没有
  • 因此,
    std::map
    的实例将产生未定义的行为
  • 注意:一般来说,让比较器提供一个总排序比较容易

    另外,让我们来描述严格弱排序需要什么

    • 您将创建一个函子
      Compator comp;
      我将把
      comp(lhs,rhs)
      看作是一个返回布尔值的函数。把它看作
      lhs
      是很有帮助的
    • 我们将创建一个函数
      equiv(lhs,rhs)
      。它被定义为
      (!comp(lhs,rhs)和&&!comp(rhs,lhs))
      。因此,
      !(lhs
    我们需要遵守以下规则:

    comp(a, b) && comp(b, c) implies comp(a, c)
    equiv(a, b) && equiv(b, c) implies equiv(a, c)
    

    实际上,如果您以这种方式重写比较器,它应该可以工作:

    bool operator()(const int x, const int y) const {
        if(abs(x-y)<=minwidth) return false;
        else return x < y;
    }
    
    bool操作符()(常量int x,常量int y)常量{
    
    如果(abs(x-y),为什么不把它作为你的比较器呢

    return minwidth < (y - x);
    
    返回最小宽度<(y-x);
    

    这里有一个工作示例:

    你想知道如果a>b和b>a会发生什么情况……上帝,我希望宇宙不会破裂我甚至不知道
    std::map pulsemap(PulseCompare(256));
    是@P0W,你可以通过构造函数传递比较对象arguement@VivekVK你能告诉我你的例子是怎样的吗?(分享链接)我从来没有用过它。@POW非常抱歉。我刚刚意识到有一个输入错误。我必须在模板中给出compare类,然后才能传递参数。我现在已经编辑了它。我想现在它可以让事情变得清楚了。不幸的是,这个操作符没有提供严格的弱排序。特别糟糕的是,它似乎对m有效ost值被插入到映射中,但有一些情况下映射会严重损坏。@chrisddod您能给我一个失败的例子吗?插入两个差值略大于minwidth的值,然后在这两个值之间插入一个值(在两者的minwidth范围内)这将给出一个包含两个值的映射,该值与比较器的值相等,并且事情将从那里开始下降。失败的细节将取决于 STD::MAP 在库中的内部实现细节。@克里斯多德考虑MINWLASH=100。我先插入100。然后201,这不是问题。如果我在插入150,然后比较器将检查abs(100-150)假设一个简单的红黑树。先插入100,然后插入201。现在插入150;它将替换100,树中有150和201(minwidth内的两个值)如果这还不够坏,现在插入225;它将替换150,然后插入305;它将替换225。现在搜索201,它将找不到它,因为它将在树的错误分支中查看……考虑我已经有1700个,并且我插入1600,1800。ice检查相等性(每边一次)。不需要abs。有吗?我没有说在比较器中交换x和y。我希望插入元素不在当前元素中加上或减去minwidth。我需要abs()检查当前元素的两面。我是否有意义?还是我仍然错了,不理解它?您仍然不理解。比较函数本质上是一个“小于”运算符。Map将调用
    compare(a,b)
    查看“acompare(b,a)
    查看
    b
    。你一直在尝试编写一个比较函数,当你只需要编写一个返回“acomp(a,b)意味着
    !comp(b,a)
    ,而
    comp(a,a)
    是假的。