【问题标题】:Practical meaning of std::strong_ordering and std::weak_orderingstd::strong_ordering 和 std::weak_ordering 的实际意义
【发布时间】:2018-12-12 02:46:50
【问题描述】:

我一直在阅读有关 C++20 的 consistent comparison(即 operator<=>)的内容,但不明白 std::strong_orderingstd::weak_ordering 之间的实际区别是什么(_equality 版本也是如此以这种方式)。
除了对类型的可替代性进行非常详细的描述之外,它实际上是否会影响生成的代码?它是否对如何使用该类型添加任何限制?
希望看到一个真实的例子来证明这一点。

【问题讨论】:

    标签: c++ c++20 spaceship-operator


    【解决方案1】:

    它是否对如何使用该类型添加任何限制?

    一个非常重要的限制(原始论文并非有意)是P0732 采用strong_ordering 的重要性作为类类型可以用作非类型的指标模板参数。 weak_ordering 在这种情况下是不够的,因为模板等效性必须如何工作。 现在不再是这种情况,因为非类型模板参数不再以这种方式工作(有关问题的解释,请参阅 P1907R0P1907R1 了解新规则的措辞)。

    一般来说,有些算法可能只需要weak_ordering,但其他算法需要strong_ordering,因此能够在类型上注释它可能意味着编译错误(提供的强排序不足)而不是简单地未能满足算法在运行时的要求,因此只是未定义的行为。但是我所知道的标准库和 Ranges TS 中的所有算法都只需要weak_ordering。我不知道有哪一个需要strong_ordering

    它真的会影响生成的代码吗?

    除了需要strong_ordering 或算法根据比较类别明确选择不同行为的情况之外,没有。

    【讨论】:

      【解决方案2】:

      确实没有任何理由拥有std::weak_ordering。确实,该标准描述了诸如根据"strict" weak order 进行排序之类的操作,但是在严格的弱排序和原始集合的完全有序分区之间存在同构,无法比较等价类。很少会遇到对 order 结构(将每个等价类视为一个“值”)和一些可能更精细的 equivalence 概念感兴趣的通用代码:请注意,当标准库使用<(或<=>)时,它不使用==(可能更好)。

      std::weak_ordering 的常见示例是不区分大小写的字符串,因为例如打印两个仅大小写不同的字符串肯定会产生不同的行为,尽管它们是等价的(在任何运算符下)。但是,尽管是 ==,但许多类型可能具有不同的行为:例如,两个 std::vector<int> 对象可能具有相同的内容和不同的容量,因此附加到它们可能会以不同的方式使迭代器失效。

      简单的事实是,std::strong_ordering::equivalent 而不是std::weak_ordering::equivalent 所暗示的“平等”与受益于它的代码无关,因为通用 strong> 代码不依赖于隐含的行为变化,非泛型代码不需要区分排序类型,因为它知道它所操作的类型的规则。

      该标准试图通过谈论“可替代性”来赋予区分含义,但这不可避免地是循环,因为它可以明智地仅指代通过比较检查的状态。这个was discussed 在发布 C++20 之前,但(可能出于显而易见的原因)没有进行太多计划中的进一步讨论。

      【讨论】:

        猜你喜欢
        • 2020-08-08
        • 2020-06-09
        • 2012-05-08
        • 2021-03-29
        • 2018-10-18
        • 1970-01-01
        • 1970-01-01
        • 2013-05-09
        • 1970-01-01
        相关资源
        最近更新 更多