C ++ 20中“关系”概念的定义背后的动机

时间:2019-05-23 11:49:57

标签: c++ c++-standard-library c++20 c++-concepts

the online C++ draftcppreference都定义了标准Relation概念,如下所示:

template <class R, class T, class U>
concept Relation =
  std::Predicate<R, T, T> && std::Predicate<R, U, U> &&
  std::Predicate<R, T, U> && std::Predicate<R, U, T>;

这个定义使我感到惊讶,因为我希望看到类似的东西

template <class R, class T, class U>
concept Relation = std::Predicate<R, T, U>;

或者也许

template <class R, class T, class U>
concept Relation = std::Predicate<R, T, U> && std::Predicate<R, U, T>;

甚至

template <class R, class T, class U>
concept Relation = std::Predicate<R, T, U> || std::Predicate<R, U, T>;

据我了解,类型TU之间的relation是对(T, U)上的二进制谓词。因此,对两个T类型的对象或两个U类型的对象进行评估是没有意义的。但是,给定的定义要求必须使用参数(T,T)(U,U)来调用关系。

我的问题是 :这个Relation概念的定义(看似错误)背后的动机是什么?

关于cppreference的说明指出

  

Relation(关系)概念指定R在表达式集和值类别为 T或U 编码的表达式集上定义二进制关系。

(重点是我的)

这听起来很奇怪:为什么在{strong> 任意组合中使用了 两种类型 的两个支持参数定义了通用Relation概念

一种可能是该概念用于指针和nullptr_t的比较,以及迭代器和哨兵迭代器的比较。如果是这种情况,为什么将此概念称为Relation,而不是更具体的名称,例如InterComparable?只是误称吗?

1 个答案:

答案 0 :(得分:4)

这是一个错误的称呼。据我所知,存在为StrictWeakOrder之类的东西提供语法要求,而没有语义要求的地方。

例如也考虑

template <class R, class T, class U>
concept Equivalence = std::Relation<R, T, U>;

//A relation r is an equivalence if
// - it is reflexive: for all x, r(x, x) is true;
// - it is symmetric: for all a and b, if r(a, b) is true then r(b, a) is true;
// - it is transitive: for all a, b and c, if r(a, b) and r(b, c) are both true then r(a, c) is true;