基本标准设置逻辑

时间:2015-12-16 10:32:49

标签: c++ std

这可能是一个枯燥的问题,但我想确定。 让我们说我有一个结构:

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");
}

我得到的输出是&#34; FOUND&#34;。我理解,因为我传递值,所以set中的元素按值进行比较。但是,对象A如何通过它们的值进行比较,因为相等运算符没有被覆盖?我不明白最重要的操作符&#39;&lt;&#39;对于集合查找功能来说已经足够了。

3 个答案:

答案 0 :(得分:3)

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

如果两个元素都不小于另一个元素,则认为它们是相等的。

这个概念如果“平等”可能与你可能拥有的其他平等概念不同。有时候,“等价”这个术语更倾向于区分这种概念,这种概念是由可能同时存在的其他特殊的平等概念(例如,过载的operator==)所引起的,而不是排序。

对于“理智”的值类型(也称为常规类型),ad-hoc相等和低于诱导的等价要求是相同的;许多自然发生的类型是规则的(例如算术类型(如果NaN被移除))。在其他情况下,特别是如果小于谓词是在外部提供而不是由类型本身提供的,那么小于等价类完全有可能包含许多非“相等”的值。

答案 1 :(得分:2)

flag成员在这里完全无关紧要。 set找到的元素与搜索到的值相同,相对于&lt;

即,如果a不小于b,并且b不小于a,则a和b必须相等。这是正常整数的工作原理。这就是决定std::set中2个值是等价的方式。

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

您还可以提供执行<工作的功能,但它必须表现为strict weak ordering。这对数学来说有点沉重,但基本上你可以通过std::greater使用>,或者定义你自己的命名函数而不是定义operator<

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

答案 2 :(得分:1)

来自set

的文档
  

两个对象a和b被认为是等价的(不唯一)   比较少:!comp(a,b)&amp;&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 ::以下

将致电operator<,这就是它的原因。