基本标准设置逻辑

Basic std set logic

本文关键字:设置 标准      更新时间:2023-10-16

这个问题可能很枯燥,但我想确定一下。假设我有一个结构:

struct A
{
    int number;
    bool flag;
    bool operator<(const A& other) const
    {
        return number < other.number;
    }
};

代码中的某个位置:

A a1, a2, a3;
std::set<A> set;
a1.flag = true;
a1.number = 0;
a2.flag = false;
a2.number = 10;
a3 = a1;
set.insert(a1);
set.insert(a2);
if(set.find(a3) == set.end())
{
    printf("NOT FOUND");
}
else
{
    printf("FOUND");
}

我得到的输出是"FOUND"。我知道,由于我传递的是值,所以集合中的元素是按值进行比较的。但是,既然等式运算符并没有被高估,那么如何通过它们的值来比较对象A呢?我不明白如何重写运算符'<'对于集查找函数来说就足够了。

有序容器(set、multiset、map、multimap)使用一个谓词来建立元素顺序并查找值,小于的谓词。

如果两个元素都不小于另一个,则认为这两个元素相等。

这个"平等"的概念可能与你可能拥有的其他平等概念不同。有时,术语"等价"更倾向于将这种由小于排序引起的概念与可能同时存在的其他特别的相等概念(例如过载的operator==)区分开来。

对于"sane"值类型(也称为正则类型),特别等价和小于诱导等价需要相同;许多自然出现的类型是规则的(例如算术类型(如果去除NaN))。在其他情况下,特别是如果小于谓词是外部提供的,而不是由类型本身提供的,则小于等价类完全可能包含许多非"相等"值。

flag成员在这里完全无关。set已经找到了与搜索到的值相对<

也就是说,如果a不小于b,而b不小于a,那么a和b必须相等。这就是它处理普通整数的方式。这就是在CCD_ 4中确定2个值相等的方式。

std::set根本不使用==。(unordered_set是一个散列集,它确实使用了它,因为它是区分散列冲突的唯一方法)。

您也可以提供一个函数来完成<的工作,但它必须表现为严格弱排序。这对数学来说有点重,但基本上你可以通过std::greater使用>,或者定义你自己的命名函数,而不是定义operator<

因此,从技术上讲,没有什么可以阻止你定义一个operator==,它的行为与来自operator<的等价概念不同,但std::set不会使用它,它可能会让人们感到困惑。

从设置的文档

如果两个对象a和b都不是,则认为它们是等价的(不是唯一的)比其他人少:!comp(a,b)&amp!comp(b,a)

http://en.cppreference.com/w/cpp/container/set

在模板中,您可以看到

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

std::更少

将调用CCD_ 15,这就是它工作的原因。