C++ 严格弱序

什么是严格弱序?

C++关联容器的有序容器对元素关键字的类型有要求,元素关键字的类型必须定义了严格弱序(stick weak ordering)
拿内置类型来说,C++都定义了 “<”操作符,这就是一个严格弱序,而“<=”就不是一个严格弱序


严格弱序有什么用?

对于内置类型我们自然可以有<、>、=来判断两个值的大小关系,而对于自定义的类类型,为它定义三种比较操作符是没有必要的,只用一个严格弱序(这里就用<为例)就可以表示两个元素三种大小关系

  • a小于b

    a < b

  • b小于a

    b < a

  • a等于b

    !(a < b) && !( b < a )


严格弱序的三条要求

  1. 两个关键字不能同时“严格弱序”于对方
  2. 如果a“严格弱序”于b,且b“严格弱序”于c,则a必须“严格弱序”于c
  3. 如果存在两个关键字,任何一个都不“严格弱序”于另一个,则这两个关键字是相等的。

如果我们把<代入上面的要求,代替掉“严格弱序”,会发现这三条要求简直是理所当然的,这是因为<正是严格弱序的。反之,如果代入<=就会发现逻辑上的错误:

1.两个关键字不能同时“<=”于对方
显然有a<=b,b<=a,a,b相等时成立
2.如果存在两个关键字,任何一个都不“<=”于另一个,则这两个关键字是相等的。
a不小于等于b,且b也不小于等于a,也就是a>b且b>a,这明显是一个伪命题

我们定义一个具体的函数来说明它是怎么满足和不满足严格弱序要求的,以及不满足严格弱序有什么后果

//定义一个结构体,该结构体没有提供严格弱序操作,必须额外为它定义一个严格弱序操作
struct MyStruct
{
    int val;
    MyStruct(int _val):val(_val){}

};

//定义两个“我们所期望的严格弱序操作”
bool Compare1(const MyStruct &a, const MyStruct &b)
{
    return a.val < b.val;
}
//虽然很容易看出Compare2并不是一个严格弱序操作
//但我们站在编译器的角度,用上面的三条要求来判别
bool Compare2(const MyStruct &a, const MyStruct &b)
{
    return a.val <= b.val;
}


可以看出Compare2方法在判断相等的逻辑式(!C2(a,b)&&!C2(b,a))上出现错误,而且恒为false,也就是任何a,b关键字都认为是不相等的。

 这样的非严格弱序方法带来的问题

有序关联容器不允许存在相同的关键字,在用Compare2判断时,会认为相同的关键字是不相等的,因此会将两个相同的关键字插入容器中,这个行为是未定义的

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页