基本标准设置逻辑
Basic std set logic
这个问题可能很枯燥,但我想确定一下。假设我有一个结构:
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)&!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,这就是它工作的原因。
- 是否允许使用带有"w+"模式的 freopen 进行标准设置?
- 无法重置 std::shared_ptr 标准::设置<>中的对象...为什么?
- 使用 lambda 表达式的 Raspbian G++ 8.3.0 导致 ']' 之前的预期主表达式 - 即使标准设置为 c++14
- 查找不在标准中的第一个值::设置<int>最小-最大值
- C++ Cmake没有在Travis CI服务器上设置编译器语言标准
- 如何在不使用命名空间标准的情况下取消设置ios::fixed
- 将标准:设置为<int> jintArray
- 如何优化标准::设置交集算法(C++)
- 无法使用 Visual Studio 和 CMake 将__cplusplus设置为 C++17 标准
- 如何获取标准::设置的相对索引
- C++ 在标准::unordered_map中设置 std::tuple 值
- 标准::设置运算符的使用<
- 将标准::设置与自定义比较器进行比较
- 在编译时填充标准::设置
- 如何比较两个比较两个标准::设置
- 在此初始值设定项方法上将整个数组设置为 NULL 是否C++标准?
- 如何迭代标准::设置
- forward_list,设置,列表等如何调用标准::分配器
- 是否有C++标准类在作用域出口处将变量设置为值
- 如何正确初始化标准::设置<标准::字符串>?