ISO C ++标准委员会(WG21)如何以及为何决定接受宇宙飞船运营商的提案?

时间:2017-11-25 12:09:17

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

在最近发表的论文[1]中,Herb Sutter等人。用三向比较运算符描述编程语言C ++的扩展。作者提到了相当多的早期提案,所有这些提案最终都被拒绝了。

新方法的聪明核心概念是在比较运算符的返回类型中编码不同类别的关系。作者声明

  

主要设计目标是概念完整性[Brooks 1975],其中   意味着设计是连贯的,并且可靠地完成了用户的工作   期待它。

总共介绍了五类比较关系:

  • weak_equality
  • strong_equality
  • partial_ordering
  • weak_ordering
  • strong_ordering

如果您想知道,作者证明他们选择的词语如下:

  

我提出了这些名称,而不是标准的数学术语   相反,因为我发现这些更容易教。

从文本中可以推断出weak_equality对应等价strong_equality对应等等weak_ordering对应弱订单strong_ordering线性订单。与过去的好日子不同[3],遗憾的是,作者没有公理地描述这些术语。

对于partial_ordering

,这会特别有用

事实证明partial_ordering与数学意义上的偏序不对应,因为它没有强加反对称。相反,它对应于准订单

这两种关系都有实际应用。

广泛使用的部分顺序是子集关系。它显然是 reflexive transitive 反对称。特别是,给定A和B组的命题'A⊆B和B⊆A'意味着A和B是相等的(不仅仅是等价的)。

真正的悲剧是,在一个全新的框架中,不可能精确地表示子集关系(或任何其他部分顺序)。

  

对于浮点类型,我们使用支持两者的partial_ordering   使用-0 <=> +0的通常语义签署零和NaN   返回equivalentNaN <=> anything返回unordered

虽然正确描述了特定浮点比较的结果,但作者忽略了这种结构根本没有定义任何顺序的事实,因为它缺乏反身性。数学废话?尝试对包含NaN的浮点实体数组进行排序,并享受未定义的行为!

2.5节介绍了进一步的漏洞。为每个比较关系类别提供默认模板函数实现,特别是:

  • strong_order()
  • weak_order()
  • partial_order()
  • strong_equal()
  • weak_equal()

由于此工具是纯库扩展,因此无需担心向后兼容性。作者声称

  

现有operator<通常会尝试表达弱势订单

显然,他们明白并非每一个现有的operator<都表达了一个弱势的秩序。然而,weak_order()的默认实现可以追溯到遗留operator==operator<,因此可以提供充足的机会在运行时自己动手。

这完全破坏了提案的核心概念和光荣的设计目标。

根据[4],ISO C ++标准委员会(WG21)投票赞成在2017年11月的Albuquerque会议上将该提案纳入C ++ 20工作草案。

这引出了我的问题:委员会是否意识到了这些弱点并有意识地接受了这些弱点,或者只是忽略了它们?

确定:

  • 我非常喜欢这个基本概念。
  • 我没有看到改变长期条款的任何好处。
  • 我不想在没有任何明确指示的情况下默默地改变共同指定的含义。
  • 我觉得很遗憾它并不是为了精确地代表部分订单。
  • 我发现不必要地让用户面临潜在的运行时错误风险是不可接受的。
  • 几个月前向其中一位作者发出的直接信息仍然没有得到答复,也没有被忽视。

参考

[1] Herb Sutter等人:一致的比较。 ISO / IEC JTC1 / SC22 / WG21文件P0515R2(前阿尔伯克基邮寄),2017-09-30。 网址https://wg21.link/p0515r2

[2] Walter E. Brown:宇宙飞船(比较)运营商的图书馆支持。 ISO / IEC JTC1 / SC22 / WG21文件P0768R0(前阿尔伯克基邮寄),2017-09-30。 网址https://wg21.link/p0768r0

[3] Hewlett-Packard公司:严格的弱订购。 标准模板库程序员指南,1994。 网址https://www.sgi.com/tech/stl/StrictWeakOrdering.html

[4] Botond Ballo:旅行报告。 2017年11月在阿尔伯克基举行的C ++标准会议。 网址https://botondballo.wordpress.com/2017/11/20/trip-report-c-standards-meeting-in-albuquerque-november-2017/

[5]维基百科:印第安纳皮比尔。 网址https://en.wikipedia.org/wiki/Indiana_Pi_Bill

补编

包含真正部分订单的层次结构可能如下所示: Alternative comparison relation hierarchy

2.5节中命名比较函数的数学上合理的实现可以简单如下:

template <class T>
std::linear_ordering linear_order(const T& a, const T& b)
{
   return compare_3way(a, b);
}

template <class T>
std::weak_ordering weak_order(const T& a, const T& b)
{
   return compare_3way(a, b);
}

template <class T>
std::partial_ordering partial_order(const T& a, const T& b)
{
   return compare_3way(a, b);
}

template <class T>
std::quasi_ordering quasi_order(const T& a, const T& b)
{
   return compare_3way(a, b);
}

template <class T>
std::equality equal(const T& a, const T& b)
{
   return compare_3way(a, b);
}

template <class T>
std::equivalence equivalent(const T& a, const T& b)
{
   return compare_3way(a, b);
}

使用

template <class T, class U>
auto compare_3way(const T& a, const U& b)
{
   return a <=> b;
}

template <class T, class U>
auto compare_3way(const T& a, const U& b)
{
   if constexpr (/* can invoke a <=> b */)
   {
      return a <=> b;
   }
   else if constexpr (std::is_same_v<T, U> &&
      /* can invoke a.M <=> b.M for each member M of T */)
   {
      /* do that */
   }
}

template <class T, class U>
auto compare_3way(const T& a, const U& b)
{
   if constexpr (/* can invoke a <=> b */)
   {
      return a <=> b;
   }
   else if constexpr (std::is_same_v<T, U> &&
      /* can invoke compare_3way(a.M, b.M) for each member M of T */)
   {
      /* do that */
   }
}

0 个答案:

没有答案