使用设置更少或less_equal
less or less_equal using set
我们可以将函数作为<
(更少(运算符传递给STL数据结构,例如set
,multiset
,map
,priority_queue
,...
如果我们的函数像<=
(less_equal(一样有问题吗?
是的,有一个问题。
从形式上讲,比较函数必须定义严格的弱排序,而<=
不会这样做。
更具体地说,<
也用于确定等价性(x
和y
是等价的iff !(x < y) && !(y < x)
(。这不适用于<=
(使用该运算符会让你的集合相信对象永远不会等效(
来自有效的 STL ->第 21 项。总是让比较函数返回 false 表示相等值。
创建一个less_equal为比较类型的集合,然后将 10 插入到该集合中:
set<int, less_equal<int> > s; // s is sorted by "<="
s.insert(10); //insert the value 10
现在尝试再次插入 10:
s.insert(10);
要插入此调用,集合必须确定 10 是否已存在。我们知道就是这样。但是这套烤面包像吐司一样愚蠢,所以它必须检查。为了更容易了解当集合执行此操作时会发生什么,我们将最初称为 10插入 10A 和我们尝试插入 10B 的 10。该集合通过其内部数据结构运行,寻找插入 10B 的位置。它最终必须检查10B,看看它是否与10A相同。"相同"的定义对于关联容器是等价的,因此集合测试以查看是否10B相当于10A。在执行此测试时,它自然会使用该集合的比较功能。在此示例中,这是运算符<=,因为我们指定了less_equal作为集合的比较函数,less_equal表示运算符。集从而检查此表达式是否为真:
!(10A<= 10B)&&!(10B<= 10A) //test 10Aand 10B for equivalence
嗯,10A和10B都是10,所以很明显,10A<= 10B.同样清楚的是,10B<= 10A。因此,上述表达式简化为
!!(true)&&!(true)
这简化了
false && false
这简直是错误的。也就是说,集合得出结论,10A 和 10B 不等价,因此不一样,因此它将 10B 插入容器中10A.从技术上讲,此操作会产生未定义的行为,但几乎是通用的结果是集合最终得到值 10 的两个副本,这意味着它不是再来一套。通过使用less_equal作为我们的比较类型,我们已经破坏了容器!此外,任何相等值返回 true 的比较函数都将做同样的事情。根据定义,相等的值不等效!
确实有问题。
比较函数应该满足严格的弱排序,而<=
则不满足。
- 如何使用std::min和std::less返回对象
- 如何使用"equal to"以外的评估编写开关语句
- std::less是否应该允许在编译时比较不相关的指针?
- 无法获得等效的 std::less 来用于嵌套迭代器
- 如何在长g++错误消息上使用linux less命令
- C++有"not equal compare and exchange"或"fetch add on not equal"吗?
- 为什么 std::equal 模板由两个类参数化?
- C++20概念中的"equal"概念
- enable_if std的组合:: Less sizeof ..使MSVC失败
- 如何实现随机访问迭代器的"less than operator"?
- 如何在不重载"operator()"、"std::less"、"std
- SFINAE 检查 std::less 是否有效
- 如何在 C++ 类中重载 'less than' 运算符以比较常量?
- 使用'equal to'符号初始化期间的内存
- "compares less than 0"是什么意思?
- 不能对 std::set<std::string, std::less 使用用户提供的比较函数<>>
- 为什么 std::less<Eigen::VectorXd> 编译失败?
- 如果 std::greater<>,那么为什么是 std::less(而不是 std::lesser<>)?
- 在 C 族中,在一个循环中,为什么"less than or equal to"比"less than"符号更受欢迎?
- 为什么C++ STL 容器使用 "less than" 运算符<而不是 "equal equal" 运算符== 作为比较器?